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

Commit c31097da authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Refactor MountEmulatedStorage().

Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
Test: atest --test-mapping packages/providers/MediaProvider
Change-Id: I3938921033bc407e28548749f9d6f8ba040333d2
parent c7c2ddec
Loading
Loading
Loading
Loading
+41 −29
Original line number Original line Diff line number Diff line
@@ -292,6 +292,7 @@ static std::array<UsapTableEntry, USAP_POOL_SIZE_MAX_LIMIT> gUsapTable;
static FileDescriptorTable* gOpenFdTable = nullptr;
static FileDescriptorTable* gOpenFdTable = nullptr;


// Must match values in com.android.internal.os.Zygote.
// Must match values in com.android.internal.os.Zygote.
// The order of entries here must be kept in sync with ExternalStorageViews array values.
enum MountExternalKind {
enum MountExternalKind {
  MOUNT_EXTERNAL_NONE = 0,
  MOUNT_EXTERNAL_NONE = 0,
  MOUNT_EXTERNAL_DEFAULT = 1,
  MOUNT_EXTERNAL_DEFAULT = 1,
@@ -300,6 +301,18 @@ enum MountExternalKind {
  MOUNT_EXTERNAL_LEGACY = 4,
  MOUNT_EXTERNAL_LEGACY = 4,
  MOUNT_EXTERNAL_INSTALLER = 5,
  MOUNT_EXTERNAL_INSTALLER = 5,
  MOUNT_EXTERNAL_FULL = 6,
  MOUNT_EXTERNAL_FULL = 6,
  MOUNT_EXTERNAL_COUNT = 7
};

// The order of entries here must be kept in sync with MountExternalKind enum values.
static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorageViews = {
  "",                     // MOUNT_EXTERNAL_NONE
  "/mnt/runtime/default", // MOUNT_EXTERNAL_DEFAULT
  "/mnt/runtime/read",    // MOUNT_EXTERNAL_READ
  "/mnt/runtime/write",   // MOUNT_EXTERNAL_WRITE
  "/mnt/runtime/write",   // MOUNT_EXTERNAL_LEGACY
  "/mnt/runtime/write",   // MOUNT_EXTERNAL_INSTALLER
  "/mnt/runtime/full",    // MOUNT_EXTERNAL_FULL
};
};


// Must match values in com.android.internal.os.Zygote.
// Must match values in com.android.internal.os.Zygote.
@@ -633,6 +646,23 @@ static int UnmountTree(const char* path) {
  return 0;
  return 0;
}
}


static void CreateDir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid,
                      fail_fn_t fail_fn) {
  if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
    fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s",
                         dir.c_str(), strerror(errno)));
  }
}

static void BindMount(const std::string& source_dir, const std::string& target_dir,
                      fail_fn_t fail_fn) {
  if (TEMP_FAILURE_RETRY(mount(source_dir.c_str(), target_dir.c_str(), nullptr,
                               MS_BIND | MS_REC, nullptr)) == -1) {
    fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
                         source_dir.c_str(), target_dir.c_str(), strerror(errno)));
  }
}

// Create a private mount namespace and bind mount appropriate emulated
// Create a private mount namespace and bind mount appropriate emulated
// storage for the given user.
// storage for the given user.
static void MountEmulatedStorage(uid_t uid, jint mount_mode,
static void MountEmulatedStorage(uid_t uid, jint mount_mode,
@@ -641,18 +671,11 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode,
  // See storage config details at http://source.android.com/tech/storage/
  // See storage config details at http://source.android.com/tech/storage/
  ATRACE_CALL();
  ATRACE_CALL();


  String8 storage_source;
  if (mount_mode < 0 || mount_mode >= MOUNT_EXTERNAL_COUNT) {
  if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
    fail_fn(CREATE_ERROR("Unknown mount_mode: %d", mount_mode));
    storage_source = "/mnt/runtime/default";
  }
  } else if (mount_mode == MOUNT_EXTERNAL_READ) {

    storage_source = "/mnt/runtime/read";
  if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
  } else if (mount_mode == MOUNT_EXTERNAL_WRITE
      || mount_mode == MOUNT_EXTERNAL_LEGACY
      || mount_mode == MOUNT_EXTERNAL_INSTALLER) {
    storage_source = "/mnt/runtime/write";
  } else if (mount_mode == MOUNT_EXTERNAL_FULL) {
    storage_source = "/mnt/runtime/full";
  } else if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
    // Sane default of no storage visible
    // Sane default of no storage visible
    return;
    return;
  }
  }
@@ -667,26 +690,15 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode,
    return;
    return;
  }
  }


  if (TEMP_FAILURE_RETRY(mount(storage_source.string(), "/storage", nullptr,
  const std::string& storage_source = ExternalStorageViews[mount_mode];
                               MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {

    fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
  BindMount(storage_source, "/storage", fail_fn);
                         storage_source.string(),
                         strerror(errno)));
  }


  // Mount user-specific symlink helper into place
  // Mount user-specific symlink helper into place
  userid_t user_id = multiuser_get_user_id(uid);
  userid_t user_id = multiuser_get_user_id(uid);
  const String8 user_source(String8::format("/mnt/user/%d", user_id));
  const std::string user_source = StringPrintf("/mnt/user/%d", user_id);
  if (fs_prepare_dir(user_source.string(), 0751, 0, 0) == -1) {
  CreateDir(user_source, 0751, AID_ROOT, AID_ROOT, fail_fn);
    fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s",
  BindMount(user_source, "/storage/self", fail_fn);
                         user_source.string()));
  }

  if (TEMP_FAILURE_RETRY(mount(user_source.string(), "/storage/self",
                               nullptr, MS_BIND, nullptr)) == -1) {
    fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
                         user_source.string(), strerror(errno)));
  }
}
}


static bool NeedsNoRandomizeWorkaround() {
static bool NeedsNoRandomizeWorkaround() {