diff options
Diffstat (limited to 'cmds/installd/InstalldNativeService.cpp')
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 4e3aae4312..7c219449d3 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -18,13 +18,9 @@ #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER -#include <algorithm> #include <errno.h> -#include <fstream> #include <fts.h> -#include <functional> #include <inttypes.h> -#include <regex> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -40,6 +36,11 @@ #include <sys/wait.h> #include <sys/xattr.h> #include <unistd.h> +#include <algorithm> +#include <filesystem> +#include <fstream> +#include <functional> +#include <regex> #include <android-base/file.h> #include <android-base/logging.h> @@ -720,6 +721,74 @@ binder::Status InstalldNativeService::createAppDataLocked( return error("Failed to prepare profiles for " + packageName); } } + + { + auto status = createAppDirectoryForSupplementalData(uuid, packageName, userId, appId, + previousAppId, seInfo, flags); + if (!status.isOk()) { + return status; + } + } + + return ok(); +} + +/** + * Responsible for creating /data/user/0/supplemental/<app-name> directory and other + * app level sub directories, such as ./shared + */ +binder::Status InstalldNativeService::createAppDirectoryForSupplementalData( + const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, + int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t flags) { + int32_t supplementalUid = multiuser_get_supplemental_uid(userId, appId); + if (supplementalUid == -1) { + // There no valid supplemental process for this app. Skip creation of data directory + return ok(); + } + + // TODO(b/211763739): what if uuid is not nullptr or TEST? + const char* uuid_ = uuid ? uuid->c_str() : nullptr; + + constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; + for (int i = 0; i < 2; i++) { + int currentFlag = storageFlags[i]; + if ((flags & currentFlag) == 0) { + continue; + } + bool isCeData = (currentFlag == FLAG_STORAGE_CE); + + // /data/misc_{ce,de}/<user-id>/supplemental directory gets created by vold + // during user creation + + // Prepare the app directory + auto appPath = create_data_misc_supplemental_package_path(uuid_, isCeData, userId, + packageName.c_str()); + if (prepare_app_dir(appPath, 0751, AID_SYSTEM)) { + return error("Failed to prepare " + appPath); + } + + // Now prepare the shared directory which will be accessible by all codes + auto sharedPath = create_data_misc_supplemental_shared_path(uuid_, isCeData, userId, + packageName.c_str()); + + int32_t previousSupplementalUid = multiuser_get_supplemental_uid(userId, previousAppId); + int32_t cacheGid = multiuser_get_cache_gid(userId, appId); + if (cacheGid == -1) { + return exception(binder::Status::EX_ILLEGAL_STATE, + StringPrintf("cacheGid cannot be -1 for supplemental data")); + } + auto status = createAppDataDirs(sharedPath, supplementalUid, &previousSupplementalUid, + cacheGid, seInfo, 0700); + if (!status.isOk()) { + return status; + } + + // TODO(b/211763739): We also need to handle art profile creations + + // TODO(b/211763739): And return the CE inode of the supplemental root directory and + // app directory under it so we can clear contents while CE storage is locked + } + return ok(); } |