diff options
| -rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 17 | ||||
| -rw-r--r-- | cmds/installd/tests/installd_dexopt_test.cpp | 34 |
2 files changed, 46 insertions, 5 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index daa744f859..04e39f9bac 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -373,13 +373,22 @@ static bool prepare_app_profile_dir(const std::string& packageName, int32_t appI 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) { + + // Prepare the reference profile directory. Note that we use the non strict version of + // fs_prepare_dir. This will fix the permission and the ownership to the correct values. + // This is particularly important given that in O there were some fixes for how the + // shared_app_gid is computed. + // + // Note that by the time we get here we know that we are using a correct uid (otherwise + // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we + // are sure that the gid being used belongs to the owning app and not someone else. + // + // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles. + if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) { PLOG(ERROR) << "Failed to prepare " << ref_profile_path; return false; } + return true; } diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp index ebeae9624c..05d7b6c03a 100644 --- a/cmds/installd/tests/installd_dexopt_test.cpp +++ b/cmds/installd/tests/installd_dexopt_test.cpp @@ -574,7 +574,39 @@ TEST_F(ProfileTest, ProfileDirOk) { 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); + CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); +} + +// Verify that the profile directories are fixed up during an upgrade. +// (The reference profile directory is prepared lazily). +TEST_F(ProfileTest, ProfileDirOkAfterFixup) { + LOG(INFO) << "ProfileDirOkAfterFixup"; + + 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_); + + // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700. + ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid)); + ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700)); + + // Run createAppData again which will offer to fix-up the profile directories. + ASSERT_TRUE(service_->createAppData( + volume_uuid_, + package_name_, + kTestUserId, + kAppDataFlags, + kTestAppUid, + se_info_, + kOSdkVersion, + &ce_data_inode_).isOk()); + + // Check the file access. + CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR); + CheckFileAccess(cur_profile_file, kTestAppUid, kTestAppUid, 0600 | S_IFREG); + CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR); } } // namespace installd |