blob: 46d9aac24d4f5d1a78df231bbc1ca6968ef1ba60 [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
Martijn Coenen4b988162019-01-28 13:58:45 +010023import android.content.pm.ApplicationInfo;
Chris Wailes2be26262019-01-11 16:14:43 -080024import android.net.Credentials;
Chris Wailescb0b37f2019-01-11 17:04:41 -080025import android.net.LocalServerSocket;
26import android.net.LocalSocket;
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -070027import android.os.Build;
Chris Wailes2be26262019-01-11 16:14:43 -080028import android.os.FactoryTest;
Jeff Sharkeyace874b2017-09-07 15:27:33 -060029import android.os.IVold;
Chris Wailes2be26262019-01-11 16:14:43 -080030import android.os.Process;
31import android.os.SystemProperties;
Narayan Kamathfbb32f62015-06-12 15:34:35 +010032import android.os.Trace;
Mathieu Chartier0bccbf72019-01-30 15:56:17 -080033import android.provider.DeviceConfig;
Elliott Hughes860c5912014-04-28 19:19:13 -070034import android.system.ErrnoException;
35import android.system.Os;
Chris Wailes2be26262019-01-11 16:14:43 -080036import android.util.Log;
Narayan Kamath973b4662014-03-31 13:41:26 +010037
Jeff Sharkeyace874b2017-09-07 15:27:33 -060038import dalvik.system.ZygoteHooks;
Tobias Sargeantb9679dc2016-01-19 16:34:54 +000039
Chris Wailescb0b37f2019-01-11 17:04:41 -080040import libcore.io.IoUtils;
41
Chris Wailes2be26262019-01-11 16:14:43 -080042import java.io.BufferedReader;
Chris Wailescb0b37f2019-01-11 17:04:41 -080043import java.io.ByteArrayOutputStream;
44import java.io.DataOutputStream;
45import java.io.FileDescriptor;
Chris Wailes2be26262019-01-11 16:14:43 -080046import java.io.IOException;
Chris Wailescb0b37f2019-01-11 17:04:41 -080047import java.io.InputStreamReader;
Chris Wailes2be26262019-01-11 16:14:43 -080048
Narayan Kamath973b4662014-03-31 13:41:26 +010049/** @hide */
50public final class Zygote {
51 /*
Nicolas Geoffray81edac42017-09-07 14:13:29 +010052 * Bit values for "runtimeFlags" argument. The definitions are duplicated
Narayan Kamath973b4662014-03-31 13:41:26 +010053 * in the native code.
54 */
55
56 /** enable debugging over JDWP */
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000057 public static final int DEBUG_ENABLE_JDWP = 1;
Narayan Kamath973b4662014-03-31 13:41:26 +010058 /** enable JNI checks */
59 public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1;
60 /** enable Java programming language "assert" statements */
61 public static final int DEBUG_ENABLE_ASSERT = 1 << 2;
Mathieu Chartier7a490282015-03-17 09:51:36 -070062 /** disable the AOT compiler and JIT */
Narayan Kamath973b4662014-03-31 13:41:26 +010063 public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3;
64 /** Enable logging of third-party JNI activity. */
65 public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
David Srbecky065075e2015-05-28 17:16:09 +010066 /** Force generation of native debugging information. */
Nicolas Geoffray9abbf452015-11-05 11:29:42 +000067 public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 5;
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000068 /** Always use JIT-ed code. */
69 public static final int DEBUG_ALWAYS_JIT = 1 << 6;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000070 /** Make the code native debuggable by turning off some optimizations. */
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000071 public static final int DEBUG_NATIVE_DEBUGGABLE = 1 << 7;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000072 /** Make the code Java debuggable by turning off some optimizations. */
73 public static final int DEBUG_JAVA_DEBUGGABLE = 1 << 8;
Mathieu Chartier7a490282015-03-17 09:51:36 -070074
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010075 /** Turn off the verifier. */
76 public static final int DISABLE_VERIFIER = 1 << 9;
77 /** Only use oat files located in /system. Otherwise use dex/jar/apk . */
78 public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
David Srbecky156ed922018-01-30 14:37:37 +000079 /** Force generation of native debugging information for backtraces. */
Mathew Inwood16073b82018-03-23 10:05:01 +000080 public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11;
81 /**
82 * Hidden API access restrictions. This is a mask for bits representing the API enforcement
83 * policy, defined by {@code @ApplicationInfo.HiddenApiEnforcementPolicy}.
84 */
85 public static final int API_ENFORCEMENT_POLICY_MASK = (1 << 12) | (1 << 13);
86 /**
87 * Bit shift for use with {@link #API_ENFORCEMENT_POLICY_MASK}.
88 *
89 * (flags & API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT gives
90 * @ApplicationInfo.ApiEnforcementPolicy values.
91 */
92 public static final int API_ENFORCEMENT_POLICY_SHIFT =
93 Integer.numberOfTrailingZeros(API_ENFORCEMENT_POLICY_MASK);
Calin Juravle8eb891b2018-05-03 19:51:18 -070094 /**
95 * Enable system server ART profiling.
96 */
97 public static final int PROFILE_SYSTEM_SERVER = 1 << 14;
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010098
Yabin Cui4d8546d2019-01-29 16:29:20 -080099 /**
100 * Enable profiling from shell.
101 */
102 public static final int PROFILE_FROM_SHELL = 1 << 15;
103
Mathieu Chartierced7e082019-02-04 13:28:36 -0800104 /*
105 * Enable using the ART app image startup cache
106 */
107 public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
108
Narayan Kamath973b4662014-03-31 13:41:26 +0100109 /** No external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600110 public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700111 /** Default external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600112 public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700113 /** Read-only external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600114 public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700115 /** Read-write external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600116 public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800117 /**
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800118 * Mount mode for apps that are already installed on the device before the isolated_storage
119 * feature is enabled.
120 */
121 public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY;
122 /**
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800123 * Mount mode for package installers which should give them access to
124 * all obb dirs in addition to their package sandboxes
125 */
126 public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700127 /** Read-write external storage should be mounted instead of package sandbox */
128 public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL;
Narayan Kamath973b4662014-03-31 13:41:26 +0100129
Chris Wailes7e797b62019-02-22 18:29:22 -0800130 /** Number of bytes sent to the Zygote over USAP pipes or the pool event FD */
131 public static final int USAP_MANAGEMENT_MESSAGE_BYTES = 8;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800132
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800133 /**
Robert Sesekd0a190df2018-02-12 18:46:01 -0500134 * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
135 * in the abstract socket namespace. This socket name is what the new child zygote
136 * should listen for connections on.
137 */
138 public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
139
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100140 /**
141 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
142 * requested ABI for the child Zygote.
143 */
144 public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list=";
145
Martijn Coenen86f08a52019-01-03 16:23:01 +0100146 /**
147 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
148 * start of the UID range the children of the Zygote may setuid()/setgid() to. This
149 * will be enforced with a seccomp filter.
150 */
151 public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start=";
152
153 /**
154 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
155 * end of the UID range the children of the Zygote may setuid()/setgid() to. This
156 * will be enforced with a seccomp filter.
157 */
158 public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end=";
159
Chris Wailescb0b37f2019-01-11 17:04:41 -0800160 /** Prefix prepended to socket names created by init */
161 private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
162
163 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800164 * The duration to wait before re-checking Zygote related system properties.
165 *
Chris Wailesdb132a32019-02-20 10:49:27 -0800166 * One minute in milliseconds.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800167 */
Chris Wailesdb132a32019-02-20 10:49:27 -0800168 public static final long PROPERTY_CHECK_INTERVAL = 60000;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800169
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800170 /**
171 * @hide for internal use only
172 */
173 public static final int SOCKET_BUFFER_SIZE = 256;
174
Chris Wailes2be26262019-01-11 16:14:43 -0800175 /** a prototype instance for a future List.toArray() */
176 protected static final int[][] INT_ARRAY_2D = new int[0][0];
177
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800178 /**
179 * @hide for internal use only.
180 */
181 public static final String PRIMARY_SOCKET_NAME = "zygote";
182
183 /**
184 * @hide for internal use only.
185 */
186 public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
187
188 /**
189 * @hide for internal use only
190 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800191 public static final String USAP_POOL_PRIMARY_SOCKET_NAME = "usap_pool_primary";
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800192
193 /**
194 * @hide for internal use only
195 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800196 public static final String USAP_POOL_SECONDARY_SOCKET_NAME = "usap_pool_secondary";
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800197
Narayan Kamath973b4662014-03-31 13:41:26 +0100198 private Zygote() {}
199
200 /**
201 * Forks a new VM instance. The current VM must have been started
202 * with the -Xzygote flag. <b>NOTE: new instance keeps all
203 * root capabilities. The new process is expected to call capset()</b>.
204 *
205 * @param uid the UNIX uid that the new process should setuid() to after
206 * fork()ing and and before spawning any threads.
207 * @param gid the UNIX gid that the new process should setgid() to after
208 * fork()ing and and before spawning any threads.
209 * @param gids null-ok; a list of UNIX gids that the new process should
210 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100211 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100212 * @param rlimits null-ok an array of rlimit tuples, with the second
213 * dimension having a length of 3 and representing
214 * (resource, rlim_cur, rlim_max). These are set via the posix
215 * setrlimit(2) call.
216 * @param seInfo null-ok a string specifying SELinux information for
217 * the new process.
218 * @param niceName null-ok a string specifying the process name.
219 * @param fdsToClose an array of ints, holding one or more POSIX
220 * file descriptor numbers that are to be closed by the child
221 * (and replaced by /dev/null) after forking. An integer value
222 * of -1 in any entry in the array means "ignore this one".
Andreas Gampe8dfa1782017-01-05 12:45:58 -0800223 * @param fdsToIgnore null-ok an array of ints, either null or holding
224 * one or more POSIX file descriptor numbers that are to be ignored
225 * in the file descriptor table check.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500226 * @param startChildZygote if true, the new child process will itself be a
227 * new zygote process.
Andreas Gampeaec67dc2014-09-02 21:23:06 -0700228 * @param instructionSet null-ok the instruction set to use.
jgu212eacd062014-09-10 06:55:07 -0400229 * @param appDataDir null-ok the data directory of the app.
Narayan Kamath973b4662014-03-31 13:41:26 +0100230 *
231 * @return 0 if this is the child, pid of the child
232 * if this is the parent, or -1 on error.
233 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100234 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700235 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
236 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700237 String packageName, String[] packagesForUID, String sandboxId, int targetSdkVersion) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000238 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800239 // Resets nice priority for zygote process.
240 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100241 int pid = nativeForkAndSpecialize(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800242 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
243 fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800244 packagesForUID, sandboxId);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100245 // Enable tracing as soon as possible for the child process.
246 if (pid == 0) {
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700247 Zygote.disableExecuteOnly(targetSdkVersion);
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700248 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100249
250 // Note that this event ends at the end of handleChildProc,
251 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
252 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000253 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100254 return pid;
255 }
256
Chris Wailesaa1c9622019-01-10 16:55:32 -0800257 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
258 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
259 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800260 String appDataDir, String packageName, String[] packagesForUID,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800261 String sandboxId);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800262
Chris Wailescb0b37f2019-01-11 17:04:41 -0800263 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800264 * Specialize an unspecialized app process. The current VM must have been started
Chris Wailescb0b37f2019-01-11 17:04:41 -0800265 * with the -Xzygote flag.
266 *
267 * @param uid The UNIX uid that the new process should setuid() to before spawning any threads
268 * @param gid The UNIX gid that the new process should setgid() to before spawning any threads
269 * @param gids null-ok; A list of UNIX gids that the new process should
270 * setgroups() to before spawning any threads
271 * @param runtimeFlags Bit flags that enable ART features
272 * @param rlimits null-ok An array of rlimit tuples, with the second
273 * dimension having a length of 3 and representing
274 * (resource, rlim_cur, rlim_max). These are set via the posix
275 * setrlimit(2) call.
276 * @param seInfo null-ok A string specifying SELinux information for
277 * the new process.
278 * @param niceName null-ok A string specifying the process name.
279 * @param startChildZygote If true, the new child process will itself be a
280 * new zygote process.
281 * @param instructionSet null-ok The instruction set to use.
282 * @param appDataDir null-ok The data directory of the app.
283 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800284 public static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
Chris Wailescb0b37f2019-01-11 17:04:41 -0800285 int[][] rlimits, int mountExternal, String seInfo, String niceName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800286 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800287 String[] packagesForUID, String sandboxId) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800288 nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
Chris Wailescb0b37f2019-01-11 17:04:41 -0800289 niceName, startChildZygote, instructionSet, appDataDir,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800290 packageName, packagesForUID, sandboxId);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800291
292 // Enable tracing as soon as possible for the child process.
293 Trace.setTracingEnabled(true, runtimeFlags);
294
295 // Note that this event ends at the end of handleChildProc.
296 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
297
298 /*
299 * This is called here (instead of after the fork but before the specialize) to maintain
300 * consistancy with the code paths for forkAndSpecialize.
301 *
302 * TODO (chriswailes): Look into moving this to immediately after the fork.
303 */
Neil Fuller555d8b72019-01-28 18:29:20 +0000304 ZygoteHooks.postForkCommon();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800305 }
306
Chris Wailes7e797b62019-02-22 18:29:22 -0800307 private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800308 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
309 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800310 String[] packagesForUID, String sandboxId);
Narayan Kamath973b4662014-03-31 13:41:26 +0100311
312 /**
Christopher Ferris2980de42017-06-20 16:13:40 -0700313 * Called to do any initialization before starting an application.
314 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800315 static native void nativePreApplicationInit();
Christopher Ferris2980de42017-06-20 16:13:40 -0700316
317 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100318 * Special method to start the system server process. In addition to the
319 * common actions performed in forkAndSpecialize, the pid of the child
320 * process is recorded such that the death of the child process will cause
321 * zygote to exit.
322 *
323 * @param uid the UNIX uid that the new process should setuid() to after
324 * fork()ing and and before spawning any threads.
325 * @param gid the UNIX gid that the new process should setgid() to after
326 * fork()ing and and before spawning any threads.
327 * @param gids null-ok; a list of UNIX gids that the new process should
328 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100329 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100330 * @param rlimits null-ok an array of rlimit tuples, with the second
331 * dimension having a length of 3 and representing
332 * (resource, rlim_cur, rlim_max). These are set via the posix
333 * setrlimit(2) call.
334 * @param permittedCapabilities argument for setcap()
335 * @param effectiveCapabilities argument for setcap()
336 *
337 * @return 0 if this is the child, pid of the child
338 * if this is the parent, or -1 on error.
339 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100340 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100341 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000342 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800343 // Resets nice priority for zygote process.
344 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100345 int pid = nativeForkSystemServer(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800346 uid, gid, gids, runtimeFlags, rlimits,
347 permittedCapabilities, effectiveCapabilities);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100348 // Enable tracing as soon as we enter the system_server.
349 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700350 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100351 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000352 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100353 return pid;
354 }
355
Chris Wailesaa1c9622019-01-10 16:55:32 -0800356 private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100357 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
358
doheon1.lee885b7422016-01-20 13:07:27 +0900359 /**
Robert Sesek54e387d2016-12-02 17:27:50 -0500360 * Lets children of the zygote inherit open file descriptors to this path.
361 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800362 protected static native void nativeAllowFileAcrossFork(String path);
Robert Sesek54e387d2016-12-02 17:27:50 -0500363
364 /**
Martijn Coenen4b988162019-01-28 13:58:45 +0100365 * Lets children of the zygote inherit open file descriptors that belong to the
366 * ApplicationInfo that is passed in.
367 *
368 * @param appInfo ApplicationInfo of the application
369 */
370 protected static void allowAppFilesAcrossFork(ApplicationInfo appInfo) {
Torne (Richard Coles)1aaae102019-03-01 15:02:29 -0500371 for (String path : appInfo.getAllApkPaths()) {
372 Zygote.nativeAllowFileAcrossFork(path);
Martijn Coenen4b988162019-01-28 13:58:45 +0100373 }
374 }
375
376 /**
Martijn Coenen86f08a52019-01-03 16:23:01 +0100377 * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
378 * @param uidGidMin The smallest allowed uid/gid
379 * @param uidGidMax The largest allowed uid/gid
380 */
381 native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax);
382
383 /**
Chris Wailes6d482d542019-04-03 13:00:52 -0700384 * Initialize the native state of the Zygote. This inclues
385 * - Fetching socket FDs from the environment
386 * - Initializing security properties
387 * - Unmounting storage as appropriate
388 * - Loading necessary performance profile information
Chris Wailescb0b37f2019-01-11 17:04:41 -0800389 *
390 * @param isPrimary True if this is the zygote process, false if it is zygote_secondary
391 */
Chris Wailes6d482d542019-04-03 13:00:52 -0700392 static void initNativeState(boolean isPrimary) {
393 nativeInitNativeState(isPrimary);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800394 }
395
Chris Wailes6d482d542019-04-03 13:00:52 -0700396 protected static native void nativeInitNativeState(boolean isPrimary);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800397
Chris Wailescb0b37f2019-01-11 17:04:41 -0800398 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800399 * Returns the raw string value of a system property.
400 *
401 * Note that Device Config is not available without an application so SystemProperties is used
402 * instead.
403 *
404 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
405 * function to fetch it.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800406 */
Chris Wailesfe3a3482019-03-13 14:38:04 -0700407 public static String getConfigurationProperty(String propertyName, String defaultValue) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800408 return SystemProperties.get(
409 String.join(".",
410 "persist.device_config",
Matt Papee9b680a2019-03-05 15:53:13 -0800411 DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800412 propertyName),
413 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800414 }
415
Chris Wailes7e797b62019-02-22 18:29:22 -0800416 protected static void emptyUsapPool() {
417 nativeEmptyUsapPool();
Chris Wailesae937142019-01-24 12:57:33 -0800418 }
419
Chris Wailes7e797b62019-02-22 18:29:22 -0800420 private static native void nativeEmptyUsapPool();
Chris Wailesae937142019-01-24 12:57:33 -0800421
Chris Wailescb0b37f2019-01-11 17:04:41 -0800422 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800423 * Returns the value of a system property converted to a boolean using specific logic.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800424 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800425 * Note that Device Config is not available without an application so SystemProperties is used
426 * instead.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800427 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800428 * @see SystemProperties.getBoolean
429 *
430 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
431 * function to fetch it.
Chris Wailesfe3a3482019-03-13 14:38:04 -0700432 * TODO (chriswailes): Move into ZygoteConfig.java once the necessary CL lands (go/ag/6580627)
Chris Wailescb0b37f2019-01-11 17:04:41 -0800433 */
Chris Wailesfe3a3482019-03-13 14:38:04 -0700434 public static boolean getConfigurationPropertyBoolean(
435 String propertyName, Boolean defaultValue) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800436 return SystemProperties.getBoolean(
437 String.join(".",
438 "persist.device_config",
Matt Papee9b680a2019-03-05 15:53:13 -0800439 DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800440 propertyName),
441 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800442 }
443
444 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800445 * @return Number of unspecialized app processes currently in the pool
Chris Wailescb0b37f2019-01-11 17:04:41 -0800446 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800447 static int getUsapPoolCount() {
448 return nativeGetUsapPoolCount();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800449 }
450
Chris Wailes7e797b62019-02-22 18:29:22 -0800451 private static native int nativeGetUsapPoolCount();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800452
Chris Wailescb0b37f2019-01-11 17:04:41 -0800453 /**
454 * @return The event FD used for communication between the signal handler and the ZygoteServer
455 * poll loop
456 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800457 static FileDescriptor getUsapPoolEventFD() {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800458 FileDescriptor fd = new FileDescriptor();
Chris Wailes7e797b62019-02-22 18:29:22 -0800459 fd.setInt$(nativeGetUsapPoolEventFD());
Chris Wailescb0b37f2019-01-11 17:04:41 -0800460
461 return fd;
462 }
463
Chris Wailes7e797b62019-02-22 18:29:22 -0800464 private static native int nativeGetUsapPoolEventFD();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800465
Chris Wailescb0b37f2019-01-11 17:04:41 -0800466 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800467 * Fork a new unspecialized app process from the zygote
Chris Wailescb0b37f2019-01-11 17:04:41 -0800468 *
469 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
Chris Wailes7e797b62019-02-22 18:29:22 -0800470 * @return In the Zygote process this function will always return null; in unspecialized app
471 * processes this function will return a Runnable object representing the new
472 * application that is passed up from usapMain.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800473 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800474 static Runnable forkUsap(LocalServerSocket usapPoolSocket,
475 int[] sessionSocketRawFDs) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800476 FileDescriptor[] pipeFDs = null;
477
478 try {
479 pipeFDs = Os.pipe2(O_CLOEXEC);
480 } catch (ErrnoException errnoEx) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800481 throw new IllegalStateException("Unable to create USAP pipe.", errnoEx);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800482 }
483
484 int pid =
Chris Wailes7e797b62019-02-22 18:29:22 -0800485 nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800486
487 if (pid == 0) {
488 IoUtils.closeQuietly(pipeFDs[0]);
Chris Wailes7e797b62019-02-22 18:29:22 -0800489 return usapMain(usapPoolSocket, pipeFDs[1]);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800490 } else {
491 // The read-end of the pipe will be closed by the native code.
Chris Wailes7e797b62019-02-22 18:29:22 -0800492 // See removeUsapTableEntry();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800493 IoUtils.closeQuietly(pipeFDs[1]);
494 return null;
495 }
496 }
497
Chris Wailes7e797b62019-02-22 18:29:22 -0800498 private static native int nativeForkUsap(int readPipeFD,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800499 int writePipeFD,
500 int[] sessionSocketRawFDs);
501
Chris Wailescb0b37f2019-01-11 17:04:41 -0800502 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800503 * This function is used by unspecialized app processes to wait for specialization requests from
504 * the system server.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800505 *
506 * @param writePipe The write end of the reporting pipe used to communicate with the poll loop
507 * of the ZygoteServer.
508 * @return A runnable oject representing the new application.
509 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800510 private static Runnable usapMain(LocalServerSocket usapPoolSocket,
511 FileDescriptor writePipe) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800512 final int pid = Process.myPid();
Chris Wailes07530402019-03-25 18:01:30 -0700513 Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800514
515 LocalSocket sessionSocket = null;
Chris Wailes7e797b62019-02-22 18:29:22 -0800516 DataOutputStream usapOutputStream = null;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800517 Credentials peerCredentials = null;
Chris Wailesae937142019-01-24 12:57:33 -0800518 ZygoteArguments args = null;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800519
Chris Wailes35fdbc52019-04-17 17:55:48 -0700520 // Load resources
521 ZygoteInit.nativePreloadOpenGL();
522
Chris Wailescb0b37f2019-01-11 17:04:41 -0800523 while (true) {
524 try {
Chris Wailes7e797b62019-02-22 18:29:22 -0800525 sessionSocket = usapPoolSocket.accept();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800526
Chris Wailes7e797b62019-02-22 18:29:22 -0800527 BufferedReader usapReader =
Chris Wailescb0b37f2019-01-11 17:04:41 -0800528 new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
Chris Wailes7e797b62019-02-22 18:29:22 -0800529 usapOutputStream =
Chris Wailescb0b37f2019-01-11 17:04:41 -0800530 new DataOutputStream(sessionSocket.getOutputStream());
531
532 peerCredentials = sessionSocket.getPeerCredentials();
533
Chris Wailes7e797b62019-02-22 18:29:22 -0800534 String[] argStrings = readArgumentList(usapReader);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800535
536 if (argStrings != null) {
Chris Wailesae937142019-01-24 12:57:33 -0800537 args = new ZygoteArguments(argStrings);
538
539 // TODO (chriswailes): Should this only be run for debug builds?
Chris Wailes7e797b62019-02-22 18:29:22 -0800540 validateUsapCommand(args);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800541 break;
542 } else {
Chris Wailes7e797b62019-02-22 18:29:22 -0800543 Log.e("USAP", "Truncated command received.");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800544 IoUtils.closeQuietly(sessionSocket);
545 }
Chris Wailesae937142019-01-24 12:57:33 -0800546 } catch (Exception ex) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800547 Log.e("USAP", ex.getMessage());
Chris Wailescb0b37f2019-01-11 17:04:41 -0800548 IoUtils.closeQuietly(sessionSocket);
549 }
550 }
551
Chris Wailescb0b37f2019-01-11 17:04:41 -0800552 applyUidSecurityPolicy(args, peerCredentials);
553 applyDebuggerSystemProperty(args);
554
555 int[][] rlimits = null;
556
557 if (args.mRLimits != null) {
558 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
559 }
560
561 // This must happen before the SELinux policy for this process is
562 // changed when specializing.
563 try {
564 // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
565 // Process.ProcessStartResult object.
Chris Wailes7e797b62019-02-22 18:29:22 -0800566 usapOutputStream.writeInt(pid);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800567 } catch (IOException ioEx) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800568 Log.e("USAP", "Failed to write response to session socket: " + ioEx.getMessage());
Chris Wailescb0b37f2019-01-11 17:04:41 -0800569 System.exit(-1);
570 } finally {
571 IoUtils.closeQuietly(sessionSocket);
Chris Wailesb63a00a2019-04-10 15:55:29 -0700572
573 try {
574 // This socket is closed using Os.close due to an issue with the implementation of
575 // LocalSocketImp.close. Because the raw FD is created by init and then loaded from
576 // an environment variable (as opposed to being created by the LocalSocketImpl
577 // itself) the current implementation will not actually close the underlying FD.
578 //
579 // See b/130309968 for discussion of this issue.
580 Os.close(usapPoolSocket.getFileDescriptor());
581 } catch (ErrnoException ex) {
582 Log.e("USAP", "Failed to close USAP pool socket: " + ex.getMessage());
583 }
Chris Wailescb0b37f2019-01-11 17:04:41 -0800584 }
585
586 try {
587 ByteArrayOutputStream buffer =
Chris Wailes7e797b62019-02-22 18:29:22 -0800588 new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800589 DataOutputStream outputStream = new DataOutputStream(buffer);
590
Chris Wailes7e797b62019-02-22 18:29:22 -0800591 // This is written as a long so that the USAP reporting pipe and USAP pool event FD
592 // handlers in ZygoteServer.runSelectLoop can be unified. These two cases should both
593 // send/receive 8 bytes.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800594 outputStream.writeLong(pid);
595 outputStream.flush();
596
597 Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
598 } catch (Exception ex) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800599 Log.e("USAP",
Chris Wailescb0b37f2019-01-11 17:04:41 -0800600 String.format("Failed to write PID (%d) to pipe (%d): %s",
601 pid, writePipe.getInt$(), ex.getMessage()));
602 System.exit(-1);
603 } finally {
604 IoUtils.closeQuietly(writePipe);
605 }
606
Chris Wailes7e797b62019-02-22 18:29:22 -0800607 specializeAppProcess(args.mUid, args.mGid, args.mGids,
Chris Wailescb0b37f2019-01-11 17:04:41 -0800608 args.mRuntimeFlags, rlimits, args.mMountExternal,
609 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
610 args.mInstructionSet, args.mAppDataDir, args.mPackageName,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800611 args.mPackagesForUid, args.mSandboxId);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800612
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700613 disableExecuteOnly(args.mTargetSdkVersion);
614
Chris Wailescb0b37f2019-01-11 17:04:41 -0800615 if (args.mNiceName != null) {
616 Process.setArgV0(args.mNiceName);
617 }
618
619 // End of the postFork event.
620 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
621
622 return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
623 args.mRemainingArgs,
624 null /* classLoader */);
625 }
626
Chris Wailes7e797b62019-02-22 18:29:22 -0800627 private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: ";
Chris Wailescb0b37f2019-01-11 17:04:41 -0800628
629 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800630 * Checks a set of zygote arguments to see if they can be handled by a USAP. Throws an
Chris Wailescb0b37f2019-01-11 17:04:41 -0800631 * exception if an invalid arugment is encountered.
632 * @param args The arguments to test
633 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800634 private static void validateUsapCommand(ZygoteArguments args) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800635 if (args.mAbiListQuery) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800636 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--query-abi-list");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800637 } else if (args.mPidQuery) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800638 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--get-pid");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800639 } else if (args.mPreloadDefault) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800640 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-default");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800641 } else if (args.mPreloadPackage != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800642 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-package");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800643 } else if (args.mPreloadApp != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800644 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-app");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800645 } else if (args.mStartChildZygote) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800646 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800647 } else if (args.mApiBlacklistExemptions != null) {
648 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800649 USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800650 } else if (args.mHiddenApiAccessLogSampleRate != -1) {
651 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800652 USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
Andrei Oneae8e150d2019-02-18 18:27:11 +0000653 } else if (args.mHiddenApiAccessStatslogSampleRate != -1) {
654 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800655 USAP_ERROR_PREFIX + "--hidden-api-statslog-sampling-rate=");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800656 } else if (args.mInvokeWith != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800657 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--invoke-with");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800658 } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
659 throw new ZygoteSecurityException("Client may not specify capabilities: "
660 + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities)
661 + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities));
662 }
663 }
664
665 /**
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700666 * Mark execute-only segments of libraries read+execute for apps with targetSdkVersion<Q.
667 */
668 protected static void disableExecuteOnly(int targetSdkVersion) {
669 if ((targetSdkVersion < Build.VERSION_CODES.Q) && !nativeDisableExecuteOnly()) {
670 Log.e("Zygote", "Failed to set libraries to read+execute.");
671 }
672 }
673
674 private static native boolean nativeDisableExecuteOnly();
675
676 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800677 * @return Raw file descriptors for the read-end of USAP reporting pipes.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800678 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800679 protected static int[] getUsapPipeFDs() {
680 return nativeGetUsapPipeFDs();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800681 }
682
Chris Wailes7e797b62019-02-22 18:29:22 -0800683 private static native int[] nativeGetUsapPipeFDs();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800684
Chris Wailescb0b37f2019-01-11 17:04:41 -0800685 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800686 * Remove the USAP table entry for the provided process ID.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800687 *
Chris Wailes7e797b62019-02-22 18:29:22 -0800688 * @param usapPID Process ID of the entry to remove
Chris Wailescb0b37f2019-01-11 17:04:41 -0800689 * @return True if the entry was removed; false if it doesn't exist
690 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800691 protected static boolean removeUsapTableEntry(int usapPID) {
692 return nativeRemoveUsapTableEntry(usapPID);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800693 }
694
Chris Wailes7e797b62019-02-22 18:29:22 -0800695 private static native boolean nativeRemoveUsapTableEntry(int usapPID);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800696
Chris Wailes2be26262019-01-11 16:14:43 -0800697 /**
698 * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
699 * operation. It may also specify any gid and setgroups() list it chooses.
700 * In factory test mode, it may specify any UID.
701 *
702 * @param args non-null; zygote spawner arguments
703 * @param peer non-null; peer credentials
704 * @throws ZygoteSecurityException
705 */
706 protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
707 throws ZygoteSecurityException {
708
709 if (peer.getUid() == Process.SYSTEM_UID) {
710 /* In normal operation, SYSTEM_UID can only specify a restricted
711 * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
712 */
713 boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
714
715 if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
716 throw new ZygoteSecurityException(
717 "System UID may not launch process with UID < "
718 + Process.SYSTEM_UID);
719 }
720 }
721
722 // If not otherwise specified, uid and gid are inherited from peer
723 if (!args.mUidSpecified) {
724 args.mUid = peer.getUid();
725 args.mUidSpecified = true;
726 }
727 if (!args.mGidSpecified) {
728 args.mGid = peer.getGid();
729 args.mGidSpecified = true;
730 }
731 }
732
733 /**
734 * Applies debugger system properties to the zygote arguments.
735 *
736 * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
737 * the debugger state is specified via the "--enable-jdwp" flag
738 * in the spawn request.
739 *
740 * @param args non-null; zygote spawner args
741 */
742 protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
743 if (RoSystemProperties.DEBUGGABLE) {
744 args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
745 }
746 }
747
748 /**
749 * Applies zygote security policy.
750 * Based on the credentials of the process issuing a zygote command:
751 * <ol>
752 * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
753 * wrapper command.
754 * <li> Any other uid may not specify any invoke-with argument.
755 * </ul>
756 *
757 * @param args non-null; zygote spawner arguments
758 * @param peer non-null; peer credentials
759 * @throws ZygoteSecurityException
760 */
761 protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
762 throws ZygoteSecurityException {
763 int peerUid = peer.getUid();
764
765 if (args.mInvokeWith != null && peerUid != 0
766 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
Chris Wailesae937142019-01-24 12:57:33 -0800767 throw new ZygoteSecurityException("Peer is permitted to specify an "
768 + "explicit invoke-with wrapper command only for debuggable "
Chris Wailes2be26262019-01-11 16:14:43 -0800769 + "applications.");
770 }
771 }
772
773 /**
774 * Applies invoke-with system properties to the zygote arguments.
775 *
776 * @param args non-null; zygote args
777 */
778 protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
779 if (args.mInvokeWith == null && args.mNiceName != null) {
780 String property = "wrap." + args.mNiceName;
781 args.mInvokeWith = SystemProperties.get(property);
782 if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
783 args.mInvokeWith = null;
784 }
785 }
786 }
787
788 /**
789 * Reads an argument list from the provided socket
790 * @return Argument list or null if EOF is reached
791 * @throws IOException passed straight through
792 */
793 static String[] readArgumentList(BufferedReader socketReader) throws IOException {
Chris Wailes2be26262019-01-11 16:14:43 -0800794 int argc;
795
796 try {
797 String argc_string = socketReader.readLine();
798
799 if (argc_string == null) {
800 // EOF reached.
801 return null;
802 }
803 argc = Integer.parseInt(argc_string);
804
805 } catch (NumberFormatException ex) {
806 Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
807 throw new IOException("Invalid wire format");
808 }
809
810 // See bug 1092107: large argc can be used for a DOS attack
811 if (argc > MAX_ZYGOTE_ARGC) {
812 throw new IOException("Max arg count exceeded");
813 }
814
815 String[] args = new String[argc];
816 for (int arg_index = 0; arg_index < argc; arg_index++) {
817 args[arg_index] = socketReader.readLine();
818 if (args[arg_index] == null) {
819 // We got an unexpected EOF.
820 throw new IOException("Truncated request");
821 }
822 }
823
824 return args;
825 }
826
Chris Wailescb0b37f2019-01-11 17:04:41 -0800827 /**
Chris Wailescb0b37f2019-01-11 17:04:41 -0800828 * Creates a managed LocalServerSocket object using a file descriptor
829 * created by an init.rc script. The init scripts that specify the
830 * sockets name can be found in system/core/rootdir. The socket is bound
831 * to the file system in the /dev/sockets/ directory, and the file
832 * descriptor is shared via the ANDROID_SOCKET_<socketName> environment
833 * variable.
834 */
835 static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
836 int fileDesc;
837 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
838
839 try {
840 String env = System.getenv(fullSocketName);
841 fileDesc = Integer.parseInt(env);
842 } catch (RuntimeException ex) {
843 throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
844 }
845
846 try {
847 FileDescriptor fd = new FileDescriptor();
848 fd.setInt$(fileDesc);
849 return new LocalServerSocket(fd);
850 } catch (IOException ex) {
851 throw new RuntimeException(
852 "Error building socket from file descriptor: " + fileDesc, ex);
853 }
854 }
doheon1.lee885b7422016-01-20 13:07:27 +0900855
Orion Hodson46724e72018-10-19 13:05:33 +0100856 private static void callPostForkSystemServerHooks() {
857 // SystemServer specific post fork hooks run before child post fork hooks.
Neil Fuller555d8b72019-01-28 18:29:20 +0000858 ZygoteHooks.postForkSystemServer();
Orion Hodson46724e72018-10-19 13:05:33 +0100859 }
860
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100861 private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
Robert Sesekd0a190df2018-02-12 18:46:01 -0500862 boolean isZygote, String instructionSet) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000863 ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
Narayan Kamath973b4662014-03-31 13:41:26 +0100864 }
865
Narayan Kamathb49996d2017-02-06 20:24:08 +0000866 /**
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800867 * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
868 * or nice value 0). This updates both the priority value in java.lang.Thread and
869 * the nice value (setpriority).
Narayan Kamathb49996d2017-02-06 20:24:08 +0000870 */
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800871 static void resetNicePriority() {
872 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
873 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100874
875 /**
876 * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
877 * This method throws a runtime exception if exec() failed, otherwise, this
878 * method never returns.
879 *
880 * @param command The shell command to execute.
881 */
882 public static void execShell(String command) {
883 String[] args = { "/system/bin/sh", "-c", command };
884 try {
Elliott Hughes860c5912014-04-28 19:19:13 -0700885 Os.execv(args[0], args);
Narayan Kamath973b4662014-03-31 13:41:26 +0100886 } catch (ErrnoException e) {
887 throw new RuntimeException(e);
888 }
889 }
890
891 /**
892 * Appends quotes shell arguments to the specified string builder.
893 * The arguments are quoted using single-quotes, escaped if necessary,
894 * prefixed with a space, and appended to the command.
895 *
896 * @param command A string builder for the shell command being constructed.
897 * @param args An array of argument strings to be quoted and appended to the command.
898 * @see #execShell(String)
899 */
900 public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
901 for (String arg : args) {
902 command.append(" '").append(arg.replace("'", "'\\''")).append("'");
903 }
904 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100905}