Loading cmds/installd/InstalldNativeService.cpp +43 −22 Original line number Diff line number Diff line Loading @@ -342,6 +342,47 @@ static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std #endif } static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) { if (!property_get_bool("dalvik.vm.usejitprofiles", false)) { return true; } int32_t uid = multiuser_get_uid(userId, appId); int shared_app_gid = multiuser_get_shared_gid(userId, appId); if (shared_app_gid == -1) { // TODO(calin): this should no longer be possible but do not continue if we don't get // a valid shared gid. PLOG(WARNING) << "Invalid shared_app_gid for " << packageName; return true; } const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, packageName); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_dir; return false; } const std::string profile_file = create_current_profile_path(userId, packageName, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_file; return false; } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(packageName); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. if (fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { PLOG(ERROR) << "Failed to prepare " << ref_profile_path; return false; } return true; } binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { Loading Loading @@ -417,28 +458,8 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s return error("Failed to set hard quota " + path); } if (property_get_bool("dalvik.vm.usejitprofiles", false)) { const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, pkgname); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { return error("Failed to prepare " + profile_dir); } const std::string profile_file = create_current_profile_path(userId, pkgname, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { return error("Failed to prepare " + profile_file); } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(pkgname); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. int shared_app_gid = multiuser_get_shared_gid(0, appId); if ((shared_app_gid != -1) && fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { return error("Failed to prepare " + ref_profile_path); } if (!prepare_app_profile_dir(packageName, appId, userId)) { return error("Failed to prepare profiles for " + packageName); } } return ok(); Loading cmds/installd/tests/installd_dexopt_test.cpp +26 −5 Original line number Diff line number Diff line Loading @@ -144,10 +144,11 @@ protected: static constexpr uid_t kSystemGid = 1000; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr uid_t kTestAppUid = 19999; static constexpr gid_t kTestAppGid = 19999; static constexpr uid_t kTestAppId = kTestAppUid; static constexpr int32_t kTestUserId = 0; static constexpr uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId); InstalldNativeService* service_; std::unique_ptr<std::string> volume_uuid_; Loading Loading @@ -245,7 +246,10 @@ protected: void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, bool should_binder_call_succeed, bool should_dex_be_compiled = true, int uid = kTestAppUid) { int32_t uid = -1) { if (uid == -1) { uid = kTestAppUid; } std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); int32_t dexopt_needed = 0; // does not matter; std::unique_ptr<std::string> out_path = nullptr; // does not matter Loading Loading @@ -279,7 +283,10 @@ protected: void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, int uid = kTestAppUid, std::string* package_override = nullptr) { int32_t uid = -1, std::string* package_override = nullptr) { if (uid == -1) { uid = kTestAppUid; } std::vector<std::string> isas; isas.push_back(kRuntimeIsa); bool out_secondary_dex_exists = false; Loading Loading @@ -556,5 +563,19 @@ TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) { ASSERT_EQ(ENOENT, errno); } TEST_F(ProfileTest, ProfileDirOk) { LOG(INFO) << "ProfileDirOk"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kTestAppGid, kTestAppGid, 0701 | S_IFDIR); } } // namespace installd } // namespace android Loading
cmds/installd/InstalldNativeService.cpp +43 −22 Original line number Diff line number Diff line Loading @@ -342,6 +342,47 @@ static int prepare_app_quota(const std::unique_ptr<std::string>& uuid, const std #endif } static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) { if (!property_get_bool("dalvik.vm.usejitprofiles", false)) { return true; } int32_t uid = multiuser_get_uid(userId, appId); int shared_app_gid = multiuser_get_shared_gid(userId, appId); if (shared_app_gid == -1) { // TODO(calin): this should no longer be possible but do not continue if we don't get // a valid shared gid. PLOG(WARNING) << "Invalid shared_app_gid for " << packageName; return true; } const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, packageName); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_dir; return false; } const std::string profile_file = create_current_profile_path(userId, packageName, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { PLOG(ERROR) << "Failed to prepare " << profile_file; return false; } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(packageName); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. if (fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { PLOG(ERROR) << "Failed to prepare " << ref_profile_path; return false; } return true; } binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) { Loading Loading @@ -417,28 +458,8 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s return error("Failed to set hard quota " + path); } if (property_get_bool("dalvik.vm.usejitprofiles", false)) { const std::string profile_dir = create_primary_current_profile_package_dir_path(userId, pkgname); // read-write-execute only for the app user. if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) { return error("Failed to prepare " + profile_dir); } const std::string profile_file = create_current_profile_path(userId, pkgname, /*is_secondary_dex*/false); // read-write only for the app user. if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) { return error("Failed to prepare " + profile_file); } const std::string ref_profile_path = create_primary_reference_profile_package_dir_path(pkgname); // dex2oat/profman runs under the shared app gid and it needs to read/write reference // profiles. int shared_app_gid = multiuser_get_shared_gid(0, appId); if ((shared_app_gid != -1) && fs_prepare_dir_strict( ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) { return error("Failed to prepare " + ref_profile_path); } if (!prepare_app_profile_dir(packageName, appId, userId)) { return error("Failed to prepare profiles for " + packageName); } } return ok(); Loading
cmds/installd/tests/installd_dexopt_test.cpp +26 −5 Original line number Diff line number Diff line Loading @@ -144,10 +144,11 @@ protected: static constexpr uid_t kSystemGid = 1000; static constexpr int32_t kOSdkVersion = 25; static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; static constexpr uid_t kTestAppUid = 19999; static constexpr gid_t kTestAppGid = 19999; static constexpr uid_t kTestAppId = kTestAppUid; static constexpr int32_t kTestUserId = 0; static constexpr uid_t kTestAppId = 19999; const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId); const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId); InstalldNativeService* service_; std::unique_ptr<std::string> volume_uuid_; Loading Loading @@ -245,7 +246,10 @@ protected: void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag, bool should_binder_call_succeed, bool should_dex_be_compiled = true, int uid = kTestAppUid) { int32_t uid = -1) { if (uid == -1) { uid = kTestAppUid; } std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_)); int32_t dexopt_needed = 0; // does not matter; std::unique_ptr<std::string> out_path = nullptr; // does not matter Loading Loading @@ -279,7 +283,10 @@ protected: void reconcile_secondary_dex(const std::string& path, int32_t storage_flag, bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted, int uid = kTestAppUid, std::string* package_override = nullptr) { int32_t uid = -1, std::string* package_override = nullptr) { if (uid == -1) { uid = kTestAppUid; } std::vector<std::string> isas; isas.push_back(kRuntimeIsa); bool out_secondary_dex_exists = false; Loading Loading @@ -556,5 +563,19 @@ TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) { ASSERT_EQ(ENOENT, errno); } TEST_F(ProfileTest, ProfileDirOk) { LOG(INFO) << "ProfileDirOk"; std::string cur_profile_dir = create_primary_current_profile_package_dir_path( kTestUserId, package_name_); std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_, /*is_secondary_dex*/false); std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_); CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); CheckFileAccess(ref_profile_dir, kTestAppGid, kTestAppGid, 0701 | S_IFDIR); } } // namespace installd } // namespace android