diff options
-rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 7 | ||||
-rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 35 |
2 files changed, 39 insertions, 3 deletions
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 16dc1331fdbc..52b72a4e9991 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -610,6 +610,13 @@ public class ZygoteInit { // an error. ZygoteHooks.startZygoteNoThreadCreation(); + // Zygote goes into its own process group. + try { + Os.setpgid(0, 0); + } catch (ErrnoException ex) { + throw new RuntimeException("Failed to setpgid(0,0)", ex); + } + try { Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit"); RuntimeInit.enableDdms(); diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 3f4b2a61321b..5202a98bc030 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -32,6 +32,7 @@ #include <signal.h> #include <stdlib.h> #include <sys/capability.h> +#include <sys/cdefs.h> #include <sys/personality.h> #include <sys/prctl.h> #include <sys/resource.h> @@ -667,11 +668,39 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* env, jclass) { // Zygote process unmount root storage space initially before every child processes are forked. // Every forked child processes (include SystemServer) only mount their own root storage space - // And no need unmount storage operation in MountEmulatedStorage method. - // Zygote process does not utilize root storage spaces and unshared its mount namespace from the ART. + // and no need unmount storage operation in MountEmulatedStorage method. + // Zygote process does not utilize root storage spaces and unshares its mount namespace below. + + // See storage config details at http://source.android.com/tech/storage/ + // Create private mount namespace shared by all children + if (unshare(CLONE_NEWNS) == -1) { + RuntimeAbort(env, __LINE__, "Failed to unshare()"); + return; + } + + // Mark rootfs as being a slave so that changes from default + // namespace only flow into our children. + if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) { + RuntimeAbort(env, __LINE__, "Failed to mount() rootfs as MS_SLAVE"); + return; + } + + // Create a staging tmpfs that is shared by our children; they will + // bind mount storage into their respective private namespaces, which + // are isolated from each other. + const char* target_base = getenv("EMULATED_STORAGE_TARGET"); + if (target_base != nullptr) { +#define STRINGIFY_UID(x) __STRING(x) + if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV, + "uid=0,gid=" STRINGIFY_UID(AID_SDCARD_R) ",mode=0751") == -1) { + ALOGE("Failed to mount tmpfs to %s", target_base); + RuntimeAbort(env, __LINE__, "Failed to mount tmpfs"); + return; + } +#undef STRINGIFY_UID + } UnmountTree("/storage"); - return; } static const JNINativeMethod gMethods[] = { |