blob: 00ab45ec35374c08f898f6f763949cb71b831630 [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
randy.jeong3ea95802019-05-29 10:43:39 +0900109 /**
110 * When set, application specified signal handlers are not chained (i.e, ignored)
111 * by the runtime.
112 *
113 * Used for debugging only. Usage: set debug.ignoreappsignalhandler to 1.
114 */
115 public static final int DEBUG_IGNORE_APP_SIGNAL_HANDLER = 1 << 17;
116
Artur Satayev19305b42019-10-28 15:25:14 +0000117 /**
118 * Disable runtime access to {@link android.annotation.TestApi} annotated members.
119 *
120 * <p>This only takes effect if Hidden API access restrictions are enabled as well.
121 */
122 public static final int DISABLE_TEST_API_ENFORCEMENT_POLICY = 1 << 18;
123
Narayan Kamath973b4662014-03-31 13:41:26 +0100124 /** No external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600125 public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700126 /** Default external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600127 public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700128 /** Read-only external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600129 public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700130 /** Read-write external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600131 public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800132 /**
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800133 * Mount mode for apps that are already installed on the device before the isolated_storage
134 * feature is enabled.
135 */
136 public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY;
137 /**
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800138 * Mount mode for package installers which should give them access to
139 * all obb dirs in addition to their package sandboxes
140 */
141 public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700142 /** Read-write external storage should be mounted instead of package sandbox */
143 public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL;
Narayan Kamath973b4662014-03-31 13:41:26 +0100144
Chris Wailes7e797b62019-02-22 18:29:22 -0800145 /** Number of bytes sent to the Zygote over USAP pipes or the pool event FD */
146 public static final int USAP_MANAGEMENT_MESSAGE_BYTES = 8;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800147
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800148 /**
Robert Sesekd0a190df2018-02-12 18:46:01 -0500149 * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
150 * in the abstract socket namespace. This socket name is what the new child zygote
151 * should listen for connections on.
152 */
153 public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
154
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100155 /**
156 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
157 * requested ABI for the child Zygote.
158 */
159 public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list=";
160
Martijn Coenen86f08a52019-01-03 16:23:01 +0100161 /**
162 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
163 * start of the UID range the children of the Zygote may setuid()/setgid() to. This
164 * will be enforced with a seccomp filter.
165 */
166 public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start=";
167
168 /**
169 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
170 * end of the UID range the children of the Zygote may setuid()/setgid() to. This
171 * will be enforced with a seccomp filter.
172 */
173 public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end=";
174
Chris Wailescb0b37f2019-01-11 17:04:41 -0800175 /** Prefix prepended to socket names created by init */
176 private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
177
178 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800179 * The duration to wait before re-checking Zygote related system properties.
180 *
Chris Wailesdb132a32019-02-20 10:49:27 -0800181 * One minute in milliseconds.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800182 */
Chris Wailesdb132a32019-02-20 10:49:27 -0800183 public static final long PROPERTY_CHECK_INTERVAL = 60000;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800184
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800185 /**
186 * @hide for internal use only
187 */
188 public static final int SOCKET_BUFFER_SIZE = 256;
189
Chris Wailes2be26262019-01-11 16:14:43 -0800190 /** a prototype instance for a future List.toArray() */
191 protected static final int[][] INT_ARRAY_2D = new int[0][0];
192
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800193 /**
194 * @hide for internal use only.
195 */
196 public static final String PRIMARY_SOCKET_NAME = "zygote";
197
198 /**
199 * @hide for internal use only.
200 */
201 public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
202
203 /**
204 * @hide for internal use only
205 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800206 public static final String USAP_POOL_PRIMARY_SOCKET_NAME = "usap_pool_primary";
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800207
208 /**
209 * @hide for internal use only
210 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800211 public static final String USAP_POOL_SECONDARY_SOCKET_NAME = "usap_pool_secondary";
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800212
Narayan Kamath973b4662014-03-31 13:41:26 +0100213 private Zygote() {}
214
215 /**
216 * Forks a new VM instance. The current VM must have been started
217 * with the -Xzygote flag. <b>NOTE: new instance keeps all
218 * root capabilities. The new process is expected to call capset()</b>.
219 *
220 * @param uid the UNIX uid that the new process should setuid() to after
221 * fork()ing and and before spawning any threads.
222 * @param gid the UNIX gid that the new process should setgid() to after
223 * fork()ing and and before spawning any threads.
224 * @param gids null-ok; a list of UNIX gids that the new process should
225 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100226 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100227 * @param rlimits null-ok an array of rlimit tuples, with the second
228 * dimension having a length of 3 and representing
229 * (resource, rlim_cur, rlim_max). These are set via the posix
230 * setrlimit(2) call.
231 * @param seInfo null-ok a string specifying SELinux information for
232 * the new process.
233 * @param niceName null-ok a string specifying the process name.
234 * @param fdsToClose an array of ints, holding one or more POSIX
235 * file descriptor numbers that are to be closed by the child
236 * (and replaced by /dev/null) after forking. An integer value
237 * of -1 in any entry in the array means "ignore this one".
Andreas Gampe8dfa1782017-01-05 12:45:58 -0800238 * @param fdsToIgnore null-ok an array of ints, either null or holding
239 * one or more POSIX file descriptor numbers that are to be ignored
240 * in the file descriptor table check.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500241 * @param startChildZygote if true, the new child process will itself be a
242 * new zygote process.
Andreas Gampeaec67dc2014-09-02 21:23:06 -0700243 * @param instructionSet null-ok the instruction set to use.
jgu212eacd062014-09-10 06:55:07 -0400244 * @param appDataDir null-ok the data directory of the app.
Narayan Kamath973b4662014-03-31 13:41:26 +0100245 *
246 * @return 0 if this is the child, pid of the child
247 * if this is the parent, or -1 on error.
248 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100249 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700250 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
251 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700252 int targetSdkVersion) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000253 ZygoteHooks.preFork();
Mathew Inwood3e68de12019-05-24 14:06:10 +0100254 // Resets nice priority for zygote process.
255 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100256 int pid = nativeForkAndSpecialize(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800257 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700258 fdsToIgnore, startChildZygote, instructionSet, appDataDir);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100259 // Enable tracing as soon as possible for the child process.
260 if (pid == 0) {
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700261 Zygote.disableExecuteOnly(targetSdkVersion);
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700262 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100263
264 // Note that this event ends at the end of handleChildProc,
265 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
266 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000267 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100268 return pid;
269 }
270
Chris Wailesaa1c9622019-01-10 16:55:32 -0800271 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
272 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
273 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700274 String appDataDir);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800275
Chris Wailescb0b37f2019-01-11 17:04:41 -0800276 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800277 * Specialize an unspecialized app process. The current VM must have been started
Chris Wailescb0b37f2019-01-11 17:04:41 -0800278 * with the -Xzygote flag.
279 *
280 * @param uid The UNIX uid that the new process should setuid() to before spawning any threads
281 * @param gid The UNIX gid that the new process should setgid() to before spawning any threads
282 * @param gids null-ok; A list of UNIX gids that the new process should
283 * setgroups() to before spawning any threads
284 * @param runtimeFlags Bit flags that enable ART features
285 * @param rlimits null-ok An array of rlimit tuples, with the second
286 * dimension having a length of 3 and representing
287 * (resource, rlim_cur, rlim_max). These are set via the posix
288 * setrlimit(2) call.
289 * @param seInfo null-ok A string specifying SELinux information for
290 * the new process.
291 * @param niceName null-ok A string specifying the process name.
292 * @param startChildZygote If true, the new child process will itself be a
293 * new zygote process.
294 * @param instructionSet null-ok The instruction set to use.
295 * @param appDataDir null-ok The data directory of the app.
296 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800297 public static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
Chris Wailescb0b37f2019-01-11 17:04:41 -0800298 int[][] rlimits, int mountExternal, String seInfo, String niceName,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700299 boolean startChildZygote, String instructionSet, String appDataDir) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800300 nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700301 niceName, startChildZygote, instructionSet, appDataDir);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800302
303 // Enable tracing as soon as possible for the child process.
304 Trace.setTracingEnabled(true, runtimeFlags);
305
306 // Note that this event ends at the end of handleChildProc.
307 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
308
309 /*
310 * This is called here (instead of after the fork but before the specialize) to maintain
311 * consistancy with the code paths for forkAndSpecialize.
312 *
313 * TODO (chriswailes): Look into moving this to immediately after the fork.
314 */
Neil Fuller555d8b72019-01-28 18:29:20 +0000315 ZygoteHooks.postForkCommon();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800316 }
317
Chris Wailes7e797b62019-02-22 18:29:22 -0800318 private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800319 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
Sudheer Shanka64501e52019-04-29 10:46:26 -0700320 boolean startChildZygote, String instructionSet, String appDataDir);
Narayan Kamath973b4662014-03-31 13:41:26 +0100321
322 /**
Christopher Ferris2980de42017-06-20 16:13:40 -0700323 * Called to do any initialization before starting an application.
324 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800325 static native void nativePreApplicationInit();
Christopher Ferris2980de42017-06-20 16:13:40 -0700326
327 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100328 * Special method to start the system server process. In addition to the
329 * common actions performed in forkAndSpecialize, the pid of the child
330 * process is recorded such that the death of the child process will cause
331 * zygote to exit.
332 *
333 * @param uid the UNIX uid that the new process should setuid() to after
334 * fork()ing and and before spawning any threads.
335 * @param gid the UNIX gid that the new process should setgid() to after
336 * fork()ing and and before spawning any threads.
337 * @param gids null-ok; a list of UNIX gids that the new process should
338 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100339 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100340 * @param rlimits null-ok an array of rlimit tuples, with the second
341 * dimension having a length of 3 and representing
342 * (resource, rlim_cur, rlim_max). These are set via the posix
343 * setrlimit(2) call.
344 * @param permittedCapabilities argument for setcap()
345 * @param effectiveCapabilities argument for setcap()
346 *
347 * @return 0 if this is the child, pid of the child
348 * if this is the parent, or -1 on error.
349 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100350 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100351 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000352 ZygoteHooks.preFork();
Mathew Inwood3e68de12019-05-24 14:06:10 +0100353 // Resets nice priority for zygote process.
354 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100355 int pid = nativeForkSystemServer(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800356 uid, gid, gids, runtimeFlags, rlimits,
357 permittedCapabilities, effectiveCapabilities);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100358 // Enable tracing as soon as we enter the system_server.
359 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700360 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100361 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000362 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100363 return pid;
364 }
365
Chris Wailesaa1c9622019-01-10 16:55:32 -0800366 private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100367 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
368
doheon1.lee885b7422016-01-20 13:07:27 +0900369 /**
Robert Sesek54e387d2016-12-02 17:27:50 -0500370 * Lets children of the zygote inherit open file descriptors to this path.
371 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800372 protected static native void nativeAllowFileAcrossFork(String path);
Robert Sesek54e387d2016-12-02 17:27:50 -0500373
374 /**
Martijn Coenen4b988162019-01-28 13:58:45 +0100375 * Lets children of the zygote inherit open file descriptors that belong to the
376 * ApplicationInfo that is passed in.
377 *
378 * @param appInfo ApplicationInfo of the application
379 */
380 protected static void allowAppFilesAcrossFork(ApplicationInfo appInfo) {
Torne (Richard Coles)1aaae102019-03-01 15:02:29 -0500381 for (String path : appInfo.getAllApkPaths()) {
382 Zygote.nativeAllowFileAcrossFork(path);
Martijn Coenen4b988162019-01-28 13:58:45 +0100383 }
384 }
385
386 /**
Martijn Coenen86f08a52019-01-03 16:23:01 +0100387 * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
388 * @param uidGidMin The smallest allowed uid/gid
389 * @param uidGidMax The largest allowed uid/gid
390 */
391 native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax);
392
393 /**
Chris Wailes6d482d542019-04-03 13:00:52 -0700394 * Initialize the native state of the Zygote. This inclues
395 * - Fetching socket FDs from the environment
396 * - Initializing security properties
397 * - Unmounting storage as appropriate
398 * - Loading necessary performance profile information
Chris Wailescb0b37f2019-01-11 17:04:41 -0800399 *
400 * @param isPrimary True if this is the zygote process, false if it is zygote_secondary
401 */
Chris Wailes6d482d542019-04-03 13:00:52 -0700402 static void initNativeState(boolean isPrimary) {
403 nativeInitNativeState(isPrimary);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800404 }
405
Chris Wailes6d482d542019-04-03 13:00:52 -0700406 protected static native void nativeInitNativeState(boolean isPrimary);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800407
Chris Wailescb0b37f2019-01-11 17:04:41 -0800408 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800409 * Returns the raw string value of a system property.
410 *
411 * Note that Device Config is not available without an application so SystemProperties is used
412 * instead.
413 *
414 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
415 * function to fetch it.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800416 */
Chris Wailesfe3a3482019-03-13 14:38:04 -0700417 public static String getConfigurationProperty(String propertyName, String defaultValue) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800418 return SystemProperties.get(
419 String.join(".",
420 "persist.device_config",
Matt Papee9b680a2019-03-05 15:53:13 -0800421 DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800422 propertyName),
423 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800424 }
425
Chris Wailes7e797b62019-02-22 18:29:22 -0800426 protected static void emptyUsapPool() {
427 nativeEmptyUsapPool();
Chris Wailesae937142019-01-24 12:57:33 -0800428 }
429
Chris Wailes7e797b62019-02-22 18:29:22 -0800430 private static native void nativeEmptyUsapPool();
Chris Wailesae937142019-01-24 12:57:33 -0800431
Chris Wailescb0b37f2019-01-11 17:04:41 -0800432 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800433 * Returns the value of a system property converted to a boolean using specific logic.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800434 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800435 * Note that Device Config is not available without an application so SystemProperties is used
436 * instead.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800437 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800438 * @see SystemProperties.getBoolean
439 *
440 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
441 * function to fetch it.
Chris Wailesfe3a3482019-03-13 14:38:04 -0700442 * TODO (chriswailes): Move into ZygoteConfig.java once the necessary CL lands (go/ag/6580627)
Chris Wailescb0b37f2019-01-11 17:04:41 -0800443 */
Chris Wailesfe3a3482019-03-13 14:38:04 -0700444 public static boolean getConfigurationPropertyBoolean(
445 String propertyName, Boolean defaultValue) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800446 return SystemProperties.getBoolean(
447 String.join(".",
448 "persist.device_config",
Matt Papee9b680a2019-03-05 15:53:13 -0800449 DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800450 propertyName),
451 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800452 }
453
454 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800455 * @return Number of unspecialized app processes currently in the pool
Chris Wailescb0b37f2019-01-11 17:04:41 -0800456 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800457 static int getUsapPoolCount() {
458 return nativeGetUsapPoolCount();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800459 }
460
Chris Wailes7e797b62019-02-22 18:29:22 -0800461 private static native int nativeGetUsapPoolCount();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800462
Chris Wailescb0b37f2019-01-11 17:04:41 -0800463 /**
464 * @return The event FD used for communication between the signal handler and the ZygoteServer
465 * poll loop
466 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800467 static FileDescriptor getUsapPoolEventFD() {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800468 FileDescriptor fd = new FileDescriptor();
Chris Wailes7e797b62019-02-22 18:29:22 -0800469 fd.setInt$(nativeGetUsapPoolEventFD());
Chris Wailescb0b37f2019-01-11 17:04:41 -0800470
471 return fd;
472 }
473
Chris Wailes7e797b62019-02-22 18:29:22 -0800474 private static native int nativeGetUsapPoolEventFD();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800475
Chris Wailescb0b37f2019-01-11 17:04:41 -0800476 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800477 * Fork a new unspecialized app process from the zygote
Chris Wailescb0b37f2019-01-11 17:04:41 -0800478 *
479 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
Chris Wailes7e797b62019-02-22 18:29:22 -0800480 * @return In the Zygote process this function will always return null; in unspecialized app
481 * processes this function will return a Runnable object representing the new
482 * application that is passed up from usapMain.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800483 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800484 static Runnable forkUsap(LocalServerSocket usapPoolSocket,
Mathew Inwood3e68de12019-05-24 14:06:10 +0100485 int[] sessionSocketRawFDs) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800486 FileDescriptor[] pipeFDs = null;
487
488 try {
489 pipeFDs = Os.pipe2(O_CLOEXEC);
490 } catch (ErrnoException errnoEx) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800491 throw new IllegalStateException("Unable to create USAP pipe.", errnoEx);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800492 }
493
494 int pid =
Mathew Inwood3e68de12019-05-24 14:06:10 +0100495 nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800496
497 if (pid == 0) {
498 IoUtils.closeQuietly(pipeFDs[0]);
Chris Wailes7e797b62019-02-22 18:29:22 -0800499 return usapMain(usapPoolSocket, pipeFDs[1]);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800500 } else {
501 // The read-end of the pipe will be closed by the native code.
Chris Wailes7e797b62019-02-22 18:29:22 -0800502 // See removeUsapTableEntry();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800503 IoUtils.closeQuietly(pipeFDs[1]);
504 return null;
505 }
506 }
507
Chris Wailes7e797b62019-02-22 18:29:22 -0800508 private static native int nativeForkUsap(int readPipeFD,
Mathew Inwood3e68de12019-05-24 14:06:10 +0100509 int writePipeFD,
510 int[] sessionSocketRawFDs);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800511
Chris Wailescb0b37f2019-01-11 17:04:41 -0800512 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800513 * This function is used by unspecialized app processes to wait for specialization requests from
514 * the system server.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800515 *
516 * @param writePipe The write end of the reporting pipe used to communicate with the poll loop
517 * of the ZygoteServer.
518 * @return A runnable oject representing the new application.
519 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800520 private static Runnable usapMain(LocalServerSocket usapPoolSocket,
521 FileDescriptor writePipe) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800522 final int pid = Process.myPid();
Chris Wailes07530402019-03-25 18:01:30 -0700523 Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800524
525 LocalSocket sessionSocket = null;
Chris Wailes7e797b62019-02-22 18:29:22 -0800526 DataOutputStream usapOutputStream = null;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800527 Credentials peerCredentials = null;
Chris Wailesae937142019-01-24 12:57:33 -0800528 ZygoteArguments args = null;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800529
530 while (true) {
531 try {
Chris Wailes7e797b62019-02-22 18:29:22 -0800532 sessionSocket = usapPoolSocket.accept();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800533
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700534 // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool.
535 blockSigTerm();
536
Chris Wailes7e797b62019-02-22 18:29:22 -0800537 BufferedReader usapReader =
Chris Wailescb0b37f2019-01-11 17:04:41 -0800538 new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
Chris Wailes7e797b62019-02-22 18:29:22 -0800539 usapOutputStream =
Chris Wailescb0b37f2019-01-11 17:04:41 -0800540 new DataOutputStream(sessionSocket.getOutputStream());
541
542 peerCredentials = sessionSocket.getPeerCredentials();
543
Chris Wailes7e797b62019-02-22 18:29:22 -0800544 String[] argStrings = readArgumentList(usapReader);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800545
546 if (argStrings != null) {
Chris Wailesae937142019-01-24 12:57:33 -0800547 args = new ZygoteArguments(argStrings);
548
549 // TODO (chriswailes): Should this only be run for debug builds?
Chris Wailes7e797b62019-02-22 18:29:22 -0800550 validateUsapCommand(args);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800551 break;
552 } else {
Chris Wailes7e797b62019-02-22 18:29:22 -0800553 Log.e("USAP", "Truncated command received.");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800554 IoUtils.closeQuietly(sessionSocket);
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700555
556 // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
557 unblockSigTerm();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800558 }
Chris Wailesae937142019-01-24 12:57:33 -0800559 } catch (Exception ex) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800560 Log.e("USAP", ex.getMessage());
Chris Wailescb0b37f2019-01-11 17:04:41 -0800561 IoUtils.closeQuietly(sessionSocket);
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700562
563 // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
564 unblockSigTerm();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800565 }
566 }
567
Chris Wailescb0b37f2019-01-11 17:04:41 -0800568 try {
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700569 // SIGTERM is blocked on loop exit. This prevents a USAP that is specializing from
570 // being killed during a pool flush.
571
572 applyUidSecurityPolicy(args, peerCredentials);
573 applyDebuggerSystemProperty(args);
574
575 int[][] rlimits = null;
576
577 if (args.mRLimits != null) {
578 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
579 }
580
581 // This must happen before the SELinux policy for this process is
582 // changed when specializing.
583 try {
584 // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
585 // Process.ProcessStartResult object.
586 usapOutputStream.writeInt(pid);
587 } catch (IOException ioEx) {
588 Log.e("USAP", "Failed to write response to session socket: "
589 + ioEx.getMessage());
590 throw new RuntimeException(ioEx);
591 } finally {
592 IoUtils.closeQuietly(sessionSocket);
593
594 try {
595 // This socket is closed using Os.close due to an issue with the implementation
596 // of LocalSocketImp.close(). Because the raw FD is created by init and then
597 // loaded from an environment variable (as opposed to being created by the
598 // LocalSocketImpl itself) the current implementation will not actually close
599 // the underlying FD.
600 //
601 // See b/130309968 for discussion of this issue.
602 Os.close(usapPoolSocket.getFileDescriptor());
603 } catch (ErrnoException ex) {
604 Log.e("USAP", "Failed to close USAP pool socket");
605 throw new RuntimeException(ex);
606 }
607 }
Chris Wailesb63a00a2019-04-10 15:55:29 -0700608
609 try {
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700610 ByteArrayOutputStream buffer =
611 new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
612 DataOutputStream outputStream = new DataOutputStream(buffer);
613
614 // This is written as a long so that the USAP reporting pipe and USAP pool event FD
615 // handlers in ZygoteServer.runSelectLoop can be unified. These two cases should
616 // both send/receive 8 bytes.
617 outputStream.writeLong(pid);
618 outputStream.flush();
619
620 Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
621 } catch (Exception ex) {
622 Log.e("USAP",
623 String.format("Failed to write PID (%d) to pipe (%d): %s",
624 pid, writePipe.getInt$(), ex.getMessage()));
625 throw new RuntimeException(ex);
626 } finally {
627 IoUtils.closeQuietly(writePipe);
Chris Wailesb63a00a2019-04-10 15:55:29 -0700628 }
Chris Wailescb0b37f2019-01-11 17:04:41 -0800629
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700630 specializeAppProcess(args.mUid, args.mGid, args.mGids,
631 args.mRuntimeFlags, rlimits, args.mMountExternal,
632 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
633 args.mInstructionSet, args.mAppDataDir);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800634
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700635 disableExecuteOnly(args.mTargetSdkVersion);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800636
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700637 if (args.mNiceName != null) {
638 Process.setArgV0(args.mNiceName);
639 }
640
641 // End of the postFork event.
642 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
643
644 return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
645 args.mRemainingArgs,
646 null /* classLoader */);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800647 } finally {
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700648 // Unblock SIGTERM to restore the process to default behavior.
649 unblockSigTerm();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800650 }
Chris Wailescb0b37f2019-01-11 17:04:41 -0800651 }
652
Chris Wailesf59ea2c2019-06-05 16:07:50 -0700653 private static void blockSigTerm() {
654 nativeBlockSigTerm();
655 }
656
657 private static native void nativeBlockSigTerm();
658
659 private static void unblockSigTerm() {
660 nativeUnblockSigTerm();
661 }
662
663 private static native void nativeUnblockSigTerm();
664
Chris Wailes7e797b62019-02-22 18:29:22 -0800665 private static final String USAP_ERROR_PREFIX = "Invalid command to USAP: ";
Chris Wailescb0b37f2019-01-11 17:04:41 -0800666
667 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800668 * 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 -0800669 * exception if an invalid arugment is encountered.
670 * @param args The arguments to test
671 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800672 private static void validateUsapCommand(ZygoteArguments args) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800673 if (args.mAbiListQuery) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800674 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--query-abi-list");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800675 } else if (args.mPidQuery) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800676 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--get-pid");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800677 } else if (args.mPreloadDefault) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800678 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-default");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800679 } else if (args.mPreloadPackage != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800680 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-package");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800681 } else if (args.mPreloadApp != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800682 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--preload-app");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800683 } else if (args.mStartChildZygote) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800684 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--start-child-zygote");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800685 } else if (args.mApiBlacklistExemptions != null) {
686 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800687 USAP_ERROR_PREFIX + "--set-api-blacklist-exemptions");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800688 } else if (args.mHiddenApiAccessLogSampleRate != -1) {
689 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800690 USAP_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
Andrei Oneae8e150d2019-02-18 18:27:11 +0000691 } else if (args.mHiddenApiAccessStatslogSampleRate != -1) {
692 throw new IllegalArgumentException(
Chris Wailes7e797b62019-02-22 18:29:22 -0800693 USAP_ERROR_PREFIX + "--hidden-api-statslog-sampling-rate=");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800694 } else if (args.mInvokeWith != null) {
Chris Wailes7e797b62019-02-22 18:29:22 -0800695 throw new IllegalArgumentException(USAP_ERROR_PREFIX + "--invoke-with");
Chris Wailescb0b37f2019-01-11 17:04:41 -0800696 } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
697 throw new ZygoteSecurityException("Client may not specify capabilities: "
698 + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities)
699 + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities));
700 }
701 }
702
703 /**
Jeff Vander Stoep739c0b52019-03-25 20:27:52 -0700704 * Mark execute-only segments of libraries read+execute for apps with targetSdkVersion<Q.
705 */
706 protected static void disableExecuteOnly(int targetSdkVersion) {
707 if ((targetSdkVersion < Build.VERSION_CODES.Q) && !nativeDisableExecuteOnly()) {
708 Log.e("Zygote", "Failed to set libraries to read+execute.");
709 }
710 }
711
712 private static native boolean nativeDisableExecuteOnly();
713
714 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800715 * @return Raw file descriptors for the read-end of USAP reporting pipes.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800716 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800717 protected static int[] getUsapPipeFDs() {
718 return nativeGetUsapPipeFDs();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800719 }
720
Chris Wailes7e797b62019-02-22 18:29:22 -0800721 private static native int[] nativeGetUsapPipeFDs();
Chris Wailesaa1c9622019-01-10 16:55:32 -0800722
Chris Wailescb0b37f2019-01-11 17:04:41 -0800723 /**
Chris Wailes7e797b62019-02-22 18:29:22 -0800724 * Remove the USAP table entry for the provided process ID.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800725 *
Chris Wailes7e797b62019-02-22 18:29:22 -0800726 * @param usapPID Process ID of the entry to remove
Chris Wailescb0b37f2019-01-11 17:04:41 -0800727 * @return True if the entry was removed; false if it doesn't exist
728 */
Chris Wailes7e797b62019-02-22 18:29:22 -0800729 protected static boolean removeUsapTableEntry(int usapPID) {
730 return nativeRemoveUsapTableEntry(usapPID);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800731 }
732
Chris Wailes7e797b62019-02-22 18:29:22 -0800733 private static native boolean nativeRemoveUsapTableEntry(int usapPID);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800734
Chris Wailes2be26262019-01-11 16:14:43 -0800735 /**
736 * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
737 * operation. It may also specify any gid and setgroups() list it chooses.
738 * In factory test mode, it may specify any UID.
739 *
740 * @param args non-null; zygote spawner arguments
741 * @param peer non-null; peer credentials
742 * @throws ZygoteSecurityException
743 */
744 protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
745 throws ZygoteSecurityException {
746
747 if (peer.getUid() == Process.SYSTEM_UID) {
748 /* In normal operation, SYSTEM_UID can only specify a restricted
749 * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
750 */
751 boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
752
753 if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
754 throw new ZygoteSecurityException(
755 "System UID may not launch process with UID < "
756 + Process.SYSTEM_UID);
757 }
758 }
759
760 // If not otherwise specified, uid and gid are inherited from peer
761 if (!args.mUidSpecified) {
762 args.mUid = peer.getUid();
763 args.mUidSpecified = true;
764 }
765 if (!args.mGidSpecified) {
766 args.mGid = peer.getGid();
767 args.mGidSpecified = true;
768 }
769 }
770
771 /**
772 * Applies debugger system properties to the zygote arguments.
773 *
774 * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
775 * the debugger state is specified via the "--enable-jdwp" flag
776 * in the spawn request.
777 *
778 * @param args non-null; zygote spawner args
779 */
780 protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
781 if (RoSystemProperties.DEBUGGABLE) {
782 args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
783 }
784 }
785
786 /**
787 * Applies zygote security policy.
788 * Based on the credentials of the process issuing a zygote command:
789 * <ol>
790 * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
791 * wrapper command.
792 * <li> Any other uid may not specify any invoke-with argument.
793 * </ul>
794 *
795 * @param args non-null; zygote spawner arguments
796 * @param peer non-null; peer credentials
797 * @throws ZygoteSecurityException
798 */
799 protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
800 throws ZygoteSecurityException {
801 int peerUid = peer.getUid();
802
803 if (args.mInvokeWith != null && peerUid != 0
804 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
Chris Wailesae937142019-01-24 12:57:33 -0800805 throw new ZygoteSecurityException("Peer is permitted to specify an "
806 + "explicit invoke-with wrapper command only for debuggable "
Chris Wailes2be26262019-01-11 16:14:43 -0800807 + "applications.");
808 }
809 }
810
811 /**
812 * Applies invoke-with system properties to the zygote arguments.
813 *
814 * @param args non-null; zygote args
815 */
816 protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
817 if (args.mInvokeWith == null && args.mNiceName != null) {
818 String property = "wrap." + args.mNiceName;
819 args.mInvokeWith = SystemProperties.get(property);
820 if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
821 args.mInvokeWith = null;
822 }
823 }
824 }
825
826 /**
827 * Reads an argument list from the provided socket
828 * @return Argument list or null if EOF is reached
829 * @throws IOException passed straight through
830 */
831 static String[] readArgumentList(BufferedReader socketReader) throws IOException {
Chris Wailes2be26262019-01-11 16:14:43 -0800832 int argc;
833
834 try {
835 String argc_string = socketReader.readLine();
836
837 if (argc_string == null) {
838 // EOF reached.
839 return null;
840 }
841 argc = Integer.parseInt(argc_string);
842
843 } catch (NumberFormatException ex) {
844 Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
845 throw new IOException("Invalid wire format");
846 }
847
848 // See bug 1092107: large argc can be used for a DOS attack
849 if (argc > MAX_ZYGOTE_ARGC) {
850 throw new IOException("Max arg count exceeded");
851 }
852
853 String[] args = new String[argc];
854 for (int arg_index = 0; arg_index < argc; arg_index++) {
855 args[arg_index] = socketReader.readLine();
856 if (args[arg_index] == null) {
857 // We got an unexpected EOF.
858 throw new IOException("Truncated request");
859 }
860 }
861
862 return args;
863 }
864
Chris Wailescb0b37f2019-01-11 17:04:41 -0800865 /**
Chris Wailescb0b37f2019-01-11 17:04:41 -0800866 * Creates a managed LocalServerSocket object using a file descriptor
867 * created by an init.rc script. The init scripts that specify the
868 * sockets name can be found in system/core/rootdir. The socket is bound
869 * to the file system in the /dev/sockets/ directory, and the file
870 * descriptor is shared via the ANDROID_SOCKET_<socketName> environment
871 * variable.
872 */
873 static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
874 int fileDesc;
875 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
876
877 try {
878 String env = System.getenv(fullSocketName);
879 fileDesc = Integer.parseInt(env);
880 } catch (RuntimeException ex) {
881 throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
882 }
883
884 try {
885 FileDescriptor fd = new FileDescriptor();
886 fd.setInt$(fileDesc);
887 return new LocalServerSocket(fd);
888 } catch (IOException ex) {
889 throw new RuntimeException(
890 "Error building socket from file descriptor: " + fileDesc, ex);
891 }
892 }
doheon1.lee885b7422016-01-20 13:07:27 +0900893
Mathieu Chartier742981e2019-11-21 14:30:03 -0800894 private static void callPostForkSystemServerHooks(int runtimeFlags) {
Orion Hodson46724e72018-10-19 13:05:33 +0100895 // SystemServer specific post fork hooks run before child post fork hooks.
Mathieu Chartier742981e2019-11-21 14:30:03 -0800896 ZygoteHooks.postForkSystemServer(runtimeFlags);
Orion Hodson46724e72018-10-19 13:05:33 +0100897 }
898
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100899 private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
Robert Sesekd0a190df2018-02-12 18:46:01 -0500900 boolean isZygote, String instructionSet) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000901 ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
Narayan Kamath973b4662014-03-31 13:41:26 +0100902 }
903
Narayan Kamathb49996d2017-02-06 20:24:08 +0000904 /**
Mathew Inwood3e68de12019-05-24 14:06:10 +0100905 * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
906 * or nice value 0). This updates both the priority value in java.lang.Thread and
907 * the nice value (setpriority).
908 */
909 static void resetNicePriority() {
910 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
911 }
912
913 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100914 * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
915 * This method throws a runtime exception if exec() failed, otherwise, this
916 * method never returns.
917 *
918 * @param command The shell command to execute.
919 */
920 public static void execShell(String command) {
921 String[] args = { "/system/bin/sh", "-c", command };
922 try {
Elliott Hughes860c5912014-04-28 19:19:13 -0700923 Os.execv(args[0], args);
Narayan Kamath973b4662014-03-31 13:41:26 +0100924 } catch (ErrnoException e) {
925 throw new RuntimeException(e);
926 }
927 }
928
929 /**
930 * Appends quotes shell arguments to the specified string builder.
931 * The arguments are quoted using single-quotes, escaped if necessary,
932 * prefixed with a space, and appended to the command.
933 *
934 * @param command A string builder for the shell command being constructed.
935 * @param args An array of argument strings to be quoted and appended to the command.
936 * @see #execShell(String)
937 */
938 public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
939 for (String arg : args) {
940 command.append(" '").append(arg.replace("'", "'\\''")).append("'");
941 }
942 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100943}