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

Commit 98cb3f09 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Allow some apps to get full access to external storage.

Apps with WRITE_MEDIA_STORAGE permission will get
full access to external storage.

Bug: 111890351
Test: manual

Change-Id: Icbfe1f68c0bfca77bdc557e9903ded45994f5945
parent 07ae651a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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();

+3 −1
Original line number Diff line number Diff line
@@ -644,6 +644,8 @@ class ZygoteConnection {
                    mountExternal = Zygote.MOUNT_EXTERNAL_READ;
                } else if (arg.equals("--mount-external-write")) {
                    mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
                } 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")) {
+40 −14
Original line number Diff line number Diff line
@@ -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,10 +434,34 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
    }

    if (GetBoolProperty(kIsolatedStorage, 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;
@@ -447,6 +472,7 @@ static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
                        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) {
+29 −25
Original line number Diff line number Diff line
@@ -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,6 +659,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                    }
                });

        if (!SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) {
            StorageManagerInternal storageManagerInternal = LocalServices.getService(
                    StorageManagerInternal.class);
            storageManagerInternal.addExternalStoragePolicy(
@@ -685,6 +688,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                        }
                    });
        }
    }

    public void packageRemoved(int uid, String packageName) {
        synchronized (this) {
Loading