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

Commit 684ee529 authored by Nikita Ioffe's avatar Nikita Ioffe Committed by android-build-merger
Browse files

Merge "installd: Validate volumeUuid in snapshotAppData and...

Merge "installd: Validate volumeUuid in snapshotAppData and restoreAppDataSnapshot" am: 2470dd34 am: 92bb4515
am: 01e37e98

Change-Id: Ib70fac030b8c36d2a4fbb2ee963299cfaa0652e7
parents 68fd8263 01e37e98
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -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";

@@ -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;
@@ -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,
+51 −0
Original line number Diff line number Diff line
@@ -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