summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/ZygoteProcess.java3
-rw-r--r--core/java/com/android/internal/os/Zygote.java2
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java4
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp54
-rw-r--r--services/core/java/com/android/server/AppOpsService.java54
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java6
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;
}