blob: d4fa5cbb4f55a9e984adfe2d2bf7affd2bb096d9 [file] [log] [blame]
Narayan Kamath973b4662014-03-31 13:41:26 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Chris Wailesc37ebe12019-01-11 17:04:41 -080019import static android.system.OsConstants.O_CLOEXEC;
20
Chris Wailes682b4792019-01-11 16:14:43 -080021import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
22
23import android.net.Credentials;
Chris Wailesc37ebe12019-01-11 17:04:41 -080024import android.net.LocalServerSocket;
25import android.net.LocalSocket;
Chris Wailes682b4792019-01-11 16:14:43 -080026import android.os.FactoryTest;
Jeff Sharkeyace874b2017-09-07 15:27:33 -060027import android.os.IVold;
Chris Wailes682b4792019-01-11 16:14:43 -080028import android.os.Process;
29import android.os.SystemProperties;
Narayan Kamathfbb32f62015-06-12 15:34:35 +010030import android.os.Trace;
Elliott Hughes860c5912014-04-28 19:19:13 -070031import android.system.ErrnoException;
32import android.system.Os;
Chris Wailes682b4792019-01-11 16:14:43 -080033import android.util.Log;
Narayan Kamath973b4662014-03-31 13:41:26 +010034
Jeff Sharkeyace874b2017-09-07 15:27:33 -060035import dalvik.system.ZygoteHooks;
Tobias Sargeantb9679dc2016-01-19 16:34:54 +000036
Chris Wailesc37ebe12019-01-11 17:04:41 -080037import libcore.io.IoUtils;
38
Chris Wailes682b4792019-01-11 16:14:43 -080039import java.io.BufferedReader;
Chris Wailesc37ebe12019-01-11 17:04:41 -080040import java.io.ByteArrayOutputStream;
41import java.io.DataOutputStream;
42import java.io.FileDescriptor;
Chris Wailes682b4792019-01-11 16:14:43 -080043import java.io.IOException;
Chris Wailesc37ebe12019-01-11 17:04:41 -080044import java.io.InputStreamReader;
Chris Wailes682b4792019-01-11 16:14:43 -080045
Narayan Kamath973b4662014-03-31 13:41:26 +010046/** @hide */
47public final class Zygote {
48 /*
Nicolas Geoffray81edac42017-09-07 14:13:29 +010049 * Bit values for "runtimeFlags" argument. The definitions are duplicated
Narayan Kamath973b4662014-03-31 13:41:26 +010050 * in the native code.
51 */
52
53 /** enable debugging over JDWP */
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000054 public static final int DEBUG_ENABLE_JDWP = 1;
Narayan Kamath973b4662014-03-31 13:41:26 +010055 /** enable JNI checks */
56 public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1;
57 /** enable Java programming language "assert" statements */
58 public static final int DEBUG_ENABLE_ASSERT = 1 << 2;
Mathieu Chartier7a490282015-03-17 09:51:36 -070059 /** disable the AOT compiler and JIT */
Narayan Kamath973b4662014-03-31 13:41:26 +010060 public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3;
61 /** Enable logging of third-party JNI activity. */
62 public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
David Srbecky065075e2015-05-28 17:16:09 +010063 /** Force generation of native debugging information. */
Nicolas Geoffray9abbf452015-11-05 11:29:42 +000064 public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 5;
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000065 /** Always use JIT-ed code. */
66 public static final int DEBUG_ALWAYS_JIT = 1 << 6;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000067 /** Make the code native debuggable by turning off some optimizations. */
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000068 public static final int DEBUG_NATIVE_DEBUGGABLE = 1 << 7;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000069 /** Make the code Java debuggable by turning off some optimizations. */
70 public static final int DEBUG_JAVA_DEBUGGABLE = 1 << 8;
Mathieu Chartier7a490282015-03-17 09:51:36 -070071
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010072 /** Turn off the verifier. */
73 public static final int DISABLE_VERIFIER = 1 << 9;
74 /** Only use oat files located in /system. Otherwise use dex/jar/apk . */
75 public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
David Srbecky156ed922018-01-30 14:37:37 +000076 /** Force generation of native debugging information for backtraces. */
Mathew Inwood16073b82018-03-23 10:05:01 +000077 public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11;
78 /**
79 * Hidden API access restrictions. This is a mask for bits representing the API enforcement
80 * policy, defined by {@code @ApplicationInfo.HiddenApiEnforcementPolicy}.
81 */
82 public static final int API_ENFORCEMENT_POLICY_MASK = (1 << 12) | (1 << 13);
83 /**
84 * Bit shift for use with {@link #API_ENFORCEMENT_POLICY_MASK}.
85 *
86 * (flags & API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT gives
87 * @ApplicationInfo.ApiEnforcementPolicy values.
88 */
89 public static final int API_ENFORCEMENT_POLICY_SHIFT =
90 Integer.numberOfTrailingZeros(API_ENFORCEMENT_POLICY_MASK);
Calin Juravle8eb891b2018-05-03 19:51:18 -070091 /**
92 * Enable system server ART profiling.
93 */
94 public static final int PROFILE_SYSTEM_SERVER = 1 << 14;
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010095
Mathieu Chartierf5cd8c12019-02-04 13:28:36 -080096 /*
97 * Enable using the ART app image startup cache
98 */
99 public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
100
Narayan Kamath973b4662014-03-31 13:41:26 +0100101 /** No external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600102 public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700103 /** Default external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600104 public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700105 /** Read-only external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600106 public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700107 /** Read-write external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600108 public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
Narayan Kamath973b4662014-03-31 13:41:26 +0100109
Chris Wailesc37ebe12019-01-11 17:04:41 -0800110 /** Number of bytes sent to the Zygote over blastula pipes or the pool event FD */
111 public static final int BLASTULA_MANAGEMENT_MESSAGE_BYTES = 8;
112
Chris Wailescffbf1c2019-01-11 17:13:00 -0800113 /**
114 * If the blastula pool should be created and used to start applications.
115 *
116 * Setting this value to false will disable the creation, maintenance, and use of the blastula
117 * pool. When the blastula pool is disabled the application lifecycle will be identical to
118 * previous versions of Android.
119 */
Chris Wailesc37ebe12019-01-11 17:04:41 -0800120 public static final boolean BLASTULA_POOL_ENABLED = false;
121
122 /**
123 * File descriptor used for communication between the signal handler and the ZygoteServer poll
124 * loop.
125 * */
126 protected static FileDescriptor sBlastulaPoolEventFD;
127
Robert Sesekd0a190df2018-02-12 18:46:01 -0500128 /**
129 * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
130 * in the abstract socket namespace. This socket name is what the new child zygote
131 * should listen for connections on.
132 */
133 public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
134
Chris Wailesc37ebe12019-01-11 17:04:41 -0800135 /** Prefix prepended to socket names created by init */
136 private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
137
138 /**
139 * The maximum value that the sBlastulaPoolMax variable may take. This value
140 * is a mirror of BLASTULA_POOL_MAX_LIMIT found in com_android_internal_os_Zygote.cpp.
141 */
142 static final int BLASTULA_POOL_MAX_LIMIT = 10;
143
144 /**
145 * The minimum value that the sBlastulaPoolMin variable may take.
146 */
147 static final int BLASTULA_POOL_MIN_LIMIT = 1;
148
149 /**
150 * The runtime-adjustable maximum Blastula pool size.
151 */
152 static int sBlastulaPoolMax = BLASTULA_POOL_MAX_LIMIT;
153
154 /**
155 * The runtime-adjustable minimum Blastula pool size.
156 */
157 static int sBlastulaPoolMin = BLASTULA_POOL_MIN_LIMIT;
158
159 /**
160 * The runtime-adjustable value used to determine when to re-fill the
161 * blastula pool. The pool will be re-filled when
162 * (sBlastulaPoolMax - gBlastulaPoolCount) >= sBlastulaPoolRefillThreshold.
163 */
164 // TODO (chriswailes): This must be updated at the same time as sBlastulaPoolMax.
165 static int sBlastulaPoolRefillThreshold = (sBlastulaPoolMax / 2);
166
Chris Wailescffbf1c2019-01-11 17:13:00 -0800167 /**
168 * @hide for internal use only
169 */
170 public static final int SOCKET_BUFFER_SIZE = 256;
171
Chris Wailesc37ebe12019-01-11 17:04:41 -0800172 private static LocalServerSocket sBlastulaPoolSocket = null;
173
Chris Wailes682b4792019-01-11 16:14:43 -0800174 /** a prototype instance for a future List.toArray() */
175 protected static final int[][] INT_ARRAY_2D = new int[0][0];
176
Narayan Kamath973b4662014-03-31 13:41:26 +0100177 private Zygote() {}
178
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800179 /** Called for some security initialization before any fork. */
Chris Wailes8b35ba22019-01-10 16:55:32 -0800180 static native void nativeSecurityInit();
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800181
Narayan Kamath973b4662014-03-31 13:41:26 +0100182 /**
183 * Forks a new VM instance. The current VM must have been started
184 * with the -Xzygote flag. <b>NOTE: new instance keeps all
185 * root capabilities. The new process is expected to call capset()</b>.
186 *
187 * @param uid the UNIX uid that the new process should setuid() to after
188 * fork()ing and and before spawning any threads.
189 * @param gid the UNIX gid that the new process should setgid() to after
190 * fork()ing and and before spawning any threads.
191 * @param gids null-ok; a list of UNIX gids that the new process should
192 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100193 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100194 * @param rlimits null-ok an array of rlimit tuples, with the second
195 * dimension having a length of 3 and representing
196 * (resource, rlim_cur, rlim_max). These are set via the posix
197 * setrlimit(2) call.
198 * @param seInfo null-ok a string specifying SELinux information for
199 * the new process.
200 * @param niceName null-ok a string specifying the process name.
201 * @param fdsToClose an array of ints, holding one or more POSIX
202 * file descriptor numbers that are to be closed by the child
203 * (and replaced by /dev/null) after forking. An integer value
204 * of -1 in any entry in the array means "ignore this one".
Andreas Gampe8dfa1782017-01-05 12:45:58 -0800205 * @param fdsToIgnore null-ok an array of ints, either null or holding
206 * one or more POSIX file descriptor numbers that are to be ignored
207 * in the file descriptor table check.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500208 * @param startChildZygote if true, the new child process will itself be a
209 * new zygote process.
Andreas Gampeaec67dc2014-09-02 21:23:06 -0700210 * @param instructionSet null-ok the instruction set to use.
jgu212eacd062014-09-10 06:55:07 -0400211 * @param appDataDir null-ok the data directory of the app.
Narayan Kamath973b4662014-03-31 13:41:26 +0100212 *
213 * @return 0 if this is the child, pid of the child
214 * if this is the parent, or -1 on error.
215 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100216 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
Chris Wailes8b35ba22019-01-10 16:55:32 -0800217 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
218 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) {
Neil Fuller927c15c2019-01-28 18:29:20 +0000219 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800220 // Resets nice priority for zygote process.
221 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100222 int pid = nativeForkAndSpecialize(
Chris Wailes8b35ba22019-01-10 16:55:32 -0800223 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
224 fdsToIgnore, startChildZygote, instructionSet, appDataDir);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100225 // Enable tracing as soon as possible for the child process.
226 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700227 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100228
229 // Note that this event ends at the end of handleChildProc,
230 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
231 }
Neil Fuller927c15c2019-01-28 18:29:20 +0000232 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100233 return pid;
234 }
235
Chris Wailes8b35ba22019-01-10 16:55:32 -0800236 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
237 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
238 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
239 String appDataDir);
240
Chris Wailesc37ebe12019-01-11 17:04:41 -0800241 /**
242 * Specialize a Blastula instance. The current VM must have been started
243 * with the -Xzygote flag.
244 *
245 * @param uid The UNIX uid that the new process should setuid() to before spawning any threads
246 * @param gid The UNIX gid that the new process should setgid() to before spawning any threads
247 * @param gids null-ok; A list of UNIX gids that the new process should
248 * setgroups() to before spawning any threads
249 * @param runtimeFlags Bit flags that enable ART features
250 * @param rlimits null-ok An array of rlimit tuples, with the second
251 * dimension having a length of 3 and representing
252 * (resource, rlim_cur, rlim_max). These are set via the posix
253 * setrlimit(2) call.
254 * @param seInfo null-ok A string specifying SELinux information for
255 * the new process.
256 * @param niceName null-ok A string specifying the process name.
257 * @param startChildZygote If true, the new child process will itself be a
258 * new zygote process.
259 * @param instructionSet null-ok The instruction set to use.
260 * @param appDataDir null-ok The data directory of the app.
261 */
262 public static void specializeBlastula(int uid, int gid, int[] gids, int runtimeFlags,
263 int[][] rlimits, int mountExternal, String seInfo, String niceName,
264 boolean startChildZygote, String instructionSet, String appDataDir) {
265
266 nativeSpecializeBlastula(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
267 niceName, startChildZygote, instructionSet, appDataDir);
268
269 // Enable tracing as soon as possible for the child process.
270 Trace.setTracingEnabled(true, runtimeFlags);
271
272 // Note that this event ends at the end of handleChildProc.
273 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
274
275 /*
276 * This is called here (instead of after the fork but before the specialize) to maintain
277 * consistancy with the code paths for forkAndSpecialize.
278 *
279 * TODO (chriswailes): Look into moving this to immediately after the fork.
280 */
Neil Fuller927c15c2019-01-28 18:29:20 +0000281 ZygoteHooks.postForkCommon();
Chris Wailesc37ebe12019-01-11 17:04:41 -0800282 }
283
Chris Wailes8b35ba22019-01-10 16:55:32 -0800284 private static native void nativeSpecializeBlastula(int uid, int gid, int[] gids,
285 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
286 boolean startChildZygote, String instructionSet, String appDataDir);
Narayan Kamath973b4662014-03-31 13:41:26 +0100287
288 /**
Christopher Ferris2980de42017-06-20 16:13:40 -0700289 * Called to do any initialization before starting an application.
290 */
Chris Wailes8b35ba22019-01-10 16:55:32 -0800291 static native void nativePreApplicationInit();
Christopher Ferris2980de42017-06-20 16:13:40 -0700292
293 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100294 * Special method to start the system server process. In addition to the
295 * common actions performed in forkAndSpecialize, the pid of the child
296 * process is recorded such that the death of the child process will cause
297 * zygote to exit.
298 *
299 * @param uid the UNIX uid that the new process should setuid() to after
300 * fork()ing and and before spawning any threads.
301 * @param gid the UNIX gid that the new process should setgid() to after
302 * fork()ing and and before spawning any threads.
303 * @param gids null-ok; a list of UNIX gids that the new process should
304 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100305 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100306 * @param rlimits null-ok an array of rlimit tuples, with the second
307 * dimension having a length of 3 and representing
308 * (resource, rlim_cur, rlim_max). These are set via the posix
309 * setrlimit(2) call.
310 * @param permittedCapabilities argument for setcap()
311 * @param effectiveCapabilities argument for setcap()
312 *
313 * @return 0 if this is the child, pid of the child
314 * if this is the parent, or -1 on error.
315 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100316 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100317 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
Neil Fuller927c15c2019-01-28 18:29:20 +0000318 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800319 // Resets nice priority for zygote process.
320 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100321 int pid = nativeForkSystemServer(
Chris Wailes8b35ba22019-01-10 16:55:32 -0800322 uid, gid, gids, runtimeFlags, rlimits,
323 permittedCapabilities, effectiveCapabilities);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100324 // Enable tracing as soon as we enter the system_server.
325 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700326 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100327 }
Neil Fuller927c15c2019-01-28 18:29:20 +0000328 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100329 return pid;
330 }
331
Chris Wailes8b35ba22019-01-10 16:55:32 -0800332 private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100333 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
334
doheon1.lee885b7422016-01-20 13:07:27 +0900335 /**
Robert Sesek54e387d2016-12-02 17:27:50 -0500336 * Lets children of the zygote inherit open file descriptors to this path.
337 */
Chris Wailes8b35ba22019-01-10 16:55:32 -0800338 protected static native void nativeAllowFileAcrossFork(String path);
Robert Sesek54e387d2016-12-02 17:27:50 -0500339
340 /**
doheon1.lee885b7422016-01-20 13:07:27 +0900341 * Zygote unmount storage space on initializing.
342 * This method is called once.
343 */
Chris Wailes8b35ba22019-01-10 16:55:32 -0800344 protected static native void nativeUnmountStorageOnInit();
345
Chris Wailesc37ebe12019-01-11 17:04:41 -0800346 /**
347 * Get socket file descriptors (opened by init) from the environment and
348 * store them for access from native code later.
349 *
350 * @param isPrimary True if this is the zygote process, false if it is zygote_secondary
351 */
352 public static void getSocketFDs(boolean isPrimary) {
353 nativeGetSocketFDs(isPrimary);
354 }
355
Chris Wailes8b35ba22019-01-10 16:55:32 -0800356 protected static native void nativeGetSocketFDs(boolean isPrimary);
357
Chris Wailesc37ebe12019-01-11 17:04:41 -0800358 /**
359 * Initialize the blastula pool and fill it with the desired number of
360 * processes.
361 */
362 protected static Runnable initBlastulaPool() {
363 if (BLASTULA_POOL_ENABLED) {
364 sBlastulaPoolEventFD = getBlastulaPoolEventFD();
365
366 return fillBlastulaPool(null);
367 } else {
368 return null;
369 }
370 }
371
372 /**
373 * Checks to see if the current policy says that pool should be refilled, and spawns new
374 * blastulas if necessary.
375 *
376 * NOTE: This function doesn't need to be guarded with BLASTULA_POOL_ENABLED because it is
377 * only called from contexts that are only valid if the pool is enabled.
378 *
379 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
380 * @return In the Zygote process this function will always return null; in blastula processes
381 * this function will return a Runnable object representing the new application that is
382 * passed up from blastulaMain.
383 */
384 protected static Runnable fillBlastulaPool(int[] sessionSocketRawFDs) {
385 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillBlastulaPool");
386
387 int blastulaPoolCount = getBlastulaPoolCount();
388
389 int numBlastulasToSpawn = sBlastulaPoolMax - blastulaPoolCount;
390
391 if (blastulaPoolCount < sBlastulaPoolMin
392 || numBlastulasToSpawn >= sBlastulaPoolRefillThreshold) {
393
394 // Disable some VM functionality and reset some system values
395 // before forking.
Neil Fuller927c15c2019-01-28 18:29:20 +0000396 ZygoteHooks.preFork();
Chris Wailesc37ebe12019-01-11 17:04:41 -0800397 resetNicePriority();
398
399 while (blastulaPoolCount++ < sBlastulaPoolMax) {
400 Runnable caller = forkBlastula(sessionSocketRawFDs);
401
402 if (caller != null) {
403 return caller;
404 }
405 }
406
407 // Re-enable runtime services for the Zygote. Blastula services
408 // are re-enabled in specializeBlastula.
Neil Fuller927c15c2019-01-28 18:29:20 +0000409 ZygoteHooks.postForkCommon();
Chris Wailesc37ebe12019-01-11 17:04:41 -0800410
411 Log.i("zygote", "Filled the blastula pool. New blastulas: " + numBlastulasToSpawn);
412 }
413
414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
415
416 return null;
417 }
418
419 /**
420 * @return Number of blastulas currently in the pool
421 */
422 private static int getBlastulaPoolCount() {
423 return nativeGetBlastulaPoolCount();
424 }
425
Chris Wailes8b35ba22019-01-10 16:55:32 -0800426 private static native int nativeGetBlastulaPoolCount();
427
Chris Wailesc37ebe12019-01-11 17:04:41 -0800428 /**
429 * @return The event FD used for communication between the signal handler and the ZygoteServer
430 * poll loop
431 */
432 private static FileDescriptor getBlastulaPoolEventFD() {
433 FileDescriptor fd = new FileDescriptor();
434 fd.setInt$(nativeGetBlastulaPoolEventFD());
435
436 return fd;
437 }
438
Chris Wailes8b35ba22019-01-10 16:55:32 -0800439 private static native int nativeGetBlastulaPoolEventFD();
440
Chris Wailesc37ebe12019-01-11 17:04:41 -0800441 /**
442 * Fork a new blastula process from the zygote
443 *
444 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
445 * @return In the Zygote process this function will always return null; in blastula processes
446 * this function will return a Runnable object representing the new application that is
447 * passed up from blastulaMain.
448 */
449 private static Runnable forkBlastula(int[] sessionSocketRawFDs) {
450 FileDescriptor[] pipeFDs = null;
451
452 try {
453 pipeFDs = Os.pipe2(O_CLOEXEC);
454 } catch (ErrnoException errnoEx) {
455 throw new IllegalStateException("Unable to create blastula pipe.", errnoEx);
456 }
457
458 int pid =
459 nativeForkBlastula(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
460
461 if (pid == 0) {
462 IoUtils.closeQuietly(pipeFDs[0]);
463 return blastulaMain(pipeFDs[1]);
464 } else {
465 // The read-end of the pipe will be closed by the native code.
466 // See removeBlastulaTableEntry();
467 IoUtils.closeQuietly(pipeFDs[1]);
468 return null;
469 }
470 }
471
Chris Wailes8b35ba22019-01-10 16:55:32 -0800472 private static native int nativeForkBlastula(int readPipeFD,
473 int writePipeFD,
474 int[] sessionSocketRawFDs);
475
Chris Wailesc37ebe12019-01-11 17:04:41 -0800476 /**
477 * This function is used by blastulas to wait for specialization requests from the system
478 * server.
479 *
480 * @param writePipe The write end of the reporting pipe used to communicate with the poll loop
481 * of the ZygoteServer.
482 * @return A runnable oject representing the new application.
483 */
484 static Runnable blastulaMain(FileDescriptor writePipe) {
485 final int pid = Process.myPid();
486
487 LocalSocket sessionSocket = null;
488 DataOutputStream blastulaOutputStream = null;
489 Credentials peerCredentials = null;
490 String[] argStrings = null;
491
492 while (true) {
493 try {
494 sessionSocket = sBlastulaPoolSocket.accept();
495
496 BufferedReader blastulaReader =
497 new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
498 blastulaOutputStream =
499 new DataOutputStream(sessionSocket.getOutputStream());
500
501 peerCredentials = sessionSocket.getPeerCredentials();
502
503 argStrings = readArgumentList(blastulaReader);
504
505 if (argStrings != null) {
506 break;
507 } else {
508 Log.e("Blastula", "Truncated command received.");
509 IoUtils.closeQuietly(sessionSocket);
510 }
511 } catch (IOException ioEx) {
512 Log.e("Blastula", "Failed to read command: " + ioEx.getMessage());
513 IoUtils.closeQuietly(sessionSocket);
514 }
515 }
516
517 ZygoteArguments args = new ZygoteArguments(argStrings);
518
519 // TODO (chriswailes): Should this only be run for debug builds?
520 validateBlastulaCommand(args);
521
522 applyUidSecurityPolicy(args, peerCredentials);
523 applyDebuggerSystemProperty(args);
524
525 int[][] rlimits = null;
526
527 if (args.mRLimits != null) {
528 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
529 }
530
531 // This must happen before the SELinux policy for this process is
532 // changed when specializing.
533 try {
534 // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
535 // Process.ProcessStartResult object.
536 blastulaOutputStream.writeInt(pid);
537 } catch (IOException ioEx) {
538 Log.e("Blastula", "Failed to write response to session socket: " + ioEx.getMessage());
539 System.exit(-1);
540 } finally {
541 IoUtils.closeQuietly(sessionSocket);
542 IoUtils.closeQuietly(sBlastulaPoolSocket);
543 }
544
545 try {
546 ByteArrayOutputStream buffer =
547 new ByteArrayOutputStream(Zygote.BLASTULA_MANAGEMENT_MESSAGE_BYTES);
548 DataOutputStream outputStream = new DataOutputStream(buffer);
549
550 // This is written as a long so that the blastula reporting pipe and blastula pool
551 // event FD handlers in ZygoteServer.runSelectLoop can be unified. These two cases
552 // should both send/receive 8 bytes.
553 outputStream.writeLong(pid);
554 outputStream.flush();
555
556 Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
557 } catch (Exception ex) {
558 Log.e("Blastula",
559 String.format("Failed to write PID (%d) to pipe (%d): %s",
560 pid, writePipe.getInt$(), ex.getMessage()));
561 System.exit(-1);
562 } finally {
563 IoUtils.closeQuietly(writePipe);
564 }
565
566 specializeBlastula(args.mUid, args.mGid, args.mGids,
567 args.mRuntimeFlags, rlimits, args.mMountExternal,
568 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
569 args.mInstructionSet, args.mAppDataDir);
570
571 if (args.mNiceName != null) {
572 Process.setArgV0(args.mNiceName);
573 }
574
575 // End of the postFork event.
576 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
577
578 return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
579 args.mRemainingArgs,
580 null /* classLoader */);
581 }
582
583 private static final String BLASTULA_ERROR_PREFIX = "Invalid command to blastula: ";
584
585 /**
586 * Checks a set of zygote arguments to see if they can be handled by a blastula. Throws an
587 * exception if an invalid arugment is encountered.
588 * @param args The arguments to test
589 */
590 static void validateBlastulaCommand(ZygoteArguments args) {
591 if (args.mAbiListQuery) {
592 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--query-abi-list");
593 } else if (args.mPidQuery) {
594 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--get-pid");
595 } else if (args.mPreloadDefault) {
596 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-default");
597 } else if (args.mPreloadPackage != null) {
598 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-package");
599 } else if (args.mStartChildZygote) {
600 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--start-child-zygote");
601 } else if (args.mApiBlacklistExemptions != null) {
602 throw new IllegalArgumentException(
603 BLASTULA_ERROR_PREFIX + "--set-api-blacklist-exemptions");
604 } else if (args.mHiddenApiAccessLogSampleRate != -1) {
605 throw new IllegalArgumentException(
606 BLASTULA_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
607 } else if (args.mInvokeWith != null) {
608 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--invoke-with");
609 } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
610 throw new ZygoteSecurityException("Client may not specify capabilities: "
611 + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities)
612 + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities));
613 }
614 }
615
616 /**
617 * @return Raw file descriptors for the read-end of blastula reporting pipes.
618 */
619 protected static int[] getBlastulaPipeFDs() {
620 return nativeGetBlastulaPipeFDs();
621 }
622
Chris Wailes8b35ba22019-01-10 16:55:32 -0800623 private static native int[] nativeGetBlastulaPipeFDs();
624
Chris Wailesc37ebe12019-01-11 17:04:41 -0800625 /**
626 * Remove the blastula table entry for the provided process ID.
627 *
628 * @param blastulaPID Process ID of the entry to remove
629 * @return True if the entry was removed; false if it doesn't exist
630 */
631 protected static boolean removeBlastulaTableEntry(int blastulaPID) {
632 return nativeRemoveBlastulaTableEntry(blastulaPID);
633 }
634
Chris Wailes8b35ba22019-01-10 16:55:32 -0800635 private static native boolean nativeRemoveBlastulaTableEntry(int blastulaPID);
636
Chris Wailes682b4792019-01-11 16:14:43 -0800637 /**
638 * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
639 * operation. It may also specify any gid and setgroups() list it chooses.
640 * In factory test mode, it may specify any UID.
641 *
642 * @param args non-null; zygote spawner arguments
643 * @param peer non-null; peer credentials
644 * @throws ZygoteSecurityException
645 */
646 protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
647 throws ZygoteSecurityException {
648
649 if (peer.getUid() == Process.SYSTEM_UID) {
650 /* In normal operation, SYSTEM_UID can only specify a restricted
651 * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
652 */
653 boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
654
655 if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
656 throw new ZygoteSecurityException(
657 "System UID may not launch process with UID < "
658 + Process.SYSTEM_UID);
659 }
660 }
661
662 // If not otherwise specified, uid and gid are inherited from peer
663 if (!args.mUidSpecified) {
664 args.mUid = peer.getUid();
665 args.mUidSpecified = true;
666 }
667 if (!args.mGidSpecified) {
668 args.mGid = peer.getGid();
669 args.mGidSpecified = true;
670 }
671 }
672
673 /**
674 * Applies debugger system properties to the zygote arguments.
675 *
676 * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
677 * the debugger state is specified via the "--enable-jdwp" flag
678 * in the spawn request.
679 *
680 * @param args non-null; zygote spawner args
681 */
682 protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
683 if (RoSystemProperties.DEBUGGABLE) {
684 args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
685 }
686 }
687
688 /**
689 * Applies zygote security policy.
690 * Based on the credentials of the process issuing a zygote command:
691 * <ol>
692 * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
693 * wrapper command.
694 * <li> Any other uid may not specify any invoke-with argument.
695 * </ul>
696 *
697 * @param args non-null; zygote spawner arguments
698 * @param peer non-null; peer credentials
699 * @throws ZygoteSecurityException
700 */
701 protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
702 throws ZygoteSecurityException {
703 int peerUid = peer.getUid();
704
705 if (args.mInvokeWith != null && peerUid != 0
706 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
707 throw new ZygoteSecurityException("Peer is permitted to specify an"
708 + "explicit invoke-with wrapper command only for debuggable"
709 + "applications.");
710 }
711 }
712
713 /**
714 * Applies invoke-with system properties to the zygote arguments.
715 *
716 * @param args non-null; zygote args
717 */
718 protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
719 if (args.mInvokeWith == null && args.mNiceName != null) {
720 String property = "wrap." + args.mNiceName;
721 args.mInvokeWith = SystemProperties.get(property);
722 if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
723 args.mInvokeWith = null;
724 }
725 }
726 }
727
728 /**
729 * Reads an argument list from the provided socket
730 * @return Argument list or null if EOF is reached
731 * @throws IOException passed straight through
732 */
733 static String[] readArgumentList(BufferedReader socketReader) throws IOException {
Chris Wailes682b4792019-01-11 16:14:43 -0800734 int argc;
735
736 try {
737 String argc_string = socketReader.readLine();
738
739 if (argc_string == null) {
740 // EOF reached.
741 return null;
742 }
743 argc = Integer.parseInt(argc_string);
744
745 } catch (NumberFormatException ex) {
746 Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
747 throw new IOException("Invalid wire format");
748 }
749
750 // See bug 1092107: large argc can be used for a DOS attack
751 if (argc > MAX_ZYGOTE_ARGC) {
752 throw new IOException("Max arg count exceeded");
753 }
754
755 String[] args = new String[argc];
756 for (int arg_index = 0; arg_index < argc; arg_index++) {
757 args[arg_index] = socketReader.readLine();
758 if (args[arg_index] == null) {
759 // We got an unexpected EOF.
760 throw new IOException("Truncated request");
761 }
762 }
763
764 return args;
765 }
766
Chris Wailesc37ebe12019-01-11 17:04:41 -0800767 /**
768 * Creates a managed object representing the Blastula pool socket that has
769 * already been initialized and bound by init.
770 *
771 * TODO (chriswailes): Move the name selection logic into this function.
772 *
773 * @throws RuntimeException when open fails
774 */
775 static void createBlastulaSocket(String socketName) {
776 if (BLASTULA_POOL_ENABLED && sBlastulaPoolSocket == null) {
777 sBlastulaPoolSocket = createManagedSocketFromInitSocket(socketName);
778 }
779 }
780
781 /**
782 * Creates a managed LocalServerSocket object using a file descriptor
783 * created by an init.rc script. The init scripts that specify the
784 * sockets name can be found in system/core/rootdir. The socket is bound
785 * to the file system in the /dev/sockets/ directory, and the file
786 * descriptor is shared via the ANDROID_SOCKET_<socketName> environment
787 * variable.
788 */
789 static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
790 int fileDesc;
791 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
792
793 try {
794 String env = System.getenv(fullSocketName);
795 fileDesc = Integer.parseInt(env);
796 } catch (RuntimeException ex) {
797 throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
798 }
799
800 try {
801 FileDescriptor fd = new FileDescriptor();
802 fd.setInt$(fileDesc);
803 return new LocalServerSocket(fd);
804 } catch (IOException ex) {
805 throw new RuntimeException(
806 "Error building socket from file descriptor: " + fileDesc, ex);
807 }
808 }
doheon1.lee885b7422016-01-20 13:07:27 +0900809
Orion Hodson46724e72018-10-19 13:05:33 +0100810 private static void callPostForkSystemServerHooks() {
811 // SystemServer specific post fork hooks run before child post fork hooks.
Neil Fuller927c15c2019-01-28 18:29:20 +0000812 ZygoteHooks.postForkSystemServer();
Orion Hodson46724e72018-10-19 13:05:33 +0100813 }
814
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100815 private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
Robert Sesekd0a190df2018-02-12 18:46:01 -0500816 boolean isZygote, String instructionSet) {
Neil Fuller927c15c2019-01-28 18:29:20 +0000817 ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
Narayan Kamath973b4662014-03-31 13:41:26 +0100818 }
819
Narayan Kamathb49996d2017-02-06 20:24:08 +0000820 /**
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800821 * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
822 * or nice value 0). This updates both the priority value in java.lang.Thread and
823 * the nice value (setpriority).
Narayan Kamathb49996d2017-02-06 20:24:08 +0000824 */
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800825 static void resetNicePriority() {
826 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
827 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100828
829 /**
830 * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
831 * This method throws a runtime exception if exec() failed, otherwise, this
832 * method never returns.
833 *
834 * @param command The shell command to execute.
835 */
836 public static void execShell(String command) {
837 String[] args = { "/system/bin/sh", "-c", command };
838 try {
Elliott Hughes860c5912014-04-28 19:19:13 -0700839 Os.execv(args[0], args);
Narayan Kamath973b4662014-03-31 13:41:26 +0100840 } catch (ErrnoException e) {
841 throw new RuntimeException(e);
842 }
843 }
844
845 /**
846 * Appends quotes shell arguments to the specified string builder.
847 * The arguments are quoted using single-quotes, escaped if necessary,
848 * prefixed with a space, and appended to the command.
849 *
850 * @param command A string builder for the shell command being constructed.
851 * @param args An array of argument strings to be quoted and appended to the command.
852 * @see #execShell(String)
853 */
854 public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
855 for (String arg : args) {
856 command.append(" '").append(arg.replace("'", "'\\''")).append("'");
857 }
858 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100859}