Loading cmds/installd/InstalldNativeService.cpp +73 −4 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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(); } Loading cmds/installd/InstalldNativeService.h +15 −8 Original line number Diff line number Diff line Loading @@ -47,14 +47,9 @@ public: int32_t flags); binder::Status createAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status createAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status createAppData( const android::os::CreateAppDataArgs& args, Loading Loading @@ -203,6 +198,18 @@ private: std::unordered_map<uid_t, int64_t> mCacheQuotas; std::string findDataMediaPath(const std::optional<std::string>& uuid, userid_t userid); binder::Status createAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status 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); }; } // namespace installd Loading cmds/installd/tests/installd_service_test.cpp +123 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,14 @@ std::string get_package_name(uid_t uid) { } namespace installd { constexpr const char* kTestUuid = "TEST"; constexpr const char* kTestPath = "/data/local/tmp/user/0"; static constexpr const char* kTestUuid = "TEST"; static constexpr const char* kTestPath = "/data/local/tmp/user/0"; static constexpr const uid_t kSystemUid = 1000; static constexpr const int32_t kTestUserId = 0; static constexpr const uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppSupplementalUid = multiuser_get_supplemental_uid(kTestUserId, kTestAppId); #define FLAG_FORCE InstalldNativeService::FLAG_FORCE Loading Loading @@ -930,5 +936,120 @@ TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) { "com.foo", 10000, "", 0, 41, FLAG_STORAGE_DE)); } class AppSupplementalDataTest : public testing::Test { public: void CheckFileAccess(const std::string& path, uid_t uid, mode_t mode) { const auto fullPath = "/data/local/tmp/" + path; ASSERT_TRUE(exists(fullPath.c_str())) << "For path: " << fullPath; struct stat st; ASSERT_EQ(0, stat(fullPath.c_str(), &st)); ASSERT_EQ(uid, st.st_uid) << "For path: " << fullPath; ASSERT_EQ(uid, st.st_gid) << "For path: " << fullPath; ASSERT_EQ(mode, st.st_mode) << "For path: " << fullPath; } bool exists(const char* path) { return ::access(path, F_OK) == 0; } // Creates a default CreateAppDataArgs object android::os::CreateAppDataArgs createAppDataArgs() { android::os::CreateAppDataArgs args; args.uuid = kTestUuid; args.packageName = "com.foo"; args.userId = kTestUserId; args.appId = kTestAppId; args.seInfo = "default"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; return args; } protected: InstalldNativeService* service; virtual void SetUp() { setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(nullptr); service = new InstalldNativeService(); clearAppData(); ASSERT_TRUE(mkdirs("/data/local/tmp/user/0", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/user_de/0", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/misc_ce/0/supplemental", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/misc_de/0/supplemental", 0700)); init_globals_from_data_and_root(); } virtual void TearDown() { delete service; clearAppData(); } private: void clearAppData() { ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user_de", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_ce", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_de", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user_de", true)); } }; TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); CheckFileAccess("misc_ce/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared", kTestAppSupplementalUid, S_IFDIR | 0700); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared/cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared/code_cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_de/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); CheckFileAccess("misc_de/0/supplemental/com.foo/shared", kTestAppSupplementalUid, S_IFDIR | 0700); CheckFileAccess("misc_de/0/supplemental/com.foo/shared/cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_de/0/supplemental/com.foo/shared/code_cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); } TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData_WithoutDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Only CE paths should exist CheckFileAccess("misc_ce/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); // DE paths should not exist ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/supplemental/com.foo")); } TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData_WithoutCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_DE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // CE paths should not exist ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/supplemental/com.foo")); // Only DE paths should exist CheckFileAccess("misc_de/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); } } // namespace installd } // namespace android cmds/installd/tests/installd_utils_test.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -638,5 +638,39 @@ TEST_F(UtilsTest, TestCreateDirIfNeeded) { ASSERT_NE(0, create_dir_if_needed("/data/local/tmp/user/0/bar/baz", 0700)); } TEST_F(UtilsTest, TestSupplementalDataPaths) { // Ce data paths EXPECT_EQ("/data/misc_ce/0/supplemental", create_data_misc_supplemental_path(nullptr, /*isCeData=*/true, 0)); EXPECT_EQ("/data/misc_ce/10/supplemental", create_data_misc_supplemental_path(nullptr, true, 10)); EXPECT_EQ("/data/misc_ce/0/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, true, 0, "com.foo")); EXPECT_EQ("/data/misc_ce/10/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, true, 10, "com.foo")); EXPECT_EQ("/data/misc_ce/0/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, true, 0, "com.foo")); EXPECT_EQ("/data/misc_ce/10/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, true, 10, "com.foo")); // De data paths EXPECT_EQ("/data/misc_de/0/supplemental", create_data_misc_supplemental_path(nullptr, /*isCeData=*/false, 0)); EXPECT_EQ("/data/misc_de/10/supplemental", create_data_misc_supplemental_path(nullptr, false, 10)); EXPECT_EQ("/data/misc_de/0/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, false, 0, "com.foo")); EXPECT_EQ("/data/misc_de/10/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, false, 10, "com.foo")); EXPECT_EQ("/data/misc_de/0/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, false, 0, "com.foo")); EXPECT_EQ("/data/misc_de/10/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, false, 10, "com.foo")); } } // namespace installd } // namespace android cmds/installd/utils.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,43 @@ std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) { return StringPrintf("%s/user_de/%u", data.c_str(), userid); } /** * Create the path name where supplemental data for all apps will be stored. * E.g. /data/misc_ce/0/supplemental */ std::string create_data_misc_supplemental_path(const char* uuid, bool isCeData, userid_t user) { std::string data(create_data_path(uuid)); if (isCeData) { return StringPrintf("%s/misc_ce/%d/supplemental", data.c_str(), user); } else { return StringPrintf("%s/misc_de/%d/supplemental", data.c_str(), user); } } /** * Create the path name where code data for all codes in a particular app will be stored. * E.g. /data/misc_ce/0/supplemental/<app-name> */ std::string create_data_misc_supplemental_package_path(const char* volume_uuid, bool isCeData, userid_t user, const char* package_name) { check_package_name(package_name); return StringPrintf("%s/%s", create_data_misc_supplemental_path(volume_uuid, isCeData, user).c_str(), package_name); } /** * Create the path name where shared code data for a particular app will be stored. * E.g. /data/misc_ce/0/supplemental/<app-name>/shared */ std::string create_data_misc_supplemental_shared_path(const char* volume_uuid, bool isCeData, userid_t user, const char* package_name) { return StringPrintf("%s/shared", create_data_misc_supplemental_package_path(volume_uuid, isCeData, user, package_name) .c_str()); } std::string create_data_misc_ce_rollback_base_path(const char* volume_uuid, userid_t user) { return StringPrintf("%s/misc_ce/%u/rollback", create_data_path(volume_uuid).c_str(), user); } Loading Loading
cmds/installd/InstalldNativeService.cpp +73 −4 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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(); } Loading
cmds/installd/InstalldNativeService.h +15 −8 Original line number Diff line number Diff line Loading @@ -47,14 +47,9 @@ public: int32_t flags); binder::Status createAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status createAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status createAppData( const android::os::CreateAppDataArgs& args, Loading Loading @@ -203,6 +198,18 @@ private: std::unordered_map<uid_t, int64_t> mCacheQuotas; std::string findDataMediaPath(const std::optional<std::string>& uuid, userid_t userid); binder::Status createAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status 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); }; } // namespace installd Loading
cmds/installd/tests/installd_service_test.cpp +123 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,14 @@ std::string get_package_name(uid_t uid) { } namespace installd { constexpr const char* kTestUuid = "TEST"; constexpr const char* kTestPath = "/data/local/tmp/user/0"; static constexpr const char* kTestUuid = "TEST"; static constexpr const char* kTestPath = "/data/local/tmp/user/0"; static constexpr const uid_t kSystemUid = 1000; static constexpr const int32_t kTestUserId = 0; static constexpr const uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppSupplementalUid = multiuser_get_supplemental_uid(kTestUserId, kTestAppId); #define FLAG_FORCE InstalldNativeService::FLAG_FORCE Loading Loading @@ -930,5 +936,120 @@ TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) { "com.foo", 10000, "", 0, 41, FLAG_STORAGE_DE)); } class AppSupplementalDataTest : public testing::Test { public: void CheckFileAccess(const std::string& path, uid_t uid, mode_t mode) { const auto fullPath = "/data/local/tmp/" + path; ASSERT_TRUE(exists(fullPath.c_str())) << "For path: " << fullPath; struct stat st; ASSERT_EQ(0, stat(fullPath.c_str(), &st)); ASSERT_EQ(uid, st.st_uid) << "For path: " << fullPath; ASSERT_EQ(uid, st.st_gid) << "For path: " << fullPath; ASSERT_EQ(mode, st.st_mode) << "For path: " << fullPath; } bool exists(const char* path) { return ::access(path, F_OK) == 0; } // Creates a default CreateAppDataArgs object android::os::CreateAppDataArgs createAppDataArgs() { android::os::CreateAppDataArgs args; args.uuid = kTestUuid; args.packageName = "com.foo"; args.userId = kTestUserId; args.appId = kTestAppId; args.seInfo = "default"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; return args; } protected: InstalldNativeService* service; virtual void SetUp() { setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(nullptr); service = new InstalldNativeService(); clearAppData(); ASSERT_TRUE(mkdirs("/data/local/tmp/user/0", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/user_de/0", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/misc_ce/0/supplemental", 0700)); ASSERT_TRUE(mkdirs("/data/local/tmp/misc_de/0/supplemental", 0700)); init_globals_from_data_and_root(); } virtual void TearDown() { delete service; clearAppData(); } private: void clearAppData() { ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user_de", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_ce", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_de", true)); ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user_de", true)); } }; TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); CheckFileAccess("misc_ce/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared", kTestAppSupplementalUid, S_IFDIR | 0700); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared/cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_ce/0/supplemental/com.foo/shared/code_cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_de/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); CheckFileAccess("misc_de/0/supplemental/com.foo/shared", kTestAppSupplementalUid, S_IFDIR | 0700); CheckFileAccess("misc_de/0/supplemental/com.foo/shared/cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); CheckFileAccess("misc_de/0/supplemental/com.foo/shared/code_cache", kTestAppSupplementalUid, S_IFDIR | S_ISGID | 0771); } TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData_WithoutDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Only CE paths should exist CheckFileAccess("misc_ce/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); // DE paths should not exist ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/supplemental/com.foo")); } TEST_F(AppSupplementalDataTest, CreateAppData_CreatesSupplementalAppData_WithoutCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs(); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_DE; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // CE paths should not exist ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/supplemental/com.foo")); // Only DE paths should exist CheckFileAccess("misc_de/0/supplemental/com.foo", kSystemUid, S_IFDIR | 0751); } } // namespace installd } // namespace android
cmds/installd/tests/installd_utils_test.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -638,5 +638,39 @@ TEST_F(UtilsTest, TestCreateDirIfNeeded) { ASSERT_NE(0, create_dir_if_needed("/data/local/tmp/user/0/bar/baz", 0700)); } TEST_F(UtilsTest, TestSupplementalDataPaths) { // Ce data paths EXPECT_EQ("/data/misc_ce/0/supplemental", create_data_misc_supplemental_path(nullptr, /*isCeData=*/true, 0)); EXPECT_EQ("/data/misc_ce/10/supplemental", create_data_misc_supplemental_path(nullptr, true, 10)); EXPECT_EQ("/data/misc_ce/0/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, true, 0, "com.foo")); EXPECT_EQ("/data/misc_ce/10/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, true, 10, "com.foo")); EXPECT_EQ("/data/misc_ce/0/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, true, 0, "com.foo")); EXPECT_EQ("/data/misc_ce/10/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, true, 10, "com.foo")); // De data paths EXPECT_EQ("/data/misc_de/0/supplemental", create_data_misc_supplemental_path(nullptr, /*isCeData=*/false, 0)); EXPECT_EQ("/data/misc_de/10/supplemental", create_data_misc_supplemental_path(nullptr, false, 10)); EXPECT_EQ("/data/misc_de/0/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, false, 0, "com.foo")); EXPECT_EQ("/data/misc_de/10/supplemental/com.foo", create_data_misc_supplemental_package_path(nullptr, false, 10, "com.foo")); EXPECT_EQ("/data/misc_de/0/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, false, 0, "com.foo")); EXPECT_EQ("/data/misc_de/10/supplemental/com.foo/shared", create_data_misc_supplemental_shared_path(nullptr, false, 10, "com.foo")); } } // namespace installd } // namespace android
cmds/installd/utils.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,43 @@ std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) { return StringPrintf("%s/user_de/%u", data.c_str(), userid); } /** * Create the path name where supplemental data for all apps will be stored. * E.g. /data/misc_ce/0/supplemental */ std::string create_data_misc_supplemental_path(const char* uuid, bool isCeData, userid_t user) { std::string data(create_data_path(uuid)); if (isCeData) { return StringPrintf("%s/misc_ce/%d/supplemental", data.c_str(), user); } else { return StringPrintf("%s/misc_de/%d/supplemental", data.c_str(), user); } } /** * Create the path name where code data for all codes in a particular app will be stored. * E.g. /data/misc_ce/0/supplemental/<app-name> */ std::string create_data_misc_supplemental_package_path(const char* volume_uuid, bool isCeData, userid_t user, const char* package_name) { check_package_name(package_name); return StringPrintf("%s/%s", create_data_misc_supplemental_path(volume_uuid, isCeData, user).c_str(), package_name); } /** * Create the path name where shared code data for a particular app will be stored. * E.g. /data/misc_ce/0/supplemental/<app-name>/shared */ std::string create_data_misc_supplemental_shared_path(const char* volume_uuid, bool isCeData, userid_t user, const char* package_name) { return StringPrintf("%s/shared", create_data_misc_supplemental_package_path(volume_uuid, isCeData, user, package_name) .c_str()); } std::string create_data_misc_ce_rollback_base_path(const char* volume_uuid, userid_t user) { return StringPrintf("%s/misc_ce/%u/rollback", create_data_path(volume_uuid).c_str(), user); } Loading