Access to all users' external storage.

System services holding this permission have external storage bound
one level higher, giving them access to all users' files.

Bug: 7003520
Change-Id: Id95d6d5b2fa2ff75c0c94f18f81cb118f837f665
diff --git a/vm/native/dalvik_system_Zygote.cpp b/vm/native/dalvik_system_Zygote.cpp
index beddc51..53b4b4c 100644
--- a/vm/native/dalvik_system_Zygote.cpp
+++ b/vm/native/dalvik_system_Zygote.cpp
@@ -59,6 +59,7 @@
     MOUNT_EXTERNAL_NONE = 0,
     MOUNT_EXTERNAL_SINGLEUSER = 1,
     MOUNT_EXTERNAL_MULTIUSER = 2,
+    MOUNT_EXTERNAL_MULTIUSER_ALL = 3,
 };
 
 /*
@@ -264,7 +265,8 @@
     }
 
     // Create bind mounts to expose external storage
-    if (mountExternal == MOUNT_EXTERNAL_MULTIUSER) {
+    if (mountExternal == MOUNT_EXTERNAL_MULTIUSER
+            || mountExternal == MOUNT_EXTERNAL_MULTIUSER_ALL) {
         const char* storage_base = getenv("ANDROID_STORAGE");
         const char* target = getenv("EXTERNAL_STORAGE");
         const char* source_base = getenv("MULTIUSER_EXTERNAL_STORAGE");
@@ -290,29 +292,38 @@
             return -1;
         }
 
-        // Mount our user-specific external storage into place
-        std::string source(StringPrintf("%s/%d", source_base, userid));
-        if (fs_prepare_dir(source.c_str(), 0000, 0, 0) == -1) {
-            return -1;
-        }
-        if (mount(source.c_str(), target, NULL, MS_BIND, NULL) == -1) {
-            SLOGE("Failed to bind mount %s to %s: %s", source.c_str(), target, strerror(errno));
-            return -1;
-        }
+        if (mountExternal == MOUNT_EXTERNAL_MULTIUSER_ALL) {
+            // External storage for all users
+            if (mount(source_base, target, NULL, MS_BIND, NULL) == -1) {
+                SLOGE("Failed to mount %s to %s: %s", source_base, target, strerror(errno));
+                return -1;
+            }
 
-        // Mount shared OBB storage into place
-        std::string obb_source(StringPrintf("%s/obb", source_base));
-        std::string android_target(StringPrintf("%s/Android", target));
-        std::string android_obb_target(StringPrintf("%s/Android/obb", target));
-        if (fs_prepare_dir(obb_source.c_str(), 0000, 0, 0) == -1
-                || fs_prepare_dir(android_target.c_str(), 0000, 0, 0) == -1
-                || fs_prepare_dir(android_obb_target.c_str(), 0000, 0, 0) == -1) {
-            return -1;
-        }
-        if (mount(obb_source.c_str(), android_obb_target.c_str(), NULL, MS_BIND, NULL) == -1) {
-            SLOGE("Failed to bind mount %s to %s: %s",
-                    obb_source.c_str(), android_obb_target.c_str(), strerror(errno));
-            return -1;
+        } else {
+            // External storage for specific user
+            std::string source(StringPrintf("%s/%d", source_base, userid));
+            if (fs_prepare_dir(source.c_str(), 0000, 0, 0) == -1) {
+                return -1;
+            }
+            if (mount(source.c_str(), target, NULL, MS_BIND, NULL) == -1) {
+                SLOGE("Failed to mount %s to %s: %s", source.c_str(), target, strerror(errno));
+                return -1;
+            }
+
+            // Mount shared OBB storage into place
+            std::string obb_source(StringPrintf("%s/obb", source_base));
+            std::string android_target(StringPrintf("%s/Android", target));
+            std::string android_obb_target(StringPrintf("%s/Android/obb", target));
+            if (fs_prepare_dir(obb_source.c_str(), 0000, 0, 0) == -1
+                    || fs_prepare_dir(android_target.c_str(), 0000, 0, 0) == -1
+                    || fs_prepare_dir(android_obb_target.c_str(), 0000, 0, 0) == -1) {
+                return -1;
+            }
+            if (mount(obb_source.c_str(), android_obb_target.c_str(), NULL, MS_BIND, NULL) == -1) {
+                SLOGE("Failed to bind mount %s to %s: %s",
+                        obb_source.c_str(), android_obb_target.c_str(), strerror(errno));
+                return -1;
+            }
         }
 
     } else {