blob: bc7cf87557864a861ad49534020bb7e6e13a49cc [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 Wailescb0b37f2019-01-11 17:04:41 -080019import static android.system.OsConstants.O_CLOEXEC;
20
Chris Wailes2be26262019-01-11 16:14:43 -080021import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
22
23import android.net.Credentials;
Chris Wailescb0b37f2019-01-11 17:04:41 -080024import android.net.LocalServerSocket;
25import android.net.LocalSocket;
Chris Wailes2be26262019-01-11 16:14:43 -080026import android.os.FactoryTest;
Jeff Sharkeyace874b2017-09-07 15:27:33 -060027import android.os.IVold;
Chris Wailes2be26262019-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 Wailes2be26262019-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 Wailescb0b37f2019-01-11 17:04:41 -080037import libcore.io.IoUtils;
38
Chris Wailes2be26262019-01-11 16:14:43 -080039import java.io.BufferedReader;
Chris Wailescb0b37f2019-01-11 17:04:41 -080040import java.io.ByteArrayOutputStream;
41import java.io.DataOutputStream;
42import java.io.FileDescriptor;
Chris Wailes2be26262019-01-11 16:14:43 -080043import java.io.IOException;
Chris Wailescb0b37f2019-01-11 17:04:41 -080044import java.io.InputStreamReader;
Chris Wailes2be26262019-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
Narayan Kamath973b4662014-03-31 13:41:26 +010096 /** No external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -060097 public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
Jeff Sharkey9527b222015-06-24 15:24:48 -070098 /** Default external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -060099 public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700100 /** Read-only external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600101 public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700102 /** Read-write external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600103 public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800104 /**
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800105 * Mount mode for apps that are already installed on the device before the isolated_storage
106 * feature is enabled.
107 */
108 public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY;
109 /**
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800110 * Mount mode for package installers which should give them access to
111 * all obb dirs in addition to their package sandboxes
112 */
113 public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700114 /** Read-write external storage should be mounted instead of package sandbox */
115 public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL;
Narayan Kamath973b4662014-03-31 13:41:26 +0100116
Chris Wailescb0b37f2019-01-11 17:04:41 -0800117 /** Number of bytes sent to the Zygote over blastula pipes or the pool event FD */
118 public static final int BLASTULA_MANAGEMENT_MESSAGE_BYTES = 8;
119
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800120 /**
121 * If the blastula pool should be created and used to start applications.
122 *
123 * Setting this value to false will disable the creation, maintenance, and use of the blastula
124 * pool. When the blastula pool is disabled the application lifecycle will be identical to
125 * previous versions of Android.
126 */
Chris Wailescb0b37f2019-01-11 17:04:41 -0800127 public static final boolean BLASTULA_POOL_ENABLED = false;
128
129 /**
130 * File descriptor used for communication between the signal handler and the ZygoteServer poll
131 * loop.
132 * */
133 protected static FileDescriptor sBlastulaPoolEventFD;
134
Robert Sesekd0a190df2018-02-12 18:46:01 -0500135 /**
136 * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
137 * in the abstract socket namespace. This socket name is what the new child zygote
138 * should listen for connections on.
139 */
140 public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
141
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100142 /**
143 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
144 * requested ABI for the child Zygote.
145 */
146 public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list=";
147
Martijn Coenen86f08a52019-01-03 16:23:01 +0100148 /**
149 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
150 * start of the UID range the children of the Zygote may setuid()/setgid() to. This
151 * will be enforced with a seccomp filter.
152 */
153 public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start=";
154
155 /**
156 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
157 * end of the UID range the children of the Zygote may setuid()/setgid() to. This
158 * will be enforced with a seccomp filter.
159 */
160 public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end=";
161
Chris Wailescb0b37f2019-01-11 17:04:41 -0800162 /** Prefix prepended to socket names created by init */
163 private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
164
165 /**
166 * The maximum value that the sBlastulaPoolMax variable may take. This value
167 * is a mirror of BLASTULA_POOL_MAX_LIMIT found in com_android_internal_os_Zygote.cpp.
168 */
169 static final int BLASTULA_POOL_MAX_LIMIT = 10;
170
171 /**
172 * The minimum value that the sBlastulaPoolMin variable may take.
173 */
174 static final int BLASTULA_POOL_MIN_LIMIT = 1;
175
176 /**
177 * The runtime-adjustable maximum Blastula pool size.
178 */
179 static int sBlastulaPoolMax = BLASTULA_POOL_MAX_LIMIT;
180
181 /**
182 * The runtime-adjustable minimum Blastula pool size.
183 */
184 static int sBlastulaPoolMin = BLASTULA_POOL_MIN_LIMIT;
185
186 /**
187 * The runtime-adjustable value used to determine when to re-fill the
188 * blastula pool. The pool will be re-filled when
189 * (sBlastulaPoolMax - gBlastulaPoolCount) >= sBlastulaPoolRefillThreshold.
190 */
191 // TODO (chriswailes): This must be updated at the same time as sBlastulaPoolMax.
192 static int sBlastulaPoolRefillThreshold = (sBlastulaPoolMax / 2);
193
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800194 /**
195 * @hide for internal use only
196 */
197 public static final int SOCKET_BUFFER_SIZE = 256;
198
Chris Wailescb0b37f2019-01-11 17:04:41 -0800199 private static LocalServerSocket sBlastulaPoolSocket = null;
200
Chris Wailes2be26262019-01-11 16:14:43 -0800201 /** a prototype instance for a future List.toArray() */
202 protected static final int[][] INT_ARRAY_2D = new int[0][0];
203
Narayan Kamath973b4662014-03-31 13:41:26 +0100204 private Zygote() {}
205
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800206 /** Called for some security initialization before any fork. */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800207 static native void nativeSecurityInit();
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800208
Narayan Kamath973b4662014-03-31 13:41:26 +0100209 /**
210 * Forks a new VM instance. The current VM must have been started
211 * with the -Xzygote flag. <b>NOTE: new instance keeps all
212 * root capabilities. The new process is expected to call capset()</b>.
213 *
214 * @param uid the UNIX uid that the new process should setuid() to after
215 * fork()ing and and before spawning any threads.
216 * @param gid the UNIX gid that the new process should setgid() to after
217 * fork()ing and and before spawning any threads.
218 * @param gids null-ok; a list of UNIX gids that the new process should
219 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100220 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100221 * @param rlimits null-ok an array of rlimit tuples, with the second
222 * dimension having a length of 3 and representing
223 * (resource, rlim_cur, rlim_max). These are set via the posix
224 * setrlimit(2) call.
225 * @param seInfo null-ok a string specifying SELinux information for
226 * the new process.
227 * @param niceName null-ok a string specifying the process name.
228 * @param fdsToClose an array of ints, holding one or more POSIX
229 * file descriptor numbers that are to be closed by the child
230 * (and replaced by /dev/null) after forking. An integer value
231 * of -1 in any entry in the array means "ignore this one".
Andreas Gampe8dfa1782017-01-05 12:45:58 -0800232 * @param fdsToIgnore null-ok an array of ints, either null or holding
233 * one or more POSIX file descriptor numbers that are to be ignored
234 * in the file descriptor table check.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500235 * @param startChildZygote if true, the new child process will itself be a
236 * new zygote process.
Andreas Gampeaec67dc2014-09-02 21:23:06 -0700237 * @param instructionSet null-ok the instruction set to use.
jgu212eacd062014-09-10 06:55:07 -0400238 * @param appDataDir null-ok the data directory of the app.
Narayan Kamath973b4662014-03-31 13:41:26 +0100239 *
240 * @return 0 if this is the child, pid of the child
241 * if this is the parent, or -1 on error.
242 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100243 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700244 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
245 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800246 String packageName, String[] packagesForUID, String[] visibleVolIDs) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000247 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800248 // Resets nice priority for zygote process.
249 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100250 int pid = nativeForkAndSpecialize(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800251 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
252 fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800253 packagesForUID, visibleVolIDs);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100254 // Enable tracing as soon as possible for the child process.
255 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700256 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100257
258 // Note that this event ends at the end of handleChildProc,
259 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
260 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000261 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100262 return pid;
263 }
264
Chris Wailesaa1c9622019-01-10 16:55:32 -0800265 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
266 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
267 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800268 String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800269
Chris Wailescb0b37f2019-01-11 17:04:41 -0800270 /**
271 * Specialize a Blastula instance. The current VM must have been started
272 * with the -Xzygote flag.
273 *
274 * @param uid The UNIX uid that the new process should setuid() to before spawning any threads
275 * @param gid The UNIX gid that the new process should setgid() to before spawning any threads
276 * @param gids null-ok; A list of UNIX gids that the new process should
277 * setgroups() to before spawning any threads
278 * @param runtimeFlags Bit flags that enable ART features
279 * @param rlimits null-ok An array of rlimit tuples, with the second
280 * dimension having a length of 3 and representing
281 * (resource, rlim_cur, rlim_max). These are set via the posix
282 * setrlimit(2) call.
283 * @param seInfo null-ok A string specifying SELinux information for
284 * the new process.
285 * @param niceName null-ok A string specifying the process name.
286 * @param startChildZygote If true, the new child process will itself be a
287 * new zygote process.
288 * @param instructionSet null-ok The instruction set to use.
289 * @param appDataDir null-ok The data directory of the app.
290 */
291 public static void specializeBlastula(int uid, int gid, int[] gids, int runtimeFlags,
292 int[][] rlimits, int mountExternal, String seInfo, String niceName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800293 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
294 String[] packagesForUID, String[] visibleVolIDs) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800295
296 nativeSpecializeBlastula(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
297 niceName, startChildZygote, instructionSet, appDataDir,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800298 packageName, packagesForUID, visibleVolIDs);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800299
300 // Enable tracing as soon as possible for the child process.
301 Trace.setTracingEnabled(true, runtimeFlags);
302
303 // Note that this event ends at the end of handleChildProc.
304 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
305
306 /*
307 * This is called here (instead of after the fork but before the specialize) to maintain
308 * consistancy with the code paths for forkAndSpecialize.
309 *
310 * TODO (chriswailes): Look into moving this to immediately after the fork.
311 */
Neil Fuller555d8b72019-01-28 18:29:20 +0000312 ZygoteHooks.postForkCommon();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800313 }
314
Chris Wailesaa1c9622019-01-10 16:55:32 -0800315 private static native void nativeSpecializeBlastula(int uid, int gid, int[] gids,
316 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
317 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800318 String[] packagesForUID, String[] visibleVolIDs);
Narayan Kamath973b4662014-03-31 13:41:26 +0100319
320 /**
Christopher Ferris2980de42017-06-20 16:13:40 -0700321 * Called to do any initialization before starting an application.
322 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800323 static native void nativePreApplicationInit();
Christopher Ferris2980de42017-06-20 16:13:40 -0700324
325 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100326 * Special method to start the system server process. In addition to the
327 * common actions performed in forkAndSpecialize, the pid of the child
328 * process is recorded such that the death of the child process will cause
329 * zygote to exit.
330 *
331 * @param uid the UNIX uid that the new process should setuid() to after
332 * fork()ing and and before spawning any threads.
333 * @param gid the UNIX gid that the new process should setgid() to after
334 * fork()ing and and before spawning any threads.
335 * @param gids null-ok; a list of UNIX gids that the new process should
336 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100337 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100338 * @param rlimits null-ok an array of rlimit tuples, with the second
339 * dimension having a length of 3 and representing
340 * (resource, rlim_cur, rlim_max). These are set via the posix
341 * setrlimit(2) call.
342 * @param permittedCapabilities argument for setcap()
343 * @param effectiveCapabilities argument for setcap()
344 *
345 * @return 0 if this is the child, pid of the child
346 * if this is the parent, or -1 on error.
347 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100348 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100349 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000350 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800351 // Resets nice priority for zygote process.
352 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100353 int pid = nativeForkSystemServer(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800354 uid, gid, gids, runtimeFlags, rlimits,
355 permittedCapabilities, effectiveCapabilities);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100356 // Enable tracing as soon as we enter the system_server.
357 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700358 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100359 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000360 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100361 return pid;
362 }
363
Chris Wailesaa1c9622019-01-10 16:55:32 -0800364 private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100365 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
366
doheon1.lee885b7422016-01-20 13:07:27 +0900367 /**
Robert Sesek54e387d2016-12-02 17:27:50 -0500368 * Lets children of the zygote inherit open file descriptors to this path.
369 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800370 protected static native void nativeAllowFileAcrossFork(String path);
Robert Sesek54e387d2016-12-02 17:27:50 -0500371
372 /**
Martijn Coenen86f08a52019-01-03 16:23:01 +0100373 * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
374 * @param uidGidMin The smallest allowed uid/gid
375 * @param uidGidMax The largest allowed uid/gid
376 */
377 native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax);
378
379 /**
doheon1.lee885b7422016-01-20 13:07:27 +0900380 * Zygote unmount storage space on initializing.
381 * This method is called once.
382 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800383 protected static native void nativeUnmountStorageOnInit();
384
Chris Wailescb0b37f2019-01-11 17:04:41 -0800385 /**
386 * Get socket file descriptors (opened by init) from the environment and
387 * store them for access from native code later.
388 *
389 * @param isPrimary True if this is the zygote process, false if it is zygote_secondary
390 */
391 public static void getSocketFDs(boolean isPrimary) {
392 nativeGetSocketFDs(isPrimary);
393 }
394
Chris Wailesaa1c9622019-01-10 16:55:32 -0800395 protected static native void nativeGetSocketFDs(boolean isPrimary);
396
Chris Wailescb0b37f2019-01-11 17:04:41 -0800397 /**
398 * Initialize the blastula pool and fill it with the desired number of
399 * processes.
400 */
401 protected static Runnable initBlastulaPool() {
402 if (BLASTULA_POOL_ENABLED) {
403 sBlastulaPoolEventFD = getBlastulaPoolEventFD();
404
405 return fillBlastulaPool(null);
406 } else {
407 return null;
408 }
409 }
410
411 /**
412 * Checks to see if the current policy says that pool should be refilled, and spawns new
413 * blastulas if necessary.
414 *
415 * NOTE: This function doesn't need to be guarded with BLASTULA_POOL_ENABLED because it is
416 * only called from contexts that are only valid if the pool is enabled.
417 *
418 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
419 * @return In the Zygote process this function will always return null; in blastula processes
420 * this function will return a Runnable object representing the new application that is
421 * passed up from blastulaMain.
422 */
423 protected static Runnable fillBlastulaPool(int[] sessionSocketRawFDs) {
424 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillBlastulaPool");
425
426 int blastulaPoolCount = getBlastulaPoolCount();
427
428 int numBlastulasToSpawn = sBlastulaPoolMax - blastulaPoolCount;
429
430 if (blastulaPoolCount < sBlastulaPoolMin
431 || numBlastulasToSpawn >= sBlastulaPoolRefillThreshold) {
432
433 // Disable some VM functionality and reset some system values
434 // before forking.
Neil Fuller555d8b72019-01-28 18:29:20 +0000435 ZygoteHooks.preFork();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800436 resetNicePriority();
437
438 while (blastulaPoolCount++ < sBlastulaPoolMax) {
439 Runnable caller = forkBlastula(sessionSocketRawFDs);
440
441 if (caller != null) {
442 return caller;
443 }
444 }
445
446 // Re-enable runtime services for the Zygote. Blastula services
447 // are re-enabled in specializeBlastula.
Neil Fuller555d8b72019-01-28 18:29:20 +0000448 ZygoteHooks.postForkCommon();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800449
450 Log.i("zygote", "Filled the blastula pool. New blastulas: " + numBlastulasToSpawn);
451 }
452
453 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
454
455 return null;
456 }
457
458 /**
459 * @return Number of blastulas currently in the pool
460 */
461 private static int getBlastulaPoolCount() {
462 return nativeGetBlastulaPoolCount();
463 }
464
Chris Wailesaa1c9622019-01-10 16:55:32 -0800465 private static native int nativeGetBlastulaPoolCount();
466
Chris Wailescb0b37f2019-01-11 17:04:41 -0800467 /**
468 * @return The event FD used for communication between the signal handler and the ZygoteServer
469 * poll loop
470 */
471 private static FileDescriptor getBlastulaPoolEventFD() {
472 FileDescriptor fd = new FileDescriptor();
473 fd.setInt$(nativeGetBlastulaPoolEventFD());
474
475 return fd;
476 }
477
Chris Wailesaa1c9622019-01-10 16:55:32 -0800478 private static native int nativeGetBlastulaPoolEventFD();
479
Chris Wailescb0b37f2019-01-11 17:04:41 -0800480 /**
481 * Fork a new blastula process from the zygote
482 *
483 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
484 * @return In the Zygote process this function will always return null; in blastula processes
485 * this function will return a Runnable object representing the new application that is
486 * passed up from blastulaMain.
487 */
488 private static Runnable forkBlastula(int[] sessionSocketRawFDs) {
489 FileDescriptor[] pipeFDs = null;
490
491 try {
492 pipeFDs = Os.pipe2(O_CLOEXEC);
493 } catch (ErrnoException errnoEx) {
494 throw new IllegalStateException("Unable to create blastula pipe.", errnoEx);
495 }
496
497 int pid =
498 nativeForkBlastula(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
499
500 if (pid == 0) {
501 IoUtils.closeQuietly(pipeFDs[0]);
502 return blastulaMain(pipeFDs[1]);
503 } else {
504 // The read-end of the pipe will be closed by the native code.
505 // See removeBlastulaTableEntry();
506 IoUtils.closeQuietly(pipeFDs[1]);
507 return null;
508 }
509 }
510
Chris Wailesaa1c9622019-01-10 16:55:32 -0800511 private static native int nativeForkBlastula(int readPipeFD,
512 int writePipeFD,
513 int[] sessionSocketRawFDs);
514
Chris Wailescb0b37f2019-01-11 17:04:41 -0800515 /**
516 * This function is used by blastulas to wait for specialization requests from the system
517 * server.
518 *
519 * @param writePipe The write end of the reporting pipe used to communicate with the poll loop
520 * of the ZygoteServer.
521 * @return A runnable oject representing the new application.
522 */
523 static Runnable blastulaMain(FileDescriptor writePipe) {
524 final int pid = Process.myPid();
525
526 LocalSocket sessionSocket = null;
527 DataOutputStream blastulaOutputStream = null;
528 Credentials peerCredentials = null;
529 String[] argStrings = null;
530
531 while (true) {
532 try {
533 sessionSocket = sBlastulaPoolSocket.accept();
534
535 BufferedReader blastulaReader =
536 new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
537 blastulaOutputStream =
538 new DataOutputStream(sessionSocket.getOutputStream());
539
540 peerCredentials = sessionSocket.getPeerCredentials();
541
542 argStrings = readArgumentList(blastulaReader);
543
544 if (argStrings != null) {
545 break;
546 } else {
547 Log.e("Blastula", "Truncated command received.");
548 IoUtils.closeQuietly(sessionSocket);
549 }
550 } catch (IOException ioEx) {
551 Log.e("Blastula", "Failed to read command: " + ioEx.getMessage());
552 IoUtils.closeQuietly(sessionSocket);
553 }
554 }
555
556 ZygoteArguments args = new ZygoteArguments(argStrings);
557
558 // TODO (chriswailes): Should this only be run for debug builds?
559 validateBlastulaCommand(args);
560
561 applyUidSecurityPolicy(args, peerCredentials);
562 applyDebuggerSystemProperty(args);
563
564 int[][] rlimits = null;
565
566 if (args.mRLimits != null) {
567 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
568 }
569
570 // This must happen before the SELinux policy for this process is
571 // changed when specializing.
572 try {
573 // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
574 // Process.ProcessStartResult object.
575 blastulaOutputStream.writeInt(pid);
576 } catch (IOException ioEx) {
577 Log.e("Blastula", "Failed to write response to session socket: " + ioEx.getMessage());
578 System.exit(-1);
579 } finally {
580 IoUtils.closeQuietly(sessionSocket);
581 IoUtils.closeQuietly(sBlastulaPoolSocket);
582 }
583
584 try {
585 ByteArrayOutputStream buffer =
586 new ByteArrayOutputStream(Zygote.BLASTULA_MANAGEMENT_MESSAGE_BYTES);
587 DataOutputStream outputStream = new DataOutputStream(buffer);
588
589 // This is written as a long so that the blastula reporting pipe and blastula pool
590 // event FD handlers in ZygoteServer.runSelectLoop can be unified. These two cases
591 // should both send/receive 8 bytes.
592 outputStream.writeLong(pid);
593 outputStream.flush();
594
595 Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
596 } catch (Exception ex) {
597 Log.e("Blastula",
598 String.format("Failed to write PID (%d) to pipe (%d): %s",
599 pid, writePipe.getInt$(), ex.getMessage()));
600 System.exit(-1);
601 } finally {
602 IoUtils.closeQuietly(writePipe);
603 }
604
605 specializeBlastula(args.mUid, args.mGid, args.mGids,
606 args.mRuntimeFlags, rlimits, args.mMountExternal,
607 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
608 args.mInstructionSet, args.mAppDataDir, args.mPackageName,
609 args.mPackagesForUid, args.mVisibleVolIds);
610
611 if (args.mNiceName != null) {
612 Process.setArgV0(args.mNiceName);
613 }
614
615 // End of the postFork event.
616 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
617
618 return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
619 args.mRemainingArgs,
620 null /* classLoader */);
621 }
622
623 private static final String BLASTULA_ERROR_PREFIX = "Invalid command to blastula: ";
624
625 /**
626 * Checks a set of zygote arguments to see if they can be handled by a blastula. Throws an
627 * exception if an invalid arugment is encountered.
628 * @param args The arguments to test
629 */
630 static void validateBlastulaCommand(ZygoteArguments args) {
631 if (args.mAbiListQuery) {
632 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--query-abi-list");
633 } else if (args.mPidQuery) {
634 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--get-pid");
635 } else if (args.mPreloadDefault) {
636 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-default");
637 } else if (args.mPreloadPackage != null) {
638 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-package");
639 } else if (args.mPreloadApp != null) {
640 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-app");
641 } else if (args.mStartChildZygote) {
642 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--start-child-zygote");
643 } else if (args.mApiBlacklistExemptions != null) {
644 throw new IllegalArgumentException(
645 BLASTULA_ERROR_PREFIX + "--set-api-blacklist-exemptions");
646 } else if (args.mHiddenApiAccessLogSampleRate != -1) {
647 throw new IllegalArgumentException(
648 BLASTULA_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
649 } else if (args.mInvokeWith != null) {
650 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--invoke-with");
651 } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
652 throw new ZygoteSecurityException("Client may not specify capabilities: "
653 + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities)
654 + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities));
655 }
656 }
657
658 /**
659 * @return Raw file descriptors for the read-end of blastula reporting pipes.
660 */
661 protected static int[] getBlastulaPipeFDs() {
662 return nativeGetBlastulaPipeFDs();
663 }
664
Chris Wailesaa1c9622019-01-10 16:55:32 -0800665 private static native int[] nativeGetBlastulaPipeFDs();
666
Chris Wailescb0b37f2019-01-11 17:04:41 -0800667 /**
668 * Remove the blastula table entry for the provided process ID.
669 *
670 * @param blastulaPID Process ID of the entry to remove
671 * @return True if the entry was removed; false if it doesn't exist
672 */
673 protected static boolean removeBlastulaTableEntry(int blastulaPID) {
674 return nativeRemoveBlastulaTableEntry(blastulaPID);
675 }
676
Chris Wailesaa1c9622019-01-10 16:55:32 -0800677 private static native boolean nativeRemoveBlastulaTableEntry(int blastulaPID);
678
Chris Wailes2be26262019-01-11 16:14:43 -0800679 /**
680 * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
681 * operation. It may also specify any gid and setgroups() list it chooses.
682 * In factory test mode, it may specify any UID.
683 *
684 * @param args non-null; zygote spawner arguments
685 * @param peer non-null; peer credentials
686 * @throws ZygoteSecurityException
687 */
688 protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
689 throws ZygoteSecurityException {
690
691 if (peer.getUid() == Process.SYSTEM_UID) {
692 /* In normal operation, SYSTEM_UID can only specify a restricted
693 * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
694 */
695 boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
696
697 if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
698 throw new ZygoteSecurityException(
699 "System UID may not launch process with UID < "
700 + Process.SYSTEM_UID);
701 }
702 }
703
704 // If not otherwise specified, uid and gid are inherited from peer
705 if (!args.mUidSpecified) {
706 args.mUid = peer.getUid();
707 args.mUidSpecified = true;
708 }
709 if (!args.mGidSpecified) {
710 args.mGid = peer.getGid();
711 args.mGidSpecified = true;
712 }
713 }
714
715 /**
716 * Applies debugger system properties to the zygote arguments.
717 *
718 * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
719 * the debugger state is specified via the "--enable-jdwp" flag
720 * in the spawn request.
721 *
722 * @param args non-null; zygote spawner args
723 */
724 protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
725 if (RoSystemProperties.DEBUGGABLE) {
726 args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
727 }
728 }
729
730 /**
731 * Applies zygote security policy.
732 * Based on the credentials of the process issuing a zygote command:
733 * <ol>
734 * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
735 * wrapper command.
736 * <li> Any other uid may not specify any invoke-with argument.
737 * </ul>
738 *
739 * @param args non-null; zygote spawner arguments
740 * @param peer non-null; peer credentials
741 * @throws ZygoteSecurityException
742 */
743 protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
744 throws ZygoteSecurityException {
745 int peerUid = peer.getUid();
746
747 if (args.mInvokeWith != null && peerUid != 0
748 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
749 throw new ZygoteSecurityException("Peer is permitted to specify an"
750 + "explicit invoke-with wrapper command only for debuggable"
751 + "applications.");
752 }
753 }
754
755 /**
756 * Applies invoke-with system properties to the zygote arguments.
757 *
758 * @param args non-null; zygote args
759 */
760 protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
761 if (args.mInvokeWith == null && args.mNiceName != null) {
762 String property = "wrap." + args.mNiceName;
763 args.mInvokeWith = SystemProperties.get(property);
764 if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
765 args.mInvokeWith = null;
766 }
767 }
768 }
769
770 /**
771 * Reads an argument list from the provided socket
772 * @return Argument list or null if EOF is reached
773 * @throws IOException passed straight through
774 */
775 static String[] readArgumentList(BufferedReader socketReader) throws IOException {
776
777 /**
778 * See android.os.Process.zygoteSendArgsAndGetPid()
779 * Presently the wire format to the zygote process is:
780 * a) a count of arguments (argc, in essence)
781 * b) a number of newline-separated argument strings equal to count
782 *
783 * After the zygote process reads these it will write the pid of
784 * the child or -1 on failure.
785 */
786
787 int argc;
788
789 try {
790 String argc_string = socketReader.readLine();
791
792 if (argc_string == null) {
793 // EOF reached.
794 return null;
795 }
796 argc = Integer.parseInt(argc_string);
797
798 } catch (NumberFormatException ex) {
799 Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
800 throw new IOException("Invalid wire format");
801 }
802
803 // See bug 1092107: large argc can be used for a DOS attack
804 if (argc > MAX_ZYGOTE_ARGC) {
805 throw new IOException("Max arg count exceeded");
806 }
807
808 String[] args = new String[argc];
809 for (int arg_index = 0; arg_index < argc; arg_index++) {
810 args[arg_index] = socketReader.readLine();
811 if (args[arg_index] == null) {
812 // We got an unexpected EOF.
813 throw new IOException("Truncated request");
814 }
815 }
816
817 return args;
818 }
819
Chris Wailescb0b37f2019-01-11 17:04:41 -0800820 /**
821 * Creates a managed object representing the Blastula pool socket that has
822 * already been initialized and bound by init.
823 *
824 * TODO (chriswailes): Move the name selection logic into this function.
825 *
826 * @throws RuntimeException when open fails
827 */
828 static void createBlastulaSocket(String socketName) {
829 if (BLASTULA_POOL_ENABLED && sBlastulaPoolSocket == null) {
830 sBlastulaPoolSocket = createManagedSocketFromInitSocket(socketName);
831 }
832 }
833
834 /**
835 * Creates a managed LocalServerSocket object using a file descriptor
836 * created by an init.rc script. The init scripts that specify the
837 * sockets name can be found in system/core/rootdir. The socket is bound
838 * to the file system in the /dev/sockets/ directory, and the file
839 * descriptor is shared via the ANDROID_SOCKET_<socketName> environment
840 * variable.
841 */
842 static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
843 int fileDesc;
844 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
845
846 try {
847 String env = System.getenv(fullSocketName);
848 fileDesc = Integer.parseInt(env);
849 } catch (RuntimeException ex) {
850 throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
851 }
852
853 try {
854 FileDescriptor fd = new FileDescriptor();
855 fd.setInt$(fileDesc);
856 return new LocalServerSocket(fd);
857 } catch (IOException ex) {
858 throw new RuntimeException(
859 "Error building socket from file descriptor: " + fileDesc, ex);
860 }
861 }
doheon1.lee885b7422016-01-20 13:07:27 +0900862
Orion Hodson46724e72018-10-19 13:05:33 +0100863 private static void callPostForkSystemServerHooks() {
864 // SystemServer specific post fork hooks run before child post fork hooks.
Neil Fuller555d8b72019-01-28 18:29:20 +0000865 ZygoteHooks.postForkSystemServer();
Orion Hodson46724e72018-10-19 13:05:33 +0100866 }
867
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100868 private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
Robert Sesekd0a190df2018-02-12 18:46:01 -0500869 boolean isZygote, String instructionSet) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000870 ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
Narayan Kamath973b4662014-03-31 13:41:26 +0100871 }
872
Narayan Kamathb49996d2017-02-06 20:24:08 +0000873 /**
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800874 * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
875 * or nice value 0). This updates both the priority value in java.lang.Thread and
876 * the nice value (setpriority).
Narayan Kamathb49996d2017-02-06 20:24:08 +0000877 */
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800878 static void resetNicePriority() {
879 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
880 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100881
882 /**
883 * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
884 * This method throws a runtime exception if exec() failed, otherwise, this
885 * method never returns.
886 *
887 * @param command The shell command to execute.
888 */
889 public static void execShell(String command) {
890 String[] args = { "/system/bin/sh", "-c", command };
891 try {
Elliott Hughes860c5912014-04-28 19:19:13 -0700892 Os.execv(args[0], args);
Narayan Kamath973b4662014-03-31 13:41:26 +0100893 } catch (ErrnoException e) {
894 throw new RuntimeException(e);
895 }
896 }
897
898 /**
899 * Appends quotes shell arguments to the specified string builder.
900 * The arguments are quoted using single-quotes, escaped if necessary,
901 * prefixed with a space, and appended to the command.
902 *
903 * @param command A string builder for the shell command being constructed.
904 * @param args An array of argument strings to be quoted and appended to the command.
905 * @see #execShell(String)
906 */
907 public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
908 for (String arg : args) {
909 command.append(" '").append(arg.replace("'", "'\\''")).append("'");
910 }
911 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100912}