diff options
| author | 2019-01-29 03:46:50 -0800 | |
|---|---|---|
| committer | 2019-01-29 03:46:50 -0800 | |
| commit | 01e37e982aceda9dec70a9c2667a63af137edccd (patch) | |
| tree | 7af014f0bc4efe6200ee03a15d9fde1f4136d174 | |
| parent | 86b86d8bbc6527c65fb362a137f1bd375e579a7c (diff) | |
| parent | 92bb4515a58858d931a2e5e400df15341d56b9ab (diff) | |
Merge "installd: Validate volumeUuid in snapshotAppData and restoreAppDataSnapshot" am: 2470dd34e8
am: 92bb4515a5
Change-Id: Ie4b287ab65099dfe772fc0e54c40d5bcd206f5b6
| -rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 19 | ||||
| -rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 51 |
2 files changed, 64 insertions, 6 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 99f1a18d36..cae212c8a8 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -77,6 +77,9 @@ using std::endl; namespace android { namespace installd { +// An uuid used in unit tests. +static constexpr const char* kTestUuid = "TEST"; + static constexpr const char* kCpPath = "/system/bin/cp"; static constexpr const char* kXattrDefault = "user.default"; @@ -766,21 +769,21 @@ static int32_t copy_directory_recursive(const char* from, const char* to) { // TODO(narayan): We should pass through the ceDataInode so that we can call // clearAppData(FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE before we commence // the copy. -// -// TODO(narayan): For snapshotAppData as well as restoreAppDataSnapshot, we -// should validate that volumeUuid is either nullptr or TEST, we won't support -// anything else. binder::Status InstalldNativeService::snapshotAppData( const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, int32_t user, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); - CHECK_ARGUMENT_UUID(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); + if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { + return exception(binder::Status::EX_ILLEGAL_ARGUMENT, + StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); + } + binder::Status res = ok(); bool clear_ce_on_exit = false; bool clear_de_on_exit = false; @@ -854,13 +857,17 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot( const int32_t appId, const int64_t ceDataInode, const std::string& seInfo, const int32_t user, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); - CHECK_ARGUMENT_UUID(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); + if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { + return exception(binder::Status::EX_ILLEGAL_ARGUMENT, + StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); + } + auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name); auto from_de = create_data_misc_de_rollback_package_path(volume_uuid, diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp index 6ded4b4b97..29eb6c5dd7 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -412,6 +412,27 @@ TEST_F(ServiceTest, CreateAppDataSnapshot_ClearsExistingSnapshot) { ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo/file1").c_str(), &sb)); } +TEST_F(ServiceTest, SnapshotAppData_WrongVolumeUuid) { + // Setup app data to make sure that fails due to wrong volumeUuid being + // passed, not because of some other reason. + auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0); + auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0); + + ASSERT_TRUE(mkdirs(rollback_ce_dir, 700)); + ASSERT_TRUE(mkdirs(rollback_de_dir, 700)); + + auto deleter = [&rollback_ce_dir, &rollback_de_dir]() { + delete_dir_contents(rollback_ce_dir, true); + delete_dir_contents(rollback_de_dir, true); + rmdir(rollback_ce_dir.c_str()); + rmdir(rollback_de_dir.c_str()); + }; + auto scope_guard = android::base::make_scope_guard(deleter); + + ASSERT_FALSE(service->snapshotAppData(std::make_unique<std::string>("FOO"), + "com.foo", 0, FLAG_STORAGE_DE).isOk()); +} + TEST_F(ServiceTest, RestoreAppDataSnapshot) { auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0); auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0); @@ -466,5 +487,35 @@ TEST_F(ServiceTest, RestoreAppDataSnapshot) { } +TEST_F(ServiceTest, RestoreAppDataSnapshot_WrongVolumeUuid) { + // Setup rollback data to make sure that fails due to wrong volumeUuid being + // passed, not because of some other reason. + auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0); + auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0); + + ASSERT_TRUE(mkdirs(rollback_ce_dir, 700)); + ASSERT_TRUE(mkdirs(rollback_de_dir, 700)); + + auto fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo"); + auto fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo"); + + ASSERT_TRUE(mkdirs(fake_package_ce_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_de_path, 700)); + + auto deleter = [&rollback_ce_dir, &rollback_de_dir, + &fake_package_ce_path, &fake_package_de_path]() { + delete_dir_contents(rollback_ce_dir, true); + delete_dir_contents(rollback_de_dir, true); + delete_dir_contents(fake_package_ce_path, true); + delete_dir_contents(fake_package_de_path, true); + rmdir(rollback_ce_dir.c_str()); + rmdir(rollback_de_dir.c_str()); + }; + auto scope_guard = android::base::make_scope_guard(deleter); + + ASSERT_FALSE(service->restoreAppDataSnapshot(std::make_unique<std::string>("BAR"), + "com.foo", 10000, -1, "", 0, FLAG_STORAGE_DE).isOk()); +} + } // namespace installd } // namespace android |