Loading core/java/com/android/internal/os/Zygote.java +8 −14 Original line number Diff line number Diff line Loading @@ -197,9 +197,6 @@ public final class Zygote { private Zygote() {} /** Called for some security initialization before any fork. */ static native void nativeSecurityInit(); /** * Forks a new VM instance. The current VM must have been started * with the -Xzygote flag. <b>NOTE: new instance keeps all Loading Loading @@ -384,22 +381,19 @@ public final class Zygote { native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax); /** * Zygote unmount storage space on initializing. * This method is called once. */ protected static native void nativeUnmountStorageOnInit(); /** * Get socket file descriptors (opened by init) from the environment and * store them for access from native code later. * Initialize the native state of the Zygote. This inclues * - Fetching socket FDs from the environment * - Initializing security properties * - Unmounting storage as appropriate * - Loading necessary performance profile information * * @param isPrimary True if this is the zygote process, false if it is zygote_secondary */ public static void getSocketFDs(boolean isPrimary) { nativeGetSocketFDs(isPrimary); static void initNativeState(boolean isPrimary) { nativeInitNativeState(isPrimary); } protected static native void nativeGetSocketFDs(boolean isPrimary); protected static native void nativeInitNativeState(boolean isPrimary); /** * Returns the raw string value of a system property. Loading core/java/com/android/internal/os/ZygoteInit.java +3 −7 Original line number Diff line number Diff line Loading @@ -20,10 +20,10 @@ import static android.system.OsConstants.S_IRWXG; import static android.system.OsConstants.S_IRWXO; import android.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.TypedArray; import android.app.ApplicationLoaders; import android.content.pm.SharedLibraryInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -863,8 +863,6 @@ public class ZygoteInit { throw new RuntimeException("No ABI list supplied."); } Zygote.getSocketFDs(isPrimaryZygote); // In some configurations, we avoid preloading resources and classes eagerly. // In such cases, we will preload things prior to our first fork. if (!enableLazyPreload) { Loading @@ -889,10 +887,8 @@ public class ZygoteInit { // Zygote. Trace.setTracingEnabled(false, 0); Zygote.nativeSecurityInit(); // Zygote process unmounts root storage spaces. Zygote.nativeUnmountStorageOnInit(); Zygote.initNativeState(isPrimaryZygote); ZygoteHooks.stopZygoteNoThreadCreation(); Loading core/jni/com_android_internal_os_Zygote.cpp +72 −56 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ static constexpr const char* kZygoteInitClassName = "com/android/internal/os/Zyg static jclass gZygoteInitClass; static jmethodID gCreateSystemServerClassLoader; static bool g_is_security_enforced = true; static bool gIsSecurityEnforced = true; /** * The maximum number of characters (not including a null terminator) that a Loading Loading @@ -510,7 +510,7 @@ static void PreApplicationInit() { } static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) { if (!g_is_security_enforced) { if (!gIsSecurityEnforced) { ALOGI("seccomp disabled by setenforce 0"); return; } Loading Loading @@ -1626,18 +1626,48 @@ std::vector<int> MakeUsapPipeReadFDVector() { return fd_vec; } } // anonymous namespace static void UnmountStorageOnInit(JNIEnv* env) { // 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 unshares its mount namespace below. namespace android { // 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; } static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) { // security_getenforce is not allowed on app process. Initialize and cache // the value before zygote forks. g_is_security_enforced = security_getenforce(); // 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; } selinux_android_seapp_context_init(); // 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"); } } // anonymous namespace namespace android { static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) { PreApplicationInit(); } Loading Loading @@ -1791,47 +1821,9 @@ static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork( FileDescriptorWhitelist::Get()->Allow(path_cstr); } 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 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"); } static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter( JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) { if (!g_is_security_enforced) { if (!gIsSecurityEnforced) { ALOGI("seccomp disabled by setenforce 0"); return; } Loading Loading @@ -1883,8 +1875,12 @@ static void com_android_internal_os_Zygote_nativeSpecializeAppProcess( * @param is_primary If this process is the primary or secondary Zygote; used to compute the name * of the environment variable storing the file descriptors. */ static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclass, static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jclass, jboolean is_primary) { /* * Obtain file descriptors created by init from the environment. */ std::string android_socket_prefix(ANDROID_SOCKET_PREFIX); std::string env_var_name = android_socket_prefix + (is_primary ? "zygote" : "zygote_secondary"); char* env_var_val = getenv(env_var_name.c_str()); Loading @@ -1905,6 +1901,30 @@ static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclas } else { ALOGE("Unable to fetch USAP pool socket file descriptor"); } /* * Security Initialization */ // security_getenforce is not allowed on app process. Initialize and cache // the value before zygote forks. gIsSecurityEnforced = security_getenforce(); selinux_android_seapp_context_init(); /* * Storage Initialization */ UnmountStorageOnInit(env); /* * Performance Initialization */ if (!SetTaskProfiles(0, {})) { ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed"); } } /** Loading Loading @@ -2001,8 +2021,6 @@ static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv* } static const JNINativeMethod gMethods[] = { { "nativeSecurityInit", "()V", (void *) com_android_internal_os_Zygote_nativeSecurityInit }, { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, Loading @@ -2010,8 +2028,6 @@ static const JNINativeMethod gMethods[] = { (void *) com_android_internal_os_Zygote_nativeForkSystemServer }, { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork }, { "nativeUnmountStorageOnInit", "()V", (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit }, { "nativePreApplicationInit", "()V", (void *) com_android_internal_os_Zygote_nativePreApplicationInit }, { "nativeInstallSeccompUidGidFilter", "(II)V", Loading @@ -2021,8 +2037,8 @@ static const JNINativeMethod gMethods[] = { { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeSpecializeAppProcess }, { "nativeGetSocketFDs", "(Z)V", (void *) com_android_internal_os_Zygote_nativeGetSocketFDs }, { "nativeInitNativeState", "(Z)V", (void *) com_android_internal_os_Zygote_nativeInitNativeState }, { "nativeGetUsapPipeFDs", "()[I", (void *) com_android_internal_os_Zygote_nativeGetUsapPipeFDs }, { "nativeRemoveUsapTableEntry", "(I)Z", Loading Loading
core/java/com/android/internal/os/Zygote.java +8 −14 Original line number Diff line number Diff line Loading @@ -197,9 +197,6 @@ public final class Zygote { private Zygote() {} /** Called for some security initialization before any fork. */ static native void nativeSecurityInit(); /** * Forks a new VM instance. The current VM must have been started * with the -Xzygote flag. <b>NOTE: new instance keeps all Loading Loading @@ -384,22 +381,19 @@ public final class Zygote { native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax); /** * Zygote unmount storage space on initializing. * This method is called once. */ protected static native void nativeUnmountStorageOnInit(); /** * Get socket file descriptors (opened by init) from the environment and * store them for access from native code later. * Initialize the native state of the Zygote. This inclues * - Fetching socket FDs from the environment * - Initializing security properties * - Unmounting storage as appropriate * - Loading necessary performance profile information * * @param isPrimary True if this is the zygote process, false if it is zygote_secondary */ public static void getSocketFDs(boolean isPrimary) { nativeGetSocketFDs(isPrimary); static void initNativeState(boolean isPrimary) { nativeInitNativeState(isPrimary); } protected static native void nativeGetSocketFDs(boolean isPrimary); protected static native void nativeInitNativeState(boolean isPrimary); /** * Returns the raw string value of a system property. Loading
core/java/com/android/internal/os/ZygoteInit.java +3 −7 Original line number Diff line number Diff line Loading @@ -20,10 +20,10 @@ import static android.system.OsConstants.S_IRWXG; import static android.system.OsConstants.S_IRWXO; import android.annotation.UnsupportedAppUsage; import android.content.res.Resources; import android.content.res.TypedArray; import android.app.ApplicationLoaders; import android.content.pm.SharedLibraryInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -863,8 +863,6 @@ public class ZygoteInit { throw new RuntimeException("No ABI list supplied."); } Zygote.getSocketFDs(isPrimaryZygote); // In some configurations, we avoid preloading resources and classes eagerly. // In such cases, we will preload things prior to our first fork. if (!enableLazyPreload) { Loading @@ -889,10 +887,8 @@ public class ZygoteInit { // Zygote. Trace.setTracingEnabled(false, 0); Zygote.nativeSecurityInit(); // Zygote process unmounts root storage spaces. Zygote.nativeUnmountStorageOnInit(); Zygote.initNativeState(isPrimaryZygote); ZygoteHooks.stopZygoteNoThreadCreation(); Loading
core/jni/com_android_internal_os_Zygote.cpp +72 −56 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ static constexpr const char* kZygoteInitClassName = "com/android/internal/os/Zyg static jclass gZygoteInitClass; static jmethodID gCreateSystemServerClassLoader; static bool g_is_security_enforced = true; static bool gIsSecurityEnforced = true; /** * The maximum number of characters (not including a null terminator) that a Loading Loading @@ -510,7 +510,7 @@ static void PreApplicationInit() { } static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) { if (!g_is_security_enforced) { if (!gIsSecurityEnforced) { ALOGI("seccomp disabled by setenforce 0"); return; } Loading Loading @@ -1626,18 +1626,48 @@ std::vector<int> MakeUsapPipeReadFDVector() { return fd_vec; } } // anonymous namespace static void UnmountStorageOnInit(JNIEnv* env) { // 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 unshares its mount namespace below. namespace android { // 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; } static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) { // security_getenforce is not allowed on app process. Initialize and cache // the value before zygote forks. g_is_security_enforced = security_getenforce(); // 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; } selinux_android_seapp_context_init(); // 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"); } } // anonymous namespace namespace android { static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) { PreApplicationInit(); } Loading Loading @@ -1791,47 +1821,9 @@ static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork( FileDescriptorWhitelist::Get()->Allow(path_cstr); } 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 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"); } static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter( JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) { if (!g_is_security_enforced) { if (!gIsSecurityEnforced) { ALOGI("seccomp disabled by setenforce 0"); return; } Loading Loading @@ -1883,8 +1875,12 @@ static void com_android_internal_os_Zygote_nativeSpecializeAppProcess( * @param is_primary If this process is the primary or secondary Zygote; used to compute the name * of the environment variable storing the file descriptors. */ static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclass, static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jclass, jboolean is_primary) { /* * Obtain file descriptors created by init from the environment. */ std::string android_socket_prefix(ANDROID_SOCKET_PREFIX); std::string env_var_name = android_socket_prefix + (is_primary ? "zygote" : "zygote_secondary"); char* env_var_val = getenv(env_var_name.c_str()); Loading @@ -1905,6 +1901,30 @@ static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclas } else { ALOGE("Unable to fetch USAP pool socket file descriptor"); } /* * Security Initialization */ // security_getenforce is not allowed on app process. Initialize and cache // the value before zygote forks. gIsSecurityEnforced = security_getenforce(); selinux_android_seapp_context_init(); /* * Storage Initialization */ UnmountStorageOnInit(env); /* * Performance Initialization */ if (!SetTaskProfiles(0, {})) { ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed"); } } /** Loading Loading @@ -2001,8 +2021,6 @@ static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv* } static const JNINativeMethod gMethods[] = { { "nativeSecurityInit", "()V", (void *) com_android_internal_os_Zygote_nativeSecurityInit }, { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, Loading @@ -2010,8 +2028,6 @@ static const JNINativeMethod gMethods[] = { (void *) com_android_internal_os_Zygote_nativeForkSystemServer }, { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork }, { "nativeUnmountStorageOnInit", "()V", (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit }, { "nativePreApplicationInit", "()V", (void *) com_android_internal_os_Zygote_nativePreApplicationInit }, { "nativeInstallSeccompUidGidFilter", "(II)V", Loading @@ -2021,8 +2037,8 @@ static const JNINativeMethod gMethods[] = { { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V", (void *) com_android_internal_os_Zygote_nativeSpecializeAppProcess }, { "nativeGetSocketFDs", "(Z)V", (void *) com_android_internal_os_Zygote_nativeGetSocketFDs }, { "nativeInitNativeState", "(Z)V", (void *) com_android_internal_os_Zygote_nativeInitNativeState }, { "nativeGetUsapPipeFDs", "()[I", (void *) com_android_internal_os_Zygote_nativeGetUsapPipeFDs }, { "nativeRemoveUsapTableEntry", "(I)Z", Loading