Loading cmds/installd/InstalldNativeService.cpp +13 −6 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -804,21 +807,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; Loading Loading @@ -892,13 +895,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, Loading cmds/installd/tests/installd_service_test.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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 Loading
cmds/installd/InstalldNativeService.cpp +13 −6 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -804,21 +807,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; Loading Loading @@ -892,13 +895,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, Loading
cmds/installd/tests/installd_service_test.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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