diff options
| author | 2018-07-30 17:34:21 -0700 | |
|---|---|---|
| committer | 2018-07-31 01:34:16 +0000 | |
| commit | 663b1046c1c7cffa474eeccad1827853eff8b5a4 (patch) | |
| tree | f6a636863215aa6a0bcc2efb50266494148719ba | |
| parent | e2f5ce74d54f9ab06876d0dbc28a6ca4029cc3b0 (diff) | |
Mount package sandboxes during process initialization.
vold creates external storage sandboxes for packages at
/mnt/user/<user-id>/package/<package-name> when the user starts.
These package specific sandboxes will be mounted at /storage
whenever a new process starts.
Bug: 111890351
Test: n/a (changes are protected by a sys property, there's no change in
behavior without turning on that property)
Change-Id: I8db4ab823c8dccc454e8004b119ba394a08d6475
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 81 |
1 files changed, 61 insertions, 20 deletions
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index daf15e949cd8..738069216b2c 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -70,6 +70,7 @@ namespace { using android::String8; +using android::base::StringAppendF; using android::base::StringPrintf; using android::base::WriteStringToFile; using android::base::GetBoolProperty; @@ -79,6 +80,7 @@ using android::base::GetBoolProperty; static pid_t gSystemServerPid = 0; +static const char kIsolatedStorage[] = "persist.sys.isolated_storage"; static const char kZygoteClassName[] = "com/android/internal/os/Zygote"; static jclass gZygoteClass; static jmethodID gCallPostForkChildHooks; @@ -379,6 +381,28 @@ static int UnmountTree(const char* path) { return 0; } +static bool createPkgSandbox(uid_t uid, const char* package_name, std::string& pkg_sandbox_dir, + std::string* error_msg) { + // Create /mnt/user/0/package/<package-name> + userid_t user_id = multiuser_get_user_id(uid); + StringAppendF(&pkg_sandbox_dir, "/%d", user_id); + if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { + *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()); + return false; + } + StringAppendF(&pkg_sandbox_dir, "/package"); + if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { + *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()); + return false; + } + StringAppendF(&pkg_sandbox_dir, "/%s", package_name); + if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) { + *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()); + return false; + } + return true; +} + // Create a private mount namespace and bind mount appropriate emulated // storage for the given user. static bool MountEmulatedStorage(uid_t uid, jint mount_mode, @@ -408,27 +432,44 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode, return true; } - if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage", - NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) { - *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s", - storageSource.string(), - strerror(errno)); - return false; - } + if (GetBoolProperty(kIsolatedStorage, false)) { + if (package_name == nullptr) { + return true; + } - // Mount user-specific symlink helper into place - userid_t user_id = multiuser_get_user_id(uid); - const String8 userSource(String8::format("/mnt/user/%d", user_id)); - if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) { - *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", userSource.string()); - return false; - } - if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self", - NULL, MS_BIND, NULL)) == -1) { - *error_msg = CREATE_ERROR("Failed to mount %s to /storage/self: %s", - userSource.string(), - strerror(errno)); - return false; + std::string pkgSandboxDir("/mnt/user"); + if (!createPkgSandbox(uid, package_name, pkgSandboxDir, error_msg)) { + return false; + } + if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage", + nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) { + *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s", + pkgSandboxDir.c_str(), strerror(errno)); + return false; + } + } else { + if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage", + NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) { + *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s", + storageSource.string(), + strerror(errno)); + return false; + } + + // Mount user-specific symlink helper into place + userid_t user_id = multiuser_get_user_id(uid); + const String8 userSource(String8::format("/mnt/user/%d", user_id)); + if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) { + *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", userSource.string()); + return false; + } + if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self", + NULL, MS_BIND, NULL)) == -1) { + *error_msg = CREATE_ERROR("Failed to mount %s to /storage/self: %s", + userSource.string(), + strerror(errno)); + return false; + } } return true; |