Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f06eb67 authored by Calin Juravle's avatar Calin Juravle
Browse files

Fixup existing profile directories during upgrades

If the profile directory exists we need to fixup the owner and
permissions. The owner of the directory is set to AID_SYSTEM.
This allows the system to access the profiles while restricting the search
capabilities for others.

Test: installd_dexopt_test
Bug: 30934496
Bug: 69678790
Change-Id: I621c95e24cc85a2797724f6ac448c9f8a8d00a53
parent d2affb86
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -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;
}

+33 −1
Original line number Diff line number Diff line
@@ -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