Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1288662 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Prepare setresuid()/setresgid() seccomp filter in AppZygote."

parents 837f453c 86f08a51
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -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();


    /**
    /**
@@ -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;
    }
    }


    /**
    /**
@@ -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
+8 −2
Original line number Original line Diff line number Diff line
@@ -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,
@@ -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 {
+3 −1
Original line number Original line Diff line number Diff line
@@ -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
+38 −0
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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
     *
     *
@@ -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);
+21 −0
Original line number Original line Diff line number Diff line
@@ -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. */
@@ -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