Multi-user external storage support.
Remount rootfs as recursively shared, so that mount changes are
propagated into child namespaces. Mount external storage for access
from adb.
Clean multi-user dependencies for use in Dalvik. Also define
external storage paths.
Bug: 6925012
Change-Id: I375de581a63f4f36667894c56a34a9dd45361e8f
diff --git a/adb/adb.c b/adb/adb.c
index 200fc3c..a13a7c9 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -35,6 +35,7 @@
#include <private/android_filesystem_config.h>
#include <linux/capability.h>
#include <linux/prctl.h>
+#include <sys/mount.h>
#else
#include "usb_vendors.h"
#endif
@@ -989,6 +990,26 @@
}
#endif /* !ADB_HOST */
+#if !ADB_HOST
+/* Give ourselves access to external storage, which is otherwise protected. */
+static void mount_external_storage(void) {
+ // Create private mount namespace for our process
+ if (unshare(CLONE_NEWNS) == -1) {
+ fatal_errno("Failed to unshare()");
+ }
+
+ // Mark rootfs as being a slave in our process so that changes
+ // from parent namespace flow into our process.
+ if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) {
+ fatal_errno("Failed to mount() rootfs as MS_SLAVE");
+ }
+
+ if (mount(EXTERNAL_STORAGE_SYSTEM, EXTERNAL_STORAGE_APP, "none", MS_BIND, NULL) == -1) {
+ fatal_errno("Failed to mount() from %s", EXTERNAL_STORAGE_SYSTEM);
+ }
+}
+#endif /* !ADB_HOST */
+
int adb_main(int is_daemon, int server_port)
{
#if !ADB_HOST
@@ -1008,7 +1029,6 @@
init_transport_registration();
-
#if ADB_HOST
HOST = 1;
usb_vendors_init();
@@ -1022,6 +1042,8 @@
}
#else
+ mount_external_storage();
+
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (should_drop_privileges()) {
diff --git a/include/cutils/multiuser.h b/include/cutils/multiuser.h
index 22bb032..0bf403c 100644
--- a/include/cutils/multiuser.h
+++ b/include/cutils/multiuser.h
@@ -30,9 +30,9 @@
typedef uid_t userid_t;
typedef uid_t appid_t;
-extern userid_t getUserId(uid_t uid);
-extern appid_t getAppId(uid_t uid);
-extern uid_t getUid(userid_t userId, appid_t appId);
+extern userid_t multiuser_getUserId(uid_t uid);
+extern appid_t multiuser_getAppId(uid_t uid);
+extern uid_t multiuser_getUid(userid_t userId, appid_t appId);
#ifdef __cplusplus
}
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 6521cbe..012c2ae 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -229,6 +229,9 @@
{ 00644, AID_ROOT, AID_ROOT, 0 },
};
+#define EXTERNAL_STORAGE_SYSTEM "/mnt/secure/sdcard0"
+#define EXTERNAL_STORAGE_APP "/storage/sdcard0"
+
static inline void fs_config(const char *path, int dir,
unsigned *uid, unsigned *gid, unsigned *mode)
{
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 2477d23..6d525ba 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -50,7 +50,8 @@
threads.c \
sched_policy.c \
iosched_policy.c \
- str_parms.c
+ str_parms.c \
+ multiuser.c
commonHostSources := \
ashmem-host.c
@@ -124,8 +125,7 @@
mq.c \
partition_utils.c \
qtaguid.c \
- uevent.c \
- multiuser.c
+ uevent.c
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES += arch-arm/memset32.S
diff --git a/libcutils/multiuser.c b/libcutils/multiuser.c
index be9304d..3c86cee 100644
--- a/libcutils/multiuser.c
+++ b/libcutils/multiuser.c
@@ -14,19 +14,16 @@
* limitations under the License.
*/
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <cutils/multiuser.h>
-userid_t getUserId(uid_t uid) {
+userid_t multiuser_getUserId(uid_t uid) {
return uid / MULTIUSER_APP_PER_USER_RANGE;
}
-appid_t getAppId(uid_t uid) {
+appid_t multiuser_getAppId(uid_t uid) {
return uid % MULTIUSER_APP_PER_USER_RANGE;
}
-uid_t getUid(userid_t userId, appid_t appId) {
+uid_t multiuser_getUid(userid_t userId, appid_t appId) {
return userId * MULTIUSER_APP_PER_USER_RANGE + (appId % MULTIUSER_APP_PER_USER_RANGE);
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 4c20ec1..5a31a8e 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -128,6 +128,8 @@
on post-fs
# once everything is setup, no need to modify /
mount rootfs rootfs / ro remount
+ # mount shared so changes propagate into child namespaces
+ mount rootfs rootfs / shared rec
# We chown/chmod /cache again so because mount is run as root + defaults
chown system cache /cache