/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.internal.os;

import android.os.Process;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.util.Log;

/**
 * ChildZygoteInit is shared by both the Application and WebView zygote to initialize
 * and run a (child) Zygote server.
 *
 * @hide
 */
public class ChildZygoteInit {
    private static final String TAG = "ChildZygoteInit";

    static String parseSocketNameFromArgs(String[] argv) {
        for (String arg : argv) {
            if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) {
                return arg.substring(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG.length());
            }
        }

        return null;
    }

    static String parseAbiListFromArgs(String[] argv) {
        for (String arg : argv) {
            if (arg.startsWith(Zygote.CHILD_ZYGOTE_ABI_LIST_ARG)) {
                return arg.substring(Zygote.CHILD_ZYGOTE_ABI_LIST_ARG.length());
            }
        }

        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
     *
     * @param server An instance of a ZygoteServer to listen on
     * @param args Passed in arguments for this ZygoteServer
     */
    static void runZygoteServer(ZygoteServer server, String[] args) {
        String socketName = parseSocketNameFromArgs(args);
        if (socketName == null) {
            throw new NullPointerException("No socketName specified");
        }

        String abiList = parseAbiListFromArgs(args);
        if (abiList == null) {
            throw new NullPointerException("No abiList specified");
        }

        try {
            Os.prctl(OsConstants.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
        } catch (ErrnoException 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 at least do not include system UIDs; we can't easily verify there
        // are just isolated UIDs in the range, because for the webview zygote, there is no
        // single range that captures all possible isolated UIDs.
        // TODO(b/123615476) narrow this down
        if (uidGidMin < Process.FIRST_APP_ZYGOTE_ISOLATED_UID) {
            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;
        try {
            server.registerServerSocketAtAbstractName(socketName);

            // Add the abstract socket to the FD whitelist so that the native zygote code
            // can properly detach it after forking.
            Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName);

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            caller = server.runSelectLoop(abiList);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fatal exception:", e);
            throw e;
        } finally {
            server.closeServerSocket();
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }
}
