Add fixupAppDir() API.
This can be used to fixup application directories in case they have been created by some other entity besides vold; the main use case for this API right now is OBB directories, which can be created by installers outside of vold; on devices without sdcardfs, such directories and the files contained therein are not setup correctly. This API will make sure everything is setup the way it needs to be setup. Bug: 146419093 Test: inspect OBB dir after install Change-Id: I2e35b7ac2992dbb21cc950e53651ffc07cfca907
This commit is contained in:
parent
442bb83828
commit
816f4d94f6
8 changed files with 84 additions and 6 deletions
|
@ -167,6 +167,7 @@ cc_library_static {
|
|||
],
|
||||
whole_static_libs: [
|
||||
"com.android.sysprop.apex",
|
||||
"libc++fs"
|
||||
],
|
||||
}
|
||||
|
||||
|
|
46
Utils.cpp
46
Utils.cpp
|
@ -47,6 +47,7 @@
|
|||
#include <sys/xattr.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
|
@ -228,7 +229,40 @@ int PrepareDirWithProjectId(const std::string& path, mode_t mode, uid_t uid, gid
|
|||
return ret;
|
||||
}
|
||||
|
||||
int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid) {
|
||||
static int FixupAppDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid, long projectId) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// Setup the directory itself correctly
|
||||
int ret = PrepareDirWithProjectId(path, mode, uid, gid, projectId);
|
||||
if (ret != OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Fixup all of its file entries
|
||||
for (const auto& itEntry : fs::directory_iterator(path)) {
|
||||
ret = lchown(itEntry.path().c_str(), uid, gid);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = chmod(itEntry.path().c_str(), mode);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!IsFilesystemSupported("sdcardfs")) {
|
||||
ret = SetQuotaProjectId(itEntry.path(), projectId);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
|
||||
bool fixupExisting) {
|
||||
long projectId;
|
||||
size_t pos;
|
||||
int ret = 0;
|
||||
|
@ -302,7 +336,15 @@ int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int
|
|||
} else {
|
||||
projectId = uid - AID_APP_START + AID_EXT_GID_START;
|
||||
}
|
||||
ret = PrepareDirWithProjectId(pathToCreate, mode, uid, gid, projectId);
|
||||
|
||||
if (fixupExisting && access(pathToCreate.c_str(), F_OK) == 0) {
|
||||
// Fixup all files in this existing directory with the correct UID/GID
|
||||
// and project ID.
|
||||
ret = FixupAppDir(pathToCreate, mode, uid, gid, projectId);
|
||||
} else {
|
||||
ret = PrepareDirWithProjectId(pathToCreate, mode, uid, gid, projectId);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
|
3
Utils.h
3
Utils.h
|
@ -57,7 +57,8 @@ int SetQuotaProjectId(const std::string& path, long projectId);
|
|||
* ONLY for use with app-specific data directories on external storage!
|
||||
* (eg, /Android/data/com.foo, /Android/obb/com.foo, etc.)
|
||||
*/
|
||||
int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid);
|
||||
int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
|
||||
bool fixupExisting);
|
||||
|
||||
/* fs_prepare_dir wrapper that creates with SELinux context */
|
||||
status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
|
||||
|
|
|
@ -466,6 +466,14 @@ binder::Status VoldNativeService::setupAppDir(const std::string& path, int32_t a
|
|||
return translate(VolumeManager::Instance()->setupAppDir(path, appUid));
|
||||
}
|
||||
|
||||
binder::Status VoldNativeService::fixupAppDir(const std::string& path, int32_t appUid) {
|
||||
ENFORCE_SYSTEM_OR_ROOT;
|
||||
CHECK_ARGUMENT_PATH(path);
|
||||
ACQUIRE_LOCK;
|
||||
|
||||
return translate(VolumeManager::Instance()->fixupAppDir(path, appUid));
|
||||
}
|
||||
|
||||
binder::Status VoldNativeService::createObb(const std::string& sourcePath,
|
||||
const std::string& sourceKey, int32_t ownerGid,
|
||||
std::string* _aidl_return) {
|
||||
|
|
|
@ -66,6 +66,7 @@ class VoldNativeService : public BinderService<VoldNativeService>, public os::Bn
|
|||
binder::Status remountUid(int32_t uid, int32_t remountMode);
|
||||
|
||||
binder::Status setupAppDir(const std::string& path, int32_t appUid);
|
||||
binder::Status fixupAppDir(const std::string& path, int32_t appUid);
|
||||
|
||||
binder::Status createObb(const std::string& sourcePath, const std::string& sourceKey,
|
||||
int32_t ownerGid, std::string* _aidl_return);
|
||||
|
|
|
@ -814,7 +814,7 @@ int VolumeManager::unmountAll() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int VolumeManager::setupAppDir(const std::string& path, int32_t appUid) {
|
||||
int VolumeManager::setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly) {
|
||||
// Only offer to create directories for paths managed by vold
|
||||
if (!StartsWith(path, "/storage/")) {
|
||||
LOG(ERROR) << "Failed to find mounted volume for " << path;
|
||||
|
@ -859,8 +859,21 @@ int VolumeManager::setupAppDir(const std::string& path, int32_t appUid) {
|
|||
|
||||
const std::string volumeRoot = volume->getRootPath(); // eg /data/media/0
|
||||
|
||||
if (fixupExistingOnly && (access(lowerPath.c_str(), F_OK) != 0)) {
|
||||
// Nothing to fixup
|
||||
return OK;
|
||||
}
|
||||
|
||||
// Create the app paths we need from the root
|
||||
return PrepareAppDirFromRoot(lowerPath, volumeRoot, appUid);
|
||||
return PrepareAppDirFromRoot(lowerPath, volumeRoot, appUid, fixupExistingOnly);
|
||||
}
|
||||
|
||||
int VolumeManager::fixupAppDir(const std::string& path, int32_t appUid) {
|
||||
if (IsFilesystemSupported("sdcardfs")) {
|
||||
//sdcardfs magically does this for us
|
||||
return OK;
|
||||
}
|
||||
return setupAppDir(path, appUid, true /* fixupExistingOnly */);
|
||||
}
|
||||
|
||||
int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
|
||||
|
|
|
@ -157,12 +157,23 @@ class VolumeManager {
|
|||
* requirements of the underlying filesystem and are of no concern to the
|
||||
* caller.
|
||||
*
|
||||
* If fixupExistingOnly is set, we make sure to fixup any existing dirs and
|
||||
* files in the passed in path, but only if that path exists; if it doesn't
|
||||
* exist, this function doesn't create them.
|
||||
*
|
||||
* Validates that given paths are absolute and that they contain no relative
|
||||
* "." or ".." paths or symlinks. Last path segment is treated as filename
|
||||
* and ignored, unless the path ends with "/". Also ensures that path
|
||||
* belongs to a volume managed by vold.
|
||||
*/
|
||||
int setupAppDir(const std::string& path, int32_t appUid);
|
||||
int setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly = false);
|
||||
|
||||
/**
|
||||
* Fixes up an existing application directory, as if it was created with
|
||||
* setupAppDir() above. This includes fixing up the UID/GID, permissions and
|
||||
* project IDs of the contained files and directories.
|
||||
*/
|
||||
int fixupAppDir(const std::string& path, int32_t appUid);
|
||||
|
||||
int createObb(const std::string& path, const std::string& key, int32_t ownerGid,
|
||||
std::string* outVolId);
|
||||
|
|
|
@ -55,6 +55,7 @@ interface IVold {
|
|||
void remountUid(int uid, int remountMode);
|
||||
|
||||
void setupAppDir(@utf8InCpp String path, int appUid);
|
||||
void fixupAppDir(@utf8InCpp String path, int appUid);
|
||||
|
||||
@utf8InCpp String createObb(@utf8InCpp String sourcePath, @utf8InCpp String sourceKey,
|
||||
int ownerGid);
|
||||
|
|
Loading…
Reference in a new issue