From 4bfe963ad48a4864e2a35c4998328561dbced544 Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Mon, 23 Sep 2013 11:00:35 +0200 Subject: [PATCH] Make emulated storage mounting consistent to Zygote. - Mount in private namespace - Mount in forked child - Mount /storage/emulated/legacy All of this is optional and must be enabled by setting the environment variable MOUNT_EMULATED_STORAGE. Change-Id: Ied9c4485e58ab26ba8e6eafcbe05bb75fe6fdc52 --- Android.mk | 2 +- Superuser/jni/Android.mk | 4 +-- Superuser/jni/su/daemon.c | 66 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Android.mk b/Android.mk index 8030a7b..7887812 100644 --- a/Android.mk +++ b/Android.mk @@ -19,7 +19,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := su LOCAL_MODULE_TAGS := eng debug optional LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_STATIC_LIBRARIES := libc +LOCAL_STATIC_LIBRARIES := libc libcutils LOCAL_C_INCLUDES := external/sqlite/dist LOCAL_SRC_FILES := Superuser/jni/su/su.c Superuser/jni/su/daemon.c Superuser/jni/su/activity.c Superuser/jni/su/db.c Superuser/jni/su/utils.c ../../sqlite/dist/sqlite3.c LOCAL_CFLAGS := -DSQLITE_OMIT_LOAD_EXTENSION -DREQUESTOR=\"$(SUPERUSER_PACKAGE)\" diff --git a/Superuser/jni/Android.mk b/Superuser/jni/Android.mk index 41542b9..ffb2abf 100644 --- a/Superuser/jni/Android.mk +++ b/Superuser/jni/Android.mk @@ -3,8 +3,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := su -LOCAL_LDFLAGS := -static -LOCAL_STATIC_LIBRARIES := sqlite3 +LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_STATIC_LIBRARIES := sqlite3 libcutils libc LOCAL_C_INCLUDES := $(LOCAL_PATH)/sqlite3 LOCAL_SRC_FILES := su/su.c su/activity.c su/db.c su/utils.c su/daemon.c include $(BUILD_EXECUTABLE) diff --git a/Superuser/jni/su/daemon.c b/Superuser/jni/su/daemon.c index 3c2f233..0042d24 100644 --- a/Superuser/jni/su/daemon.c +++ b/Superuser/jni/su/daemon.c @@ -15,6 +15,8 @@ ** limitations under the License. */ +#define _GNU_SOURCE /* for unshare() */ + #include #include #include @@ -34,7 +36,9 @@ #include #include #include +#include #include +#include #include "su.h" #include "utils.h" @@ -91,6 +95,41 @@ static void write_string(int fd, char* val) { } } +static void mount_emulated_storage(int user_id) { + const char *emulated_source = getenv("EMULATED_STORAGE_SOURCE"); + const char *emulated_target = getenv("EMULATED_STORAGE_TARGET"); + const char* legacy = getenv("EXTERNAL_STORAGE"); + + if (!emulated_source || !emulated_target) { + // No emulated storage is present + return; + } + + // Create a second private mount namespace for our process + if (unshare(CLONE_NEWNS) < 0) { + PLOGE("unshare"); + return; + } + + if (mount("rootfs", "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { + PLOGE("mount rootfs as slave"); + return; + } + + // /mnt/shell/emulated -> /storage/emulated + if (mount(emulated_source, emulated_target, NULL, MS_BIND, NULL) < 0) { + PLOGE("mount emulated storage"); + } + + char target_user[PATH_MAX]; + snprintf(target_user, PATH_MAX, "%s/%d", emulated_target, user_id); + + // /mnt/shell/emulated/ -> /storage/emulated/legacy + if (mount(target_user, legacy, NULL, MS_BIND | MS_REC, NULL) < 0) { + PLOGE("mount legacy path"); + } +} + static int run_daemon_child(int infd, int outfd, int errfd, int argc, char** argv) { if (-1 == dup2(outfd, STDOUT_FILENO)) { PLOGE("dup2 child outfd"); @@ -171,6 +210,7 @@ static int daemon_accept(int fd) { daemon_from_pid = credentials.pid; } + int mount_storage = read_int(fd); int argc = read_int(fd); if (argc < 0 || argc > 512) { LOGE("unable to allocate args: %d", argc); @@ -291,6 +331,10 @@ static int daemon_accept(int fd) { outfd = pts; } + if (mount_storage) { + mount_emulated_storage(multiuser_get_user_id(daemon_from_uid)); + } + return run_daemon_child(infd, outfd, errfd, argc, argv); } @@ -349,19 +393,6 @@ int run_daemon() { unlink(sun.sun_path); unlink(REQUESTOR_DAEMON_PATH); - /* - * Mount emulated storage, if present. Normally that's done by zygote, - * but as we're started via init, we have to do it ourselves. - */ - const char *emulated_source = getenv("EMULATED_STORAGE_SOURCE"); - const char *emulated_target = getenv("EMULATED_STORAGE_TARGET"); - if (emulated_source && *emulated_source && emulated_target && *emulated_target) { - if (mount(emulated_source, emulated_target, NULL, - MS_BIND | MS_NOEXEC | MS_NOSUID, NULL) < 0) { - PLOGE("mount emulated storage"); - } - } - int previous_umask = umask(027); mkdir(REQUESTOR_DAEMON_PATH, 0777); @@ -431,14 +462,21 @@ int connect_daemon(int argc, char *argv[]) { } LOGD("connecting client %d", getpid()); + + int mount_storage = getenv("MOUNT_EMULATED_STORAGE") != NULL; + write_int(socketfd, getpid()); write_int(socketfd, isatty(STDIN_FILENO)); write_int(socketfd, uid); write_int(socketfd, getppid()); - write_int(socketfd, argc); + write_int(socketfd, mount_storage); + write_int(socketfd, mount_storage ? argc - 1 : argc); int i; for (i = 0; i < argc; i++) { + if (i == 1 && mount_storage) { + continue; + } write_string(socketfd, argv[i]); } -- 2.11.0