Merge "Refactored ZygoteConnection.Arguments to ZygoteArguments."
am: 3a46c1b4ce
Change-Id: Id702f32a15ad134b6d694d0fc53e1721094f78dd
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 6e14558..382542a 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -16,13 +16,23 @@
package com.android.internal.os;
+import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
+
+import android.net.Credentials;
+import android.os.FactoryTest;
import android.os.IVold;
+import android.os.Process;
+import android.os.SystemProperties;
import android.os.Trace;
import android.system.ErrnoException;
import android.system.Os;
+import android.util.Log;
import dalvik.system.ZygoteHooks;
+import java.io.BufferedReader;
+import java.io.IOException;
+
/** @hide */
public final class Zygote {
/*
@@ -91,6 +101,9 @@
*/
public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
+ /** a prototype instance for a future List.toArray() */
+ protected static final int[][] INT_ARRAY_2D = new int[0][0];
+
private Zygote() {}
/** Called for some security initialization before any fork. */
@@ -231,6 +244,147 @@
private static native boolean nativeRemoveBlastulaTableEntry(int blastulaPID);
+ /**
+ * uid 1000 (Process.SYSTEM_UID) may specify any uid > 1000 in normal
+ * operation. It may also specify any gid and setgroups() list it chooses.
+ * In factory test mode, it may specify any UID.
+ *
+ * @param args non-null; zygote spawner arguments
+ * @param peer non-null; peer credentials
+ * @throws ZygoteSecurityException
+ */
+ protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
+ throws ZygoteSecurityException {
+
+ if (peer.getUid() == Process.SYSTEM_UID) {
+ /* In normal operation, SYSTEM_UID can only specify a restricted
+ * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
+ */
+ boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
+
+ if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
+ throw new ZygoteSecurityException(
+ "System UID may not launch process with UID < "
+ + Process.SYSTEM_UID);
+ }
+ }
+
+ // If not otherwise specified, uid and gid are inherited from peer
+ if (!args.mUidSpecified) {
+ args.mUid = peer.getUid();
+ args.mUidSpecified = true;
+ }
+ if (!args.mGidSpecified) {
+ args.mGid = peer.getGid();
+ args.mGidSpecified = true;
+ }
+ }
+
+ /**
+ * Applies debugger system properties to the zygote arguments.
+ *
+ * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
+ * the debugger state is specified via the "--enable-jdwp" flag
+ * in the spawn request.
+ *
+ * @param args non-null; zygote spawner args
+ */
+ protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
+ if (RoSystemProperties.DEBUGGABLE) {
+ args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
+ }
+ }
+
+ /**
+ * Applies zygote security policy.
+ * Based on the credentials of the process issuing a zygote command:
+ * <ol>
+ * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
+ * wrapper command.
+ * <li> Any other uid may not specify any invoke-with argument.
+ * </ul>
+ *
+ * @param args non-null; zygote spawner arguments
+ * @param peer non-null; peer credentials
+ * @throws ZygoteSecurityException
+ */
+ protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
+ throws ZygoteSecurityException {
+ int peerUid = peer.getUid();
+
+ if (args.mInvokeWith != null && peerUid != 0
+ && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
+ throw new ZygoteSecurityException("Peer is permitted to specify an"
+ + "explicit invoke-with wrapper command only for debuggable"
+ + "applications.");
+ }
+ }
+
+ /**
+ * Applies invoke-with system properties to the zygote arguments.
+ *
+ * @param args non-null; zygote args
+ */
+ protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
+ if (args.mInvokeWith == null && args.mNiceName != null) {
+ String property = "wrap." + args.mNiceName;
+ args.mInvokeWith = SystemProperties.get(property);
+ if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
+ args.mInvokeWith = null;
+ }
+ }
+ }
+
+ /**
+ * Reads an argument list from the provided socket
+ * @return Argument list or null if EOF is reached
+ * @throws IOException passed straight through
+ */
+ static String[] readArgumentList(BufferedReader socketReader) throws IOException {
+
+ /**
+ * See android.os.Process.zygoteSendArgsAndGetPid()
+ * Presently the wire format to the zygote process is:
+ * a) a count of arguments (argc, in essence)
+ * b) a number of newline-separated argument strings equal to count
+ *
+ * After the zygote process reads these it will write the pid of
+ * the child or -1 on failure.
+ */
+
+ int argc;
+
+ try {
+ String argc_string = socketReader.readLine();
+
+ if (argc_string == null) {
+ // EOF reached.
+ return null;
+ }
+ argc = Integer.parseInt(argc_string);
+
+ } catch (NumberFormatException ex) {
+ Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
+ throw new IOException("Invalid wire format");
+ }
+
+ // See bug 1092107: large argc can be used for a DOS attack
+ if (argc > MAX_ZYGOTE_ARGC) {
+ throw new IOException("Max arg count exceeded");
+ }
+
+ String[] args = new String[argc];
+ for (int arg_index = 0; arg_index < argc; arg_index++) {
+ args[arg_index] = socketReader.readLine();
+ if (args[arg_index] == null) {
+ // We got an unexpected EOF.
+ throw new IOException("Truncated request");
+ }
+ }
+
+ return args;
+ }
+
private static void callPostForkSystemServerHooks() {
// SystemServer specific post fork hooks run before child post fork hooks.
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
new file mode 100644
index 0000000..2e869ae
--- /dev/null
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2007 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 java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Handles argument parsing for args related to the zygote spawner.
+ *
+ * Current recognized args:
+ * <ul>
+ * <li> --setuid=<i>uid of child process, defaults to 0</i>
+ * <li> --setgid=<i>gid of child process, defaults to 0</i>
+ * <li> --setgroups=<i>comma-separated list of supplimentary gid's</i>
+ * <li> --capabilities=<i>a pair of comma-separated integer strings
+ * indicating Linux capabilities(2) set for child. The first string represents the
+ * <code>permitted</code> set, and the second the
+ * <code>effective</code> set. Precede each with 0 or
+ * 0x for octal or hexidecimal value. If unspecified, both default to 0. This parameter is only
+ * applied if the uid of the new process will be non-0. </i>
+ * <li> --rlimit=r,c,m<i>tuple of values for setrlimit() call.
+ * <code>r</code> is the resource, <code>c</code> and <code>m</code>
+ * are the settings for current and max value.</i>
+ * <li> --instruction-set=<i>instruction-set-string</i> which instruction set to use/emulate.
+ * <li> --nice-name=<i>nice name to appear in ps</i>
+ * <li> --runtime-args indicates that the remaining arg list should
+ * be handed off to com.android.internal.os.RuntimeInit, rather than processed directly. Android
+ * runtime startup (eg, Binder initialization) is also eschewed.
+ * <li> [--] <args for RuntimeInit >
+ * </ul>
+ */
+class ZygoteArguments {
+
+ /**
+ * from --setuid
+ */
+ int mUid = 0;
+ boolean mUidSpecified;
+
+ /**
+ * from --setgid
+ */
+ int mGid = 0;
+ boolean mGidSpecified;
+
+ /**
+ * from --setgroups
+ */
+ int[] mGids;
+
+ /**
+ * From --runtime-flags.
+ */
+ int mRuntimeFlags;
+
+ /**
+ * From --mount-external
+ */
+ int mMountExternal = Zygote.MOUNT_EXTERNAL_NONE;
+
+ /**
+ * from --target-sdk-version.
+ */
+ int mTargetSdkVersion;
+ boolean mTargetSdkVersionSpecified;
+
+ /**
+ * from --nice-name
+ */
+ String mNiceName;
+
+ /**
+ * from --capabilities
+ */
+ boolean mCapabilitiesSpecified;
+ long mPermittedCapabilities;
+ long mEffectiveCapabilities;
+
+ /**
+ * from --seinfo
+ */
+ boolean mSeInfoSpecified;
+ String mSeInfo;
+
+ /**
+ * from all --rlimit=r,c,m
+ */
+ ArrayList<int[]> mRLimits;
+
+ /**
+ * from --invoke-with
+ */
+ String mInvokeWith;
+
+ /**
+ * Any args after and including the first non-option arg (or after a '--')
+ */
+ String[] mRemainingArgs;
+
+ /**
+ * Whether the current arguments constitute an ABI list query.
+ */
+ boolean mAbiListQuery;
+
+ /**
+ * The instruction set to use, or null when not important.
+ */
+ String mInstructionSet;
+
+ /**
+ * The app data directory. May be null, e.g., for the system server. Note that this might not be
+ * reliable in the case of process-sharing apps.
+ */
+ String mAppDataDir;
+
+ /**
+ * The APK path of the package to preload, when using --preload-package.
+ */
+ String mPreloadPackage;
+
+ /**
+ * The native library path of the package to preload, when using --preload-package.
+ */
+ String mPreloadPackageLibs;
+
+ /**
+ * The filename of the native library to preload, when using --preload-package.
+ */
+ String mPreloadPackageLibFileName;
+
+ /**
+ * The cache key under which to enter the preloaded package into the classloader cache, when
+ * using --preload-package.
+ */
+ String mPreloadPackageCacheKey;
+
+ /**
+ * Whether this is a request to start preloading the default resources and classes. This
+ * argument only makes sense when the zygote is in lazy preload mode (i.e, when it's started
+ * with --enable-lazy-preload).
+ */
+ boolean mPreloadDefault;
+
+ /**
+ * Whether this is a request to start a zygote process as a child of this zygote. Set with
+ * --start-child-zygote. The remaining arguments must include the CHILD_ZYGOTE_SOCKET_NAME_ARG
+ * flag to indicate the abstract socket name that should be used for communication.
+ */
+ boolean mStartChildZygote;
+
+ /**
+ * Whether the current arguments constitute a request for the zygote's PID.
+ */
+ boolean mPidQuery;
+
+ /**
+ * Exemptions from API blacklisting. These are sent to the pre-forked zygote at boot time, or
+ * when they change, via --set-api-blacklist-exemptions.
+ */
+ String[] mApiBlacklistExemptions;
+
+ /**
+ * Sampling rate for logging hidden API accesses to the event log. This is sent to the
+ * pre-forked zygote at boot time, or when it changes, via --hidden-api-log-sampling-rate.
+ */
+ int mHiddenApiAccessLogSampleRate = -1;
+
+ /**
+ * Constructs instance and parses args
+ *
+ * @param args zygote command-line args
+ */
+ ZygoteArguments(String[] args) throws IllegalArgumentException {
+ parseArgs(args);
+ }
+
+ /**
+ * Parses the commandline arguments intended for the Zygote spawner (such as "--setuid=" and
+ * "--setgid=") and creates an array containing the remaining args.
+ *
+ * Per security review bug #1112214, duplicate args are disallowed in critical cases to make
+ * injection harder.
+ */
+ private void parseArgs(String[] args)
+ throws IllegalArgumentException {
+ int curArg = 0;
+
+ boolean seenRuntimeArgs = false;
+
+ boolean expectRuntimeArgs = true;
+ for ( /* curArg */ ; curArg < args.length; curArg++) {
+ String arg = args[curArg];
+
+ if (arg.equals("--")) {
+ curArg++;
+ break;
+ } else if (arg.startsWith("--setuid=")) {
+ if (mUidSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ mUidSpecified = true;
+ mUid = Integer.parseInt(
+ arg.substring(arg.indexOf('=') + 1));
+ } else if (arg.startsWith("--setgid=")) {
+ if (mGidSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ mGidSpecified = true;
+ mGid = Integer.parseInt(
+ arg.substring(arg.indexOf('=') + 1));
+ } else if (arg.startsWith("--target-sdk-version=")) {
+ if (mTargetSdkVersionSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate target-sdk-version specified");
+ }
+ mTargetSdkVersionSpecified = true;
+ mTargetSdkVersion = Integer.parseInt(
+ arg.substring(arg.indexOf('=') + 1));
+ } else if (arg.equals("--runtime-args")) {
+ seenRuntimeArgs = true;
+ } else if (arg.startsWith("--runtime-flags=")) {
+ mRuntimeFlags = Integer.parseInt(
+ arg.substring(arg.indexOf('=') + 1));
+ } else if (arg.startsWith("--seinfo=")) {
+ if (mSeInfoSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ mSeInfoSpecified = true;
+ mSeInfo = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.startsWith("--capabilities=")) {
+ if (mCapabilitiesSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ mCapabilitiesSpecified = true;
+ String capString = arg.substring(arg.indexOf('=') + 1);
+
+ String[] capStrings = capString.split(",", 2);
+
+ if (capStrings.length == 1) {
+ mEffectiveCapabilities = Long.decode(capStrings[0]);
+ mPermittedCapabilities = mEffectiveCapabilities;
+ } else {
+ mPermittedCapabilities = Long.decode(capStrings[0]);
+ mEffectiveCapabilities = Long.decode(capStrings[1]);
+ }
+ } else if (arg.startsWith("--rlimit=")) {
+ // Duplicate --rlimit arguments are specifically allowed.
+ String[] limitStrings = arg.substring(arg.indexOf('=') + 1).split(",");
+
+ if (limitStrings.length != 3) {
+ throw new IllegalArgumentException(
+ "--rlimit= should have 3 comma-delimited ints");
+ }
+ int[] rlimitTuple = new int[limitStrings.length];
+
+ for (int i = 0; i < limitStrings.length; i++) {
+ rlimitTuple[i] = Integer.parseInt(limitStrings[i]);
+ }
+
+ if (mRLimits == null) {
+ mRLimits = new ArrayList();
+ }
+
+ mRLimits.add(rlimitTuple);
+ } else if (arg.startsWith("--setgroups=")) {
+ if (mGids != null) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+
+ String[] params = arg.substring(arg.indexOf('=') + 1).split(",");
+
+ mGids = new int[params.length];
+
+ for (int i = params.length - 1; i >= 0; i--) {
+ mGids[i] = Integer.parseInt(params[i]);
+ }
+ } else if (arg.equals("--invoke-with")) {
+ if (mInvokeWith != null) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ try {
+ mInvokeWith = args[++curArg];
+ } catch (IndexOutOfBoundsException ex) {
+ throw new IllegalArgumentException(
+ "--invoke-with requires argument");
+ }
+ } else if (arg.startsWith("--nice-name=")) {
+ if (mNiceName != null) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ mNiceName = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.equals("--mount-external-default")) {
+ mMountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
+ } else if (arg.equals("--mount-external-read")) {
+ mMountExternal = Zygote.MOUNT_EXTERNAL_READ;
+ } else if (arg.equals("--mount-external-write")) {
+ mMountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
+ } else if (arg.equals("--query-abi-list")) {
+ mAbiListQuery = true;
+ } else if (arg.equals("--get-pid")) {
+ mPidQuery = true;
+ } else if (arg.startsWith("--instruction-set=")) {
+ mInstructionSet = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.startsWith("--app-data-dir=")) {
+ mAppDataDir = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.equals("--preload-package")) {
+ mPreloadPackage = args[++curArg];
+ mPreloadPackageLibs = args[++curArg];
+ mPreloadPackageLibFileName = args[++curArg];
+ mPreloadPackageCacheKey = args[++curArg];
+ } else if (arg.equals("--preload-default")) {
+ mPreloadDefault = true;
+ expectRuntimeArgs = false;
+ } else if (arg.equals("--start-child-zygote")) {
+ mStartChildZygote = true;
+ } else if (arg.equals("--set-api-blacklist-exemptions")) {
+ // consume all remaining args; this is a stand-alone command, never included
+ // with the regular fork command.
+ mApiBlacklistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
+ curArg = args.length;
+ expectRuntimeArgs = false;
+ } else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
+ String rateStr = arg.substring(arg.indexOf('=') + 1);
+ try {
+ mHiddenApiAccessLogSampleRate = Integer.parseInt(rateStr);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException(
+ "Invalid log sampling rate: " + rateStr, nfe);
+ }
+ expectRuntimeArgs = false;
+ } else {
+ break;
+ }
+ }
+
+ if (mAbiListQuery || mPidQuery) {
+ if (args.length - curArg > 0) {
+ throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
+ }
+ } else if (mPreloadPackage != null) {
+ if (args.length - curArg > 0) {
+ throw new IllegalArgumentException(
+ "Unexpected arguments after --preload-package.");
+ }
+ } else if (expectRuntimeArgs) {
+ if (!seenRuntimeArgs) {
+ throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
+ }
+
+ mRemainingArgs = new String[args.length - curArg];
+ System.arraycopy(args, curArg, mRemainingArgs, 0, mRemainingArgs.length);
+ }
+
+ if (mStartChildZygote) {
+ boolean seenChildSocketArg = false;
+ for (String arg : mRemainingArgs) {
+ if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) {
+ seenChildSocketArg = true;
+ break;
+ }
+ }
+ if (!seenChildSocketArg) {
+ throw new IllegalArgumentException("--start-child-zygote specified "
+ + "without " + Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG);
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 12761b9..43f114f 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -22,34 +22,31 @@
import static android.system.OsConstants.STDERR_FILENO;
import static android.system.OsConstants.STDIN_FILENO;
import static android.system.OsConstants.STDOUT_FILENO;
+
import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS;
-import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
import android.net.Credentials;
import android.net.LocalSocket;
-import android.os.FactoryTest;
import android.os.Process;
-import android.os.SystemProperties;
import android.os.Trace;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructPollfd;
import android.util.Log;
+
import dalvik.system.VMRuntime;
+
+import libcore.io.IoUtils;
+
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
-import java.io.EOFException;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import libcore.io.IoUtils;
/**
* A connection that can make spawn requests.
@@ -57,9 +54,6 @@
class ZygoteConnection {
private static final String TAG = "Zygote";
- /** a prototype instance for a future List.toArray() */
- private static final int[][] intArray2d = new int[0][0];
-
/**
* The command socket.
*
@@ -108,7 +102,7 @@
*
* @return null-ok; file descriptor
*/
- FileDescriptor getFileDesciptor() {
+ FileDescriptor getFileDescriptor() {
return mSocket.getFileDescriptor();
}
@@ -122,11 +116,13 @@
*/
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
- Arguments parsedArgs = null;
+ ZygoteArguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
- args = readArgumentList();
+ args = Zygote.readArgumentList(mSocketReader);
+
+ // TODO (chriswailes): Remove this and add an assert.
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
@@ -143,60 +139,60 @@
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
- parsedArgs = new Arguments(args);
+ parsedArgs = new ZygoteArguments(args);
- if (parsedArgs.abiListQuery) {
+ if (parsedArgs.mAbiListQuery) {
handleAbiListQuery();
return null;
}
- if (parsedArgs.pidQuery) {
+ if (parsedArgs.mPidQuery) {
handlePidQuery();
return null;
}
- if (parsedArgs.preloadDefault) {
+ if (parsedArgs.mPreloadDefault) {
handlePreload();
return null;
}
- if (parsedArgs.preloadPackage != null) {
- handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
- parsedArgs.preloadPackageLibFileName, parsedArgs.preloadPackageCacheKey);
+ if (parsedArgs.mPreloadPackage != null) {
+ handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs,
+ parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey);
return null;
}
- if (parsedArgs.apiBlacklistExemptions != null) {
- handleApiBlacklistExemptions(parsedArgs.apiBlacklistExemptions);
+ if (parsedArgs.mApiBlacklistExemptions != null) {
+ handleApiBlacklistExemptions(parsedArgs.mApiBlacklistExemptions);
return null;
}
- if (parsedArgs.hiddenApiAccessLogSampleRate != -1) {
- handleHiddenApiAccessLogSampleRate(parsedArgs.hiddenApiAccessLogSampleRate);
+ if (parsedArgs.mHiddenApiAccessLogSampleRate != -1) {
+ handleHiddenApiAccessLogSampleRate(parsedArgs.mHiddenApiAccessLogSampleRate);
return null;
}
- if (parsedArgs.permittedCapabilities != 0 || parsedArgs.effectiveCapabilities != 0) {
- throw new ZygoteSecurityException("Client may not specify capabilities: " +
- "permitted=0x" + Long.toHexString(parsedArgs.permittedCapabilities) +
- ", effective=0x" + Long.toHexString(parsedArgs.effectiveCapabilities));
+ if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {
+ throw new ZygoteSecurityException("Client may not specify capabilities: "
+ + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities)
+ + ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities));
}
- applyUidSecurityPolicy(parsedArgs, peer);
- applyInvokeWithSecurityPolicy(parsedArgs, peer);
+ Zygote.applyUidSecurityPolicy(parsedArgs, peer);
+ Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer);
- applyDebuggerSystemProperty(parsedArgs);
- applyInvokeWithSystemProperty(parsedArgs);
+ Zygote.applyDebuggerSystemProperty(parsedArgs);
+ Zygote.applyInvokeWithSystemProperty(parsedArgs);
int[][] rlimits = null;
- if (parsedArgs.rlimits != null) {
- rlimits = parsedArgs.rlimits.toArray(intArray2d);
+ if (parsedArgs.mRLimits != null) {
+ rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
}
int[] fdsToIgnore = null;
- if (parsedArgs.invokeWith != null) {
+ if (parsedArgs.mInvokeWith != null) {
try {
FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
childPipeFd = pipeFds[1];
@@ -236,10 +232,10 @@
fd = null;
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
- parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
- parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
- parsedArgs.instructionSet, parsedArgs.appDataDir);
+ pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
+ parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
+ parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
+ parsedArgs.mInstructionSet, parsedArgs.mAppDataDir);
try {
if (pid == 0) {
@@ -251,7 +247,7 @@
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
- parsedArgs.startChildZygote);
+ parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
@@ -358,503 +354,6 @@
}
/**
- * Handles argument parsing for args related to the zygote spawner.
- *
- * Current recognized args:
- * <ul>
- * <li> --setuid=<i>uid of child process, defaults to 0</i>
- * <li> --setgid=<i>gid of child process, defaults to 0</i>
- * <li> --setgroups=<i>comma-separated list of supplimentary gid's</i>
- * <li> --capabilities=<i>a pair of comma-separated integer strings
- * indicating Linux capabilities(2) set for child. The first string
- * represents the <code>permitted</code> set, and the second the
- * <code>effective</code> set. Precede each with 0 or
- * 0x for octal or hexidecimal value. If unspecified, both default to 0.
- * This parameter is only applied if the uid of the new process will
- * be non-0. </i>
- * <li> --rlimit=r,c,m<i>tuple of values for setrlimit() call.
- * <code>r</code> is the resource, <code>c</code> and <code>m</code>
- * are the settings for current and max value.</i>
- * <li> --instruction-set=<i>instruction-set-string</i> which instruction set to use/emulate.
- * <li> --nice-name=<i>nice name to appear in ps</i>
- * <li> --runtime-args indicates that the remaining arg list should
- * be handed off to com.android.internal.os.RuntimeInit, rather than
- * processed directly.
- * Android runtime startup (eg, Binder initialization) is also eschewed.
- * <li> [--] <args for RuntimeInit >
- * </ul>
- */
- static class Arguments {
- /** from --setuid */
- int uid = 0;
- boolean uidSpecified;
-
- /** from --setgid */
- int gid = 0;
- boolean gidSpecified;
-
- /** from --setgroups */
- int[] gids;
-
- /**
- * From --runtime-flags.
- */
- int runtimeFlags;
-
- /** From --mount-external */
- int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
-
- /** from --target-sdk-version. */
- int targetSdkVersion;
- boolean targetSdkVersionSpecified;
-
- /** from --nice-name */
- String niceName;
-
- /** from --capabilities */
- boolean capabilitiesSpecified;
- long permittedCapabilities;
- long effectiveCapabilities;
-
- /** from --seinfo */
- boolean seInfoSpecified;
- String seInfo;
-
- /** from all --rlimit=r,c,m */
- ArrayList<int[]> rlimits;
-
- /** from --invoke-with */
- String invokeWith;
-
- /**
- * Any args after and including the first non-option arg
- * (or after a '--')
- */
- String remainingArgs[];
-
- /**
- * Whether the current arguments constitute an ABI list query.
- */
- boolean abiListQuery;
-
- /**
- * The instruction set to use, or null when not important.
- */
- String instructionSet;
-
- /**
- * The app data directory. May be null, e.g., for the system server. Note that this might
- * not be reliable in the case of process-sharing apps.
- */
- String appDataDir;
-
- /**
- * The APK path of the package to preload, when using --preload-package.
- */
- String preloadPackage;
-
- /**
- * The native library path of the package to preload, when using --preload-package.
- */
- String preloadPackageLibs;
-
- /**
- * The filename of the native library to preload, when using --preload-package.
- */
- String preloadPackageLibFileName;
-
- /**
- * The cache key under which to enter the preloaded package into the classloader cache,
- * when using --preload-package.
- */
- String preloadPackageCacheKey;
-
- /**
- * Whether this is a request to start preloading the default resources and classes.
- * This argument only makes sense when the zygote is in lazy preload mode (i.e, when
- * it's started with --enable-lazy-preload).
- */
- boolean preloadDefault;
-
- /**
- * Whether this is a request to start a zygote process as a child of this zygote.
- * Set with --start-child-zygote. The remaining arguments must include the
- * CHILD_ZYGOTE_SOCKET_NAME_ARG flag to indicate the abstract socket name that
- * should be used for communication.
- */
- boolean startChildZygote;
-
- /**
- * Whether the current arguments constitute a request for the zygote's PID.
- */
- boolean pidQuery;
-
- /**
- * Exemptions from API blacklisting. These are sent to the pre-forked zygote at boot time,
- * or when they change, via --set-api-blacklist-exemptions.
- */
- String[] apiBlacklistExemptions;
-
- /**
- * Sampling rate for logging hidden API accesses to the event log. This is sent to the
- * pre-forked zygote at boot time, or when it changes, via --hidden-api-log-sampling-rate.
- */
- int hiddenApiAccessLogSampleRate = -1;
-
- /**
- * Constructs instance and parses args
- * @param args zygote command-line args
- * @throws IllegalArgumentException
- */
- Arguments(String args[]) throws IllegalArgumentException {
- parseArgs(args);
- }
-
- /**
- * Parses the commandline arguments intended for the Zygote spawner
- * (such as "--setuid=" and "--setgid=") and creates an array
- * containing the remaining args.
- *
- * Per security review bug #1112214, duplicate args are disallowed in
- * critical cases to make injection harder.
- */
- private void parseArgs(String args[])
- throws IllegalArgumentException {
- int curArg = 0;
-
- boolean seenRuntimeArgs = false;
-
- boolean expectRuntimeArgs = true;
- for ( /* curArg */ ; curArg < args.length; curArg++) {
- String arg = args[curArg];
-
- if (arg.equals("--")) {
- curArg++;
- break;
- } else if (arg.startsWith("--setuid=")) {
- if (uidSpecified) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- uidSpecified = true;
- uid = Integer.parseInt(
- arg.substring(arg.indexOf('=') + 1));
- } else if (arg.startsWith("--setgid=")) {
- if (gidSpecified) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- gidSpecified = true;
- gid = Integer.parseInt(
- arg.substring(arg.indexOf('=') + 1));
- } else if (arg.startsWith("--target-sdk-version=")) {
- if (targetSdkVersionSpecified) {
- throw new IllegalArgumentException(
- "Duplicate target-sdk-version specified");
- }
- targetSdkVersionSpecified = true;
- targetSdkVersion = Integer.parseInt(
- arg.substring(arg.indexOf('=') + 1));
- } else if (arg.equals("--runtime-args")) {
- seenRuntimeArgs = true;
- } else if (arg.startsWith("--runtime-flags=")) {
- runtimeFlags = Integer.parseInt(
- arg.substring(arg.indexOf('=') + 1));
- } else if (arg.startsWith("--seinfo=")) {
- if (seInfoSpecified) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- seInfoSpecified = true;
- seInfo = arg.substring(arg.indexOf('=') + 1);
- } else if (arg.startsWith("--capabilities=")) {
- if (capabilitiesSpecified) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- capabilitiesSpecified = true;
- String capString = arg.substring(arg.indexOf('=')+1);
-
- String[] capStrings = capString.split(",", 2);
-
- if (capStrings.length == 1) {
- effectiveCapabilities = Long.decode(capStrings[0]);
- permittedCapabilities = effectiveCapabilities;
- } else {
- permittedCapabilities = Long.decode(capStrings[0]);
- effectiveCapabilities = Long.decode(capStrings[1]);
- }
- } else if (arg.startsWith("--rlimit=")) {
- // Duplicate --rlimit arguments are specifically allowed.
- String[] limitStrings
- = arg.substring(arg.indexOf('=')+1).split(",");
-
- if (limitStrings.length != 3) {
- throw new IllegalArgumentException(
- "--rlimit= should have 3 comma-delimited ints");
- }
- int[] rlimitTuple = new int[limitStrings.length];
-
- for(int i=0; i < limitStrings.length; i++) {
- rlimitTuple[i] = Integer.parseInt(limitStrings[i]);
- }
-
- if (rlimits == null) {
- rlimits = new ArrayList();
- }
-
- rlimits.add(rlimitTuple);
- } else if (arg.startsWith("--setgroups=")) {
- if (gids != null) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
-
- String[] params
- = arg.substring(arg.indexOf('=') + 1).split(",");
-
- gids = new int[params.length];
-
- for (int i = params.length - 1; i >= 0 ; i--) {
- gids[i] = Integer.parseInt(params[i]);
- }
- } else if (arg.equals("--invoke-with")) {
- if (invokeWith != null) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- try {
- invokeWith = args[++curArg];
- } catch (IndexOutOfBoundsException ex) {
- throw new IllegalArgumentException(
- "--invoke-with requires argument");
- }
- } else if (arg.startsWith("--nice-name=")) {
- if (niceName != null) {
- throw new IllegalArgumentException(
- "Duplicate arg specified");
- }
- niceName = arg.substring(arg.indexOf('=') + 1);
- } else if (arg.equals("--mount-external-default")) {
- mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
- } else if (arg.equals("--mount-external-read")) {
- mountExternal = Zygote.MOUNT_EXTERNAL_READ;
- } else if (arg.equals("--mount-external-write")) {
- mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
- } else if (arg.equals("--query-abi-list")) {
- abiListQuery = true;
- } else if (arg.equals("--get-pid")) {
- pidQuery = true;
- } else if (arg.startsWith("--instruction-set=")) {
- instructionSet = arg.substring(arg.indexOf('=') + 1);
- } else if (arg.startsWith("--app-data-dir=")) {
- appDataDir = arg.substring(arg.indexOf('=') + 1);
- } else if (arg.equals("--preload-package")) {
- preloadPackage = args[++curArg];
- preloadPackageLibs = args[++curArg];
- preloadPackageLibFileName = args[++curArg];
- preloadPackageCacheKey = args[++curArg];
- } else if (arg.equals("--preload-default")) {
- preloadDefault = true;
- expectRuntimeArgs = false;
- } else if (arg.equals("--start-child-zygote")) {
- startChildZygote = true;
- } else if (arg.equals("--set-api-blacklist-exemptions")) {
- // consume all remaining args; this is a stand-alone command, never included
- // with the regular fork command.
- apiBlacklistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
- curArg = args.length;
- expectRuntimeArgs = false;
- } else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
- String rateStr = arg.substring(arg.indexOf('=') + 1);
- try {
- hiddenApiAccessLogSampleRate = Integer.parseInt(rateStr);
- } catch (NumberFormatException nfe) {
- throw new IllegalArgumentException(
- "Invalid log sampling rate: " + rateStr, nfe);
- }
- expectRuntimeArgs = false;
- } else {
- break;
- }
- }
-
- if (abiListQuery || pidQuery) {
- if (args.length - curArg > 0) {
- throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
- }
- } else if (preloadPackage != null) {
- if (args.length - curArg > 0) {
- throw new IllegalArgumentException(
- "Unexpected arguments after --preload-package.");
- }
- } else if (expectRuntimeArgs) {
- if (!seenRuntimeArgs) {
- throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
- }
-
- remainingArgs = new String[args.length - curArg];
- System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length);
- }
-
- if (startChildZygote) {
- boolean seenChildSocketArg = false;
- for (String arg : remainingArgs) {
- if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) {
- seenChildSocketArg = true;
- break;
- }
- }
- if (!seenChildSocketArg) {
- throw new IllegalArgumentException("--start-child-zygote specified " +
- "without " + Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG);
- }
- }
- }
- }
-
- /**
- * Reads an argument list from the command socket/
- * @return Argument list or null if EOF is reached
- * @throws IOException passed straight through
- */
- private String[] readArgumentList()
- throws IOException {
-
- /**
- * See android.os.Process.zygoteSendArgsAndGetPid()
- * Presently the wire format to the zygote process is:
- * a) a count of arguments (argc, in essence)
- * b) a number of newline-separated argument strings equal to count
- *
- * After the zygote process reads these it will write the pid of
- * the child or -1 on failure.
- */
-
- int argc;
-
- try {
- String s = mSocketReader.readLine();
-
- if (s == null) {
- // EOF reached.
- return null;
- }
- argc = Integer.parseInt(s);
- } catch (NumberFormatException ex) {
- Log.e(TAG, "invalid Zygote wire format: non-int at argc");
- throw new IOException("invalid wire format");
- }
-
- // See bug 1092107: large argc can be used for a DOS attack
- if (argc > MAX_ZYGOTE_ARGC) {
- throw new IOException("max arg count exceeded");
- }
-
- String[] result = new String[argc];
- for (int i = 0; i < argc; i++) {
- result[i] = mSocketReader.readLine();
- if (result[i] == null) {
- // We got an unexpected EOF.
- throw new IOException("truncated request");
- }
- }
-
- return result;
- }
-
- /**
- * uid 1000 (Process.SYSTEM_UID) may specify any uid > 1000 in normal
- * operation. It may also specify any gid and setgroups() list it chooses.
- * In factory test mode, it may specify any UID.
- *
- * @param args non-null; zygote spawner arguments
- * @param peer non-null; peer credentials
- * @throws ZygoteSecurityException
- */
- private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
- throws ZygoteSecurityException {
-
- if (peer.getUid() == Process.SYSTEM_UID) {
- /* In normal operation, SYSTEM_UID can only specify a restricted
- * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
- */
- boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
-
- if (uidRestricted && args.uidSpecified && (args.uid < Process.SYSTEM_UID)) {
- throw new ZygoteSecurityException(
- "System UID may not launch process with UID < "
- + Process.SYSTEM_UID);
- }
- }
-
- // If not otherwise specified, uid and gid are inherited from peer
- if (!args.uidSpecified) {
- args.uid = peer.getUid();
- args.uidSpecified = true;
- }
- if (!args.gidSpecified) {
- args.gid = peer.getGid();
- args.gidSpecified = true;
- }
- }
-
- /**
- * Applies debugger system properties to the zygote arguments.
- *
- * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
- * the debugger state is specified via the "--enable-jdwp" flag
- * in the spawn request.
- *
- * @param args non-null; zygote spawner args
- */
- public static void applyDebuggerSystemProperty(Arguments args) {
- if (RoSystemProperties.DEBUGGABLE) {
- args.runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
- }
- }
-
- /**
- * Applies zygote security policy.
- * Based on the credentials of the process issuing a zygote command:
- * <ol>
- * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
- * wrapper command.
- * <li> Any other uid may not specify any invoke-with argument.
- * </ul>
- *
- * @param args non-null; zygote spawner arguments
- * @param peer non-null; peer credentials
- * @throws ZygoteSecurityException
- */
- private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer)
- throws ZygoteSecurityException {
- int peerUid = peer.getUid();
-
- if (args.invokeWith != null && peerUid != 0 &&
- (args.runtimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
- throw new ZygoteSecurityException("Peer is permitted to specify an"
- + "explicit invoke-with wrapper command only for debuggable"
- + "applications.");
- }
- }
-
- /**
- * Applies invoke-with system properties to the zygote arguments.
- *
- * @param args non-null; zygote args
- */
- public static void applyInvokeWithSystemProperty(Arguments args) {
- if (args.invokeWith == null && args.niceName != null) {
- String property = "wrap." + args.niceName;
- args.invokeWith = SystemProperties.get(property);
- if (args.invokeWith != null && args.invokeWith.length() == 0) {
- args.invokeWith = null;
- }
- }
- }
-
- /**
* Handles post-fork setup of child proc, closing sockets as appropriate,
* reopen stdio as appropriate, and ultimately throwing MethodAndArgsCaller
* if successful or returning if failed.
@@ -864,7 +363,7 @@
* @param pipeFd null-ok; pipe for communication back to Zygote.
* @param isZygote whether this new child process is itself a new Zygote.
*/
- private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
+ private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
/**
* By the time we get here, the native code has closed the two actual Zygote
@@ -887,27 +386,27 @@
}
}
- if (parsedArgs.niceName != null) {
- Process.setArgV0(parsedArgs.niceName);
+ if (parsedArgs.mNiceName != null) {
+ Process.setArgV0(parsedArgs.mNiceName);
}
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- if (parsedArgs.invokeWith != null) {
- WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, parsedArgs.targetSdkVersion,
+ if (parsedArgs.mInvokeWith != null) {
+ WrapperInit.execApplication(parsedArgs.mInvokeWith,
+ parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
- pipeFd, parsedArgs.remainingArgs);
+ pipeFd, parsedArgs.mRemainingArgs);
// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
- return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
- null /* classLoader */);
+ return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
+ parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
- return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
- parsedArgs.remainingArgs, null /* classLoader */);
+ return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
+ parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 37d0f3f..2f00c07 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -73,8 +73,7 @@
* Pre-initializes some classes, and then waits for commands on a UNIX domain socket. Based on these
* commands, forks off child processes that inherit the initial state of the VM.
*
- * Please see {@link ZygoteConnection.Arguments} for documentation on the
- * client protocol.
+ * Please see {@link ZygoteArguments} for documentation on the client protocol.
*
* @hide
*/
@@ -434,12 +433,12 @@
/**
* Finish remaining work for the newly forked system server process.
*/
- private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
+ private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
- if (parsedArgs.niceName != null) {
- Process.setArgV0(parsedArgs.niceName);
+ if (parsedArgs.mNiceName != null) {
+ Process.setArgV0(parsedArgs.mNiceName);
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
@@ -458,8 +457,8 @@
}
}
- if (parsedArgs.invokeWith != null) {
- String[] args = parsedArgs.remainingArgs;
+ if (parsedArgs.mInvokeWith != null) {
+ String[] args = parsedArgs.mRemainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
@@ -471,15 +470,15 @@
args = amendedArgs;
}
- WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, parsedArgs.targetSdkVersion,
+ WrapperInit.execApplication(parsedArgs.mInvokeWith,
+ parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
- cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
+ cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
@@ -487,8 +486,8 @@
/*
* Pass the remaining arguments to SystemServer.
*/
- return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
- parsedArgs.remainingArgs, cl);
+ return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
+ parsedArgs.mRemainingArgs, cl);
}
/* should never reach here */
@@ -683,29 +682,29 @@
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
- ZygoteConnection.Arguments parsedArgs = null;
+ ZygoteArguments parsedArgs = null;
int pid;
try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
- ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
+ parsedArgs = new ZygoteArguments(args);
+ Zygote.applyDebuggerSystemProperty(parsedArgs);
+ Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
- parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
+ parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids,
- parsedArgs.runtimeFlags,
+ parsedArgs.mUid, parsedArgs.mGid,
+ parsedArgs.mGids,
+ parsedArgs.mRuntimeFlags,
null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
+ parsedArgs.mPermittedCapabilities,
+ parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index fecf9b9..c1bfde1 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -20,14 +20,14 @@
import android.net.LocalServerSocket;
import android.net.LocalSocket;
-import android.system.Os;
import android.system.ErrnoException;
+import android.system.Os;
import android.system.StructPollfd;
import android.util.Log;
-
import android.util.Slog;
-import java.io.IOException;
+
import java.io.FileDescriptor;
+import java.io.IOException;
import java.util.ArrayList;
/**
@@ -63,8 +63,7 @@
*/
private boolean mIsForkChild;
- ZygoteServer() {
- }
+ ZygoteServer() { }
void setForkChild() {
mIsForkChild = true;
@@ -197,7 +196,7 @@
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
+ fds.add(newPeer.getFileDescriptor());
} else {
try {
ZygoteConnection connection = peers.get(i);