diff options
6 files changed, 83 insertions, 40 deletions
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 067e8493717b..732d3778ec6d 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -384,7 +384,10 @@ public class ZygoteProcess { argsForZygote.add("--mount-external-read"); } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) { argsForZygote.add("--mount-external-write"); + } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) { + argsForZygote.add("--mount-external-full"); } + argsForZygote.add("--target-sdk-version=" + targetSdkVersion); // --setgroups is a comma-separated list diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 413f89da571e..927322e97e28 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -81,6 +81,8 @@ public final class Zygote { public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ; /** Read-write external storage should be mounted. */ public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE; + /** Read-write external storage should be mounted instead of package sandbox */ + public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL; private static final ZygoteHooks VM_HOOKS = new ZygoteHooks(); diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index b9c717f03749..b60b43a8d45d 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -644,7 +644,9 @@ class ZygoteConnection { mountExternal = Zygote.MOUNT_EXTERNAL_READ; } else if (arg.equals("--mount-external-write")) { mountExternal = Zygote.MOUNT_EXTERNAL_WRITE; - } else if (arg.equals("--query-abi-list")) { + } else if (arg.equals("--mount-external-full")) { + mountExternal = Zygote.MOUNT_EXTERNAL_FULL; + } else if (arg.equals("--query-abi-list")) { abiListQuery = true; } else if (arg.equals("--get-pid")) { pidQuery = true; diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 19691e2cfbe3..364393e1c649 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -93,6 +93,7 @@ enum MountExternalKind { MOUNT_EXTERNAL_DEFAULT = 1, MOUNT_EXTERNAL_READ = 2, MOUNT_EXTERNAL_WRITE = 3, + MOUNT_EXTERNAL_FULL = 4, }; static void RuntimeAbort(JNIEnv* env, int line, const char* msg) { @@ -416,7 +417,7 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode, storageSource = "/mnt/runtime/read"; } else if (mount_mode == MOUNT_EXTERNAL_WRITE) { storageSource = "/mnt/runtime/write"; - } else if (!force_mount_namespace) { + } else if (mount_mode != MOUNT_EXTERNAL_FULL && !force_mount_namespace) { // Sane default of no storage visible return true; } @@ -433,19 +434,44 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode, } if (GetBoolProperty(kIsolatedStorage, false)) { - if (package_name == nullptr) { - return true; - } - - 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; + if (mount_mode == MOUNT_EXTERNAL_FULL) { + storageSource = "/mnt/runtime/write"; + 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; + } + } else { + if (package_name == nullptr) { + return true; + } + 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", diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index b3f6bd1d41cc..998e441f67d8 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -45,8 +45,10 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.provider.Settings; import android.util.ArrayMap; @@ -657,33 +659,35 @@ public class AppOpsService extends IAppOpsService.Stub { } }); - StorageManagerInternal storageManagerInternal = LocalServices.getService( - StorageManagerInternal.class); - storageManagerInternal.addExternalStoragePolicy( - new StorageManagerInternal.ExternalStorageMountPolicy() { - @Override - public int getMountMode(int uid, String packageName) { - if (Process.isIsolated(uid)) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, - packageName) != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_NONE; - } - if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, - packageName) != AppOpsManager.MODE_ALLOWED) { - return Zygote.MOUNT_EXTERNAL_READ; + if (!SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) { + StorageManagerInternal storageManagerInternal = LocalServices.getService( + StorageManagerInternal.class); + storageManagerInternal.addExternalStoragePolicy( + new StorageManagerInternal.ExternalStorageMountPolicy() { + @Override + public int getMountMode(int uid, String packageName) { + if (Process.isIsolated(uid)) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid, + packageName) != AppOpsManager.MODE_ALLOWED) { + return Zygote.MOUNT_EXTERNAL_NONE; + } + if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid, + packageName) != AppOpsManager.MODE_ALLOWED) { + return Zygote.MOUNT_EXTERNAL_READ; + } + return Zygote.MOUNT_EXTERNAL_WRITE; } - return Zygote.MOUNT_EXTERNAL_WRITE; - } - @Override - public boolean hasExternalStorage(int uid, String packageName) { - final int mountMode = getMountMode(uid, packageName); - return mountMode == Zygote.MOUNT_EXTERNAL_READ - || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; - } - }); + @Override + public boolean hasExternalStorage(int uid, String packageName) { + final int mountMode = getMountMode(uid, packageName); + return mountMode == Zygote.MOUNT_EXTERNAL_READ + || mountMode == Zygote.MOUNT_EXTERNAL_WRITE; + } + }); + } } public void packageRemoved(int uid, String packageName) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 18bed54d42c1..59c4697e4f1e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -24,6 +24,7 @@ import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; +import static android.Manifest.permission.WRITE_MEDIA_STORAGE; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.CATEGORY_DEFAULT; import static android.content.Intent.CATEGORY_HOME; @@ -20034,6 +20035,11 @@ public class PackageManagerService extends IPackageManager.Stub if (Process.isIsolated(uid)) { return Zygote.MOUNT_EXTERNAL_NONE; } + if (SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) { + return checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED + ? Zygote.MOUNT_EXTERNAL_FULL + : Zygote.MOUNT_EXTERNAL_WRITE; + } if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { return Zygote.MOUNT_EXTERNAL_DEFAULT; } |