Loading core/java/android/os/AppZygote.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -34,8 +34,15 @@ import com.android.internal.annotations.GuardedBy; public class AppZygote { public class AppZygote { private static final String LOG_TAG = "AppZygote"; private static final String LOG_TAG = "AppZygote"; // UID of the Zygote itself private final int mZygoteUid; private final int mZygoteUid; // First UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMin; // Last UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMax; private final Object mLock = new Object(); private final Object mLock = new Object(); /** /** Loading @@ -47,9 +54,11 @@ public class AppZygote { private final ApplicationInfo mAppInfo; private final ApplicationInfo mAppInfo; public AppZygote(ApplicationInfo appInfo, int zygoteUid) { public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax) { mAppInfo = appInfo; mAppInfo = appInfo; mZygoteUid = zygoteUid; mZygoteUid = zygoteUid; mZygoteUidGidMin = uidGidMin; mZygoteUidGidMax = uidGidMax; } } /** /** Loading Loading @@ -104,7 +113,9 @@ public class AppZygote { "app_zygote", // seInfo "app_zygote", // seInfo abi, // abi abi, // abi abi, // acceptedAbiList abi, // acceptedAbiList null); // instructionSet null, // instructionSet mZygoteUidGidMin, mZygoteUidGidMax); ZygoteProcess.waitForConnectionToZygote(mZygote.getPrimarySocketAddress()); ZygoteProcess.waitForConnectionToZygote(mZygote.getPrimarySocketAddress()); // preload application code in the zygote // preload application code in the zygote Loading core/java/android/os/ZygoteProcess.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -809,6 +809,8 @@ public class ZygoteProcess { * may be different from <code>abi</code> in case the children * may be different from <code>abi</code> in case the children * spawned from this Zygote only communicate using ABI-safe methods. * spawned from this Zygote only communicate using ABI-safe methods. * @param instructionSet null-ok the instruction set to use. * @param instructionSet null-ok the instruction set to use. * @param uidRangeStart The first UID in the range the child zygote may setuid()/setgid() to * @param uidRangeEnd The last UID in the range the child zygote may setuid()/setgid() to */ */ public ChildZygoteProcess startChildZygote(final String processClass, public ChildZygoteProcess startChildZygote(final String processClass, final String niceName, final String niceName, Loading @@ -817,13 +819,17 @@ public class ZygoteProcess { String seInfo, String seInfo, String abi, String abi, String acceptedAbiList, String acceptedAbiList, String instructionSet) { String instructionSet, int uidRangeStart, int uidRangeEnd) { // Create an unguessable address in the global abstract namespace. // Create an unguessable address in the global abstract namespace. final LocalSocketAddress serverAddress = new LocalSocketAddress( final LocalSocketAddress serverAddress = new LocalSocketAddress( processClass + "/" + UUID.randomUUID().toString()); processClass + "/" + UUID.randomUUID().toString()); final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName(), final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName(), Zygote.CHILD_ZYGOTE_ABI_LIST_ARG + acceptedAbiList}; Zygote.CHILD_ZYGOTE_ABI_LIST_ARG + acceptedAbiList, Zygote.CHILD_ZYGOTE_UID_RANGE_START + uidRangeStart, Zygote.CHILD_ZYGOTE_UID_RANGE_END + uidRangeEnd}; Process.ProcessStartResult result; Process.ProcessStartResult result; try { try { Loading core/java/android/webkit/WebViewZygote.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -160,7 +160,9 @@ public class WebViewZygote { "webview_zygote", // seInfo "webview_zygote", // seInfo sPackage.applicationInfo.primaryCpuAbi, // abi sPackage.applicationInfo.primaryCpuAbi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), TextUtils.join(",", Build.SUPPORTED_ABIS), null); // instructionSet null, // instructionSet Process.FIRST_ISOLATED_UID, Process.LAST_ISOLATED_UID); // All the work below is usually done by LoadedApk, but the zygote can't talk to // All the work below is usually done by LoadedApk, but the zygote can't talk to // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so Loading core/java/com/android/internal/os/ChildZygoteInit.java +38 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ */ package com.android.internal.os; package com.android.internal.os; import android.os.Process; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.system.OsConstants; import android.system.OsConstants; Loading Loading @@ -49,6 +50,22 @@ public class ChildZygoteInit { return null; return null; } } static int parseIntFromArg(String[] argv, String desiredArg) { int value = -1; for (String arg : argv) { if (arg.startsWith(desiredArg)) { String valueStr = arg.substring(arg.indexOf('=') + 1); try { value = Integer.parseInt(valueStr); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid int argument: " + valueStr, e); } } } return value; } /** /** * Starts a ZygoteServer and listens for requests * Starts a ZygoteServer and listens for requests * * Loading @@ -72,6 +89,27 @@ public class ChildZygoteInit { throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); } } int uidGidMin = parseIntFromArg(args, Zygote.CHILD_ZYGOTE_UID_RANGE_START); int uidGidMax = parseIntFromArg(args, Zygote.CHILD_ZYGOTE_UID_RANGE_END); if (uidGidMin == -1 || uidGidMax == -1) { throw new RuntimeException("Couldn't parse UID range start/end"); } if (uidGidMin > uidGidMax) { throw new RuntimeException("Passed in UID range is invalid, min > max."); } // Verify the UIDs are in the isolated UID range, as that's the only thing that we should // be forking right now if (!Process.isIsolated(uidGidMin) || !Process.isIsolated(uidGidMax)) { throw new RuntimeException("Passed in UID range does not map to isolated processes."); } /** * Install a seccomp filter that ensure this Zygote can only setuid()/setgid() * to the passed in range. */ Zygote.nativeInstallSeccompUidGidFilter(uidGidMin, uidGidMax); final Runnable caller; final Runnable caller; try { try { server.registerServerSocketAtAbstractName(socketName); server.registerServerSocketAtAbstractName(socketName); Loading core/java/com/android/internal/os/Zygote.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -104,6 +104,20 @@ public final class Zygote { */ */ public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list="; public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list="; /** * An extraArg passed when a zygote process is forking a child-zygote, specifying the * start of the UID range the children of the Zygote may setuid()/setgid() to. This * will be enforced with a seccomp filter. */ public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start="; /** * An extraArg passed when a zygote process is forking a child-zygote, specifying the * end of the UID range the children of the Zygote may setuid()/setgid() to. This * will be enforced with a seccomp filter. */ public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end="; private Zygote() {} private Zygote() {} /** Called for some security initialization before any fork. */ /** Called for some security initialization before any fork. */ Loading Loading @@ -221,6 +235,13 @@ public final class Zygote { */ */ native protected static void nativeAllowFileAcrossFork(String path); native protected static void nativeAllowFileAcrossFork(String path); /** * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range * @param uidGidMin The smallest allowed uid/gid * @param uidGidMax The largest allowed uid/gid */ native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax); /** /** * Zygote unmount storage space on initializing. * Zygote unmount storage space on initializing. * This method is called once. * This method is called once. Loading Loading
core/java/android/os/AppZygote.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -34,8 +34,15 @@ import com.android.internal.annotations.GuardedBy; public class AppZygote { public class AppZygote { private static final String LOG_TAG = "AppZygote"; private static final String LOG_TAG = "AppZygote"; // UID of the Zygote itself private final int mZygoteUid; private final int mZygoteUid; // First UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMin; // Last UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMax; private final Object mLock = new Object(); private final Object mLock = new Object(); /** /** Loading @@ -47,9 +54,11 @@ public class AppZygote { private final ApplicationInfo mAppInfo; private final ApplicationInfo mAppInfo; public AppZygote(ApplicationInfo appInfo, int zygoteUid) { public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax) { mAppInfo = appInfo; mAppInfo = appInfo; mZygoteUid = zygoteUid; mZygoteUid = zygoteUid; mZygoteUidGidMin = uidGidMin; mZygoteUidGidMax = uidGidMax; } } /** /** Loading Loading @@ -104,7 +113,9 @@ public class AppZygote { "app_zygote", // seInfo "app_zygote", // seInfo abi, // abi abi, // abi abi, // acceptedAbiList abi, // acceptedAbiList null); // instructionSet null, // instructionSet mZygoteUidGidMin, mZygoteUidGidMax); ZygoteProcess.waitForConnectionToZygote(mZygote.getPrimarySocketAddress()); ZygoteProcess.waitForConnectionToZygote(mZygote.getPrimarySocketAddress()); // preload application code in the zygote // preload application code in the zygote Loading
core/java/android/os/ZygoteProcess.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -809,6 +809,8 @@ public class ZygoteProcess { * may be different from <code>abi</code> in case the children * may be different from <code>abi</code> in case the children * spawned from this Zygote only communicate using ABI-safe methods. * spawned from this Zygote only communicate using ABI-safe methods. * @param instructionSet null-ok the instruction set to use. * @param instructionSet null-ok the instruction set to use. * @param uidRangeStart The first UID in the range the child zygote may setuid()/setgid() to * @param uidRangeEnd The last UID in the range the child zygote may setuid()/setgid() to */ */ public ChildZygoteProcess startChildZygote(final String processClass, public ChildZygoteProcess startChildZygote(final String processClass, final String niceName, final String niceName, Loading @@ -817,13 +819,17 @@ public class ZygoteProcess { String seInfo, String seInfo, String abi, String abi, String acceptedAbiList, String acceptedAbiList, String instructionSet) { String instructionSet, int uidRangeStart, int uidRangeEnd) { // Create an unguessable address in the global abstract namespace. // Create an unguessable address in the global abstract namespace. final LocalSocketAddress serverAddress = new LocalSocketAddress( final LocalSocketAddress serverAddress = new LocalSocketAddress( processClass + "/" + UUID.randomUUID().toString()); processClass + "/" + UUID.randomUUID().toString()); final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName(), final String[] extraArgs = {Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + serverAddress.getName(), Zygote.CHILD_ZYGOTE_ABI_LIST_ARG + acceptedAbiList}; Zygote.CHILD_ZYGOTE_ABI_LIST_ARG + acceptedAbiList, Zygote.CHILD_ZYGOTE_UID_RANGE_START + uidRangeStart, Zygote.CHILD_ZYGOTE_UID_RANGE_END + uidRangeEnd}; Process.ProcessStartResult result; Process.ProcessStartResult result; try { try { Loading
core/java/android/webkit/WebViewZygote.java +3 −1 Original line number Original line Diff line number Diff line Loading @@ -160,7 +160,9 @@ public class WebViewZygote { "webview_zygote", // seInfo "webview_zygote", // seInfo sPackage.applicationInfo.primaryCpuAbi, // abi sPackage.applicationInfo.primaryCpuAbi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), TextUtils.join(",", Build.SUPPORTED_ABIS), null); // instructionSet null, // instructionSet Process.FIRST_ISOLATED_UID, Process.LAST_ISOLATED_UID); // All the work below is usually done by LoadedApk, but the zygote can't talk to // All the work below is usually done by LoadedApk, but the zygote can't talk to // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so Loading
core/java/com/android/internal/os/ChildZygoteInit.java +38 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ */ package com.android.internal.os; package com.android.internal.os; import android.os.Process; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.system.OsConstants; import android.system.OsConstants; Loading Loading @@ -49,6 +50,22 @@ public class ChildZygoteInit { return null; return null; } } static int parseIntFromArg(String[] argv, String desiredArg) { int value = -1; for (String arg : argv) { if (arg.startsWith(desiredArg)) { String valueStr = arg.substring(arg.indexOf('=') + 1); try { value = Integer.parseInt(valueStr); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid int argument: " + valueStr, e); } } } return value; } /** /** * Starts a ZygoteServer and listens for requests * Starts a ZygoteServer and listens for requests * * Loading @@ -72,6 +89,27 @@ public class ChildZygoteInit { throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex); } } int uidGidMin = parseIntFromArg(args, Zygote.CHILD_ZYGOTE_UID_RANGE_START); int uidGidMax = parseIntFromArg(args, Zygote.CHILD_ZYGOTE_UID_RANGE_END); if (uidGidMin == -1 || uidGidMax == -1) { throw new RuntimeException("Couldn't parse UID range start/end"); } if (uidGidMin > uidGidMax) { throw new RuntimeException("Passed in UID range is invalid, min > max."); } // Verify the UIDs are in the isolated UID range, as that's the only thing that we should // be forking right now if (!Process.isIsolated(uidGidMin) || !Process.isIsolated(uidGidMax)) { throw new RuntimeException("Passed in UID range does not map to isolated processes."); } /** * Install a seccomp filter that ensure this Zygote can only setuid()/setgid() * to the passed in range. */ Zygote.nativeInstallSeccompUidGidFilter(uidGidMin, uidGidMax); final Runnable caller; final Runnable caller; try { try { server.registerServerSocketAtAbstractName(socketName); server.registerServerSocketAtAbstractName(socketName); Loading
core/java/com/android/internal/os/Zygote.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -104,6 +104,20 @@ public final class Zygote { */ */ public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list="; public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list="; /** * An extraArg passed when a zygote process is forking a child-zygote, specifying the * start of the UID range the children of the Zygote may setuid()/setgid() to. This * will be enforced with a seccomp filter. */ public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start="; /** * An extraArg passed when a zygote process is forking a child-zygote, specifying the * end of the UID range the children of the Zygote may setuid()/setgid() to. This * will be enforced with a seccomp filter. */ public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end="; private Zygote() {} private Zygote() {} /** Called for some security initialization before any fork. */ /** Called for some security initialization before any fork. */ Loading Loading @@ -221,6 +235,13 @@ public final class Zygote { */ */ native protected static void nativeAllowFileAcrossFork(String path); native protected static void nativeAllowFileAcrossFork(String path); /** * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range * @param uidGidMin The smallest allowed uid/gid * @param uidGidMax The largest allowed uid/gid */ native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax); /** /** * Zygote unmount storage space on initializing. * Zygote unmount storage space on initializing. * This method is called once. * This method is called once. Loading