blob: 22884ac9e3fc9d0229235dae753b4368d7aea0e2 [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;
Chris Wailes2be26262019-01-11 16:14:43 -080027import android.os.FactoryTest;
Jeff Sharkeyace874b2017-09-07 15:27:33 -060028import android.os.IVold;
Chris Wailes2be26262019-01-11 16:14:43 -080029import android.os.Process;
30import android.os.SystemProperties;
Narayan Kamathfbb32f62015-06-12 15:34:35 +010031import android.os.Trace;
Mathieu Chartier0bccbf72019-01-30 15:56:17 -080032import android.provider.DeviceConfig;
Elliott Hughes860c5912014-04-28 19:19:13 -070033import android.system.ErrnoException;
34import android.system.Os;
Chris Wailes2be26262019-01-11 16:14:43 -080035import android.util.Log;
Narayan Kamath973b4662014-03-31 13:41:26 +010036
Jeff Sharkeyace874b2017-09-07 15:27:33 -060037import dalvik.system.ZygoteHooks;
Tobias Sargeantb9679dc2016-01-19 16:34:54 +000038
Chris Wailescb0b37f2019-01-11 17:04:41 -080039import libcore.io.IoUtils;
40
Chris Wailes2be26262019-01-11 16:14:43 -080041import java.io.BufferedReader;
Chris Wailescb0b37f2019-01-11 17:04:41 -080042import java.io.ByteArrayOutputStream;
43import java.io.DataOutputStream;
44import java.io.FileDescriptor;
Chris Wailes2be26262019-01-11 16:14:43 -080045import java.io.IOException;
Chris Wailescb0b37f2019-01-11 17:04:41 -080046import java.io.InputStreamReader;
Chris Wailes2be26262019-01-11 16:14:43 -080047
Narayan Kamath973b4662014-03-31 13:41:26 +010048/** @hide */
49public final class Zygote {
50 /*
Nicolas Geoffray81edac42017-09-07 14:13:29 +010051 * Bit values for "runtimeFlags" argument. The definitions are duplicated
Narayan Kamath973b4662014-03-31 13:41:26 +010052 * in the native code.
53 */
54
55 /** enable debugging over JDWP */
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000056 public static final int DEBUG_ENABLE_JDWP = 1;
Narayan Kamath973b4662014-03-31 13:41:26 +010057 /** enable JNI checks */
58 public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1;
59 /** enable Java programming language "assert" statements */
60 public static final int DEBUG_ENABLE_ASSERT = 1 << 2;
Mathieu Chartier7a490282015-03-17 09:51:36 -070061 /** disable the AOT compiler and JIT */
Narayan Kamath973b4662014-03-31 13:41:26 +010062 public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3;
63 /** Enable logging of third-party JNI activity. */
64 public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
David Srbecky065075e2015-05-28 17:16:09 +010065 /** Force generation of native debugging information. */
Nicolas Geoffray9abbf452015-11-05 11:29:42 +000066 public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 5;
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000067 /** Always use JIT-ed code. */
68 public static final int DEBUG_ALWAYS_JIT = 1 << 6;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000069 /** Make the code native debuggable by turning off some optimizations. */
Tamas Berghammerdf6cb282016-01-29 12:07:00 +000070 public static final int DEBUG_NATIVE_DEBUGGABLE = 1 << 7;
Nicolas Geoffray347b1df2016-12-20 14:05:05 +000071 /** Make the code Java debuggable by turning off some optimizations. */
72 public static final int DEBUG_JAVA_DEBUGGABLE = 1 << 8;
Mathieu Chartier7a490282015-03-17 09:51:36 -070073
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010074 /** Turn off the verifier. */
75 public static final int DISABLE_VERIFIER = 1 << 9;
76 /** Only use oat files located in /system. Otherwise use dex/jar/apk . */
77 public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
David Srbecky156ed922018-01-30 14:37:37 +000078 /** Force generation of native debugging information for backtraces. */
Mathew Inwood16073b82018-03-23 10:05:01 +000079 public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 11;
80 /**
81 * Hidden API access restrictions. This is a mask for bits representing the API enforcement
82 * policy, defined by {@code @ApplicationInfo.HiddenApiEnforcementPolicy}.
83 */
84 public static final int API_ENFORCEMENT_POLICY_MASK = (1 << 12) | (1 << 13);
85 /**
86 * Bit shift for use with {@link #API_ENFORCEMENT_POLICY_MASK}.
87 *
88 * (flags & API_ENFORCEMENT_POLICY_MASK) >> API_ENFORCEMENT_POLICY_SHIFT gives
89 * @ApplicationInfo.ApiEnforcementPolicy values.
90 */
91 public static final int API_ENFORCEMENT_POLICY_SHIFT =
92 Integer.numberOfTrailingZeros(API_ENFORCEMENT_POLICY_MASK);
Calin Juravle8eb891b2018-05-03 19:51:18 -070093 /**
94 * Enable system server ART profiling.
95 */
96 public static final int PROFILE_SYSTEM_SERVER = 1 << 14;
Nicolas Geoffray1f88ad62017-09-13 14:21:00 +010097
Yabin Cui4d8546d2019-01-29 16:29:20 -080098 /**
99 * Enable profiling from shell.
100 */
101 public static final int PROFILE_FROM_SHELL = 1 << 15;
102
Mathieu Chartierced7e082019-02-04 13:28:36 -0800103 /*
104 * Enable using the ART app image startup cache
105 */
106 public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
107
Narayan Kamath973b4662014-03-31 13:41:26 +0100108 /** No external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600109 public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700110 /** Default external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600111 public static final int MOUNT_EXTERNAL_DEFAULT = IVold.REMOUNT_MODE_DEFAULT;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700112 /** Read-only external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600113 public static final int MOUNT_EXTERNAL_READ = IVold.REMOUNT_MODE_READ;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700114 /** Read-write external storage should be mounted. */
Jeff Sharkeyace874b2017-09-07 15:27:33 -0600115 public static final int MOUNT_EXTERNAL_WRITE = IVold.REMOUNT_MODE_WRITE;
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800116 /**
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800117 * Mount mode for apps that are already installed on the device before the isolated_storage
118 * feature is enabled.
119 */
120 public static final int MOUNT_EXTERNAL_LEGACY = IVold.REMOUNT_MODE_LEGACY;
121 /**
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800122 * Mount mode for package installers which should give them access to
123 * all obb dirs in addition to their package sandboxes
124 */
125 public static final int MOUNT_EXTERNAL_INSTALLER = IVold.REMOUNT_MODE_INSTALLER;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700126 /** Read-write external storage should be mounted instead of package sandbox */
127 public static final int MOUNT_EXTERNAL_FULL = IVold.REMOUNT_MODE_FULL;
Narayan Kamath973b4662014-03-31 13:41:26 +0100128
Chris Wailescb0b37f2019-01-11 17:04:41 -0800129 /** Number of bytes sent to the Zygote over blastula pipes or the pool event FD */
130 public static final int BLASTULA_MANAGEMENT_MESSAGE_BYTES = 8;
131
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800132 /**
Robert Sesekd0a190df2018-02-12 18:46:01 -0500133 * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
134 * in the abstract socket namespace. This socket name is what the new child zygote
135 * should listen for connections on.
136 */
137 public static final String CHILD_ZYGOTE_SOCKET_NAME_ARG = "--zygote-socket=";
138
Martijn Coenen7e6fa672018-11-05 11:45:26 +0100139 /**
140 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
141 * requested ABI for the child Zygote.
142 */
143 public static final String CHILD_ZYGOTE_ABI_LIST_ARG = "--abi-list=";
144
Martijn Coenen86f08a52019-01-03 16:23:01 +0100145 /**
146 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
147 * start of the UID range the children of the Zygote may setuid()/setgid() to. This
148 * will be enforced with a seccomp filter.
149 */
150 public static final String CHILD_ZYGOTE_UID_RANGE_START = "--uid-range-start=";
151
152 /**
153 * An extraArg passed when a zygote process is forking a child-zygote, specifying the
154 * end of the UID range the children of the Zygote may setuid()/setgid() to. This
155 * will be enforced with a seccomp filter.
156 */
157 public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end=";
158
Chris Wailescb0b37f2019-01-11 17:04:41 -0800159 /** Prefix prepended to socket names created by init */
160 private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
161
162 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800163 * The duration to wait before re-checking Zygote related system properties.
164 *
165 * Five minutes in milliseconds.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800166 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800167 public static final long PROPERTY_CHECK_INTERVAL = 300000;
Chris Wailescb0b37f2019-01-11 17:04:41 -0800168
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800169 /**
170 * @hide for internal use only
171 */
172 public static final int SOCKET_BUFFER_SIZE = 256;
173
Chris Wailes2be26262019-01-11 16:14:43 -0800174 /** a prototype instance for a future List.toArray() */
175 protected static final int[][] INT_ARRAY_2D = new int[0][0];
176
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800177 /**
178 * @hide for internal use only.
179 */
180 public static final String PRIMARY_SOCKET_NAME = "zygote";
181
182 /**
183 * @hide for internal use only.
184 */
185 public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
186
187 /**
188 * @hide for internal use only
189 */
190 public static final String BLASTULA_POOL_PRIMARY_SOCKET_NAME = "blastula_pool";
191
192 /**
193 * @hide for internal use only
194 */
195 public static final String BLASTULA_POOL_SECONDARY_SOCKET_NAME = "blastula_pool_secondary";
196
Narayan Kamath973b4662014-03-31 13:41:26 +0100197 private Zygote() {}
198
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800199 /** Called for some security initialization before any fork. */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800200 static native void nativeSecurityInit();
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800201
Narayan Kamath973b4662014-03-31 13:41:26 +0100202 /**
203 * Forks a new VM instance. The current VM must have been started
204 * with the -Xzygote flag. <b>NOTE: new instance keeps all
205 * root capabilities. The new process is expected to call capset()</b>.
206 *
207 * @param uid the UNIX uid that the new process should setuid() to after
208 * fork()ing and and before spawning any threads.
209 * @param gid the UNIX gid that the new process should setgid() to after
210 * fork()ing and and before spawning any threads.
211 * @param gids null-ok; a list of UNIX gids that the new process should
212 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100213 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100214 * @param rlimits null-ok an array of rlimit tuples, with the second
215 * dimension having a length of 3 and representing
216 * (resource, rlim_cur, rlim_max). These are set via the posix
217 * setrlimit(2) call.
218 * @param seInfo null-ok a string specifying SELinux information for
219 * the new process.
220 * @param niceName null-ok a string specifying the process name.
221 * @param fdsToClose an array of ints, holding one or more POSIX
222 * file descriptor numbers that are to be closed by the child
223 * (and replaced by /dev/null) after forking. An integer value
224 * of -1 in any entry in the array means "ignore this one".
Andreas Gampe8dfa1782017-01-05 12:45:58 -0800225 * @param fdsToIgnore null-ok an array of ints, either null or holding
226 * one or more POSIX file descriptor numbers that are to be ignored
227 * in the file descriptor table check.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500228 * @param startChildZygote if true, the new child process will itself be a
229 * new zygote process.
Andreas Gampeaec67dc2014-09-02 21:23:06 -0700230 * @param instructionSet null-ok the instruction set to use.
jgu212eacd062014-09-10 06:55:07 -0400231 * @param appDataDir null-ok the data directory of the app.
Narayan Kamath973b4662014-03-31 13:41:26 +0100232 *
233 * @return 0 if this is the child, pid of the child
234 * if this is the parent, or -1 on error.
235 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100236 public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700237 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
238 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800239 String packageName, String[] packagesForUID, String[] visibleVolIDs, String sandboxId) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000240 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800241 // Resets nice priority for zygote process.
242 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100243 int pid = nativeForkAndSpecialize(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800244 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
245 fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800246 packagesForUID, visibleVolIDs, sandboxId);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100247 // Enable tracing as soon as possible for the child process.
248 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700249 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100250
251 // Note that this event ends at the end of handleChildProc,
252 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
253 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000254 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100255 return pid;
256 }
257
Chris Wailesaa1c9622019-01-10 16:55:32 -0800258 private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
259 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
260 int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800261 String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs,
262 String sandboxId);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800263
Chris Wailescb0b37f2019-01-11 17:04:41 -0800264 /**
265 * Specialize a Blastula instance. The current VM must have been started
266 * with the -Xzygote flag.
267 *
268 * @param uid The UNIX uid that the new process should setuid() to before spawning any threads
269 * @param gid The UNIX gid that the new process should setgid() to before spawning any threads
270 * @param gids null-ok; A list of UNIX gids that the new process should
271 * setgroups() to before spawning any threads
272 * @param runtimeFlags Bit flags that enable ART features
273 * @param rlimits null-ok An array of rlimit tuples, with the second
274 * dimension having a length of 3 and representing
275 * (resource, rlim_cur, rlim_max). These are set via the posix
276 * setrlimit(2) call.
277 * @param seInfo null-ok A string specifying SELinux information for
278 * the new process.
279 * @param niceName null-ok A string specifying the process name.
280 * @param startChildZygote If true, the new child process will itself be a
281 * new zygote process.
282 * @param instructionSet null-ok The instruction set to use.
283 * @param appDataDir null-ok The data directory of the app.
284 */
285 public static void specializeBlastula(int uid, int gid, int[] gids, int runtimeFlags,
286 int[][] rlimits, int mountExternal, String seInfo, String niceName,
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800287 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800288 String[] packagesForUID, String[] visibleVolIDs, String sandboxId) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800289
290 nativeSpecializeBlastula(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
291 niceName, startChildZygote, instructionSet, appDataDir,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800292 packageName, packagesForUID, visibleVolIDs, sandboxId);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800293
294 // Enable tracing as soon as possible for the child process.
295 Trace.setTracingEnabled(true, runtimeFlags);
296
297 // Note that this event ends at the end of handleChildProc.
298 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
299
300 /*
301 * This is called here (instead of after the fork but before the specialize) to maintain
302 * consistancy with the code paths for forkAndSpecialize.
303 *
304 * TODO (chriswailes): Look into moving this to immediately after the fork.
305 */
Neil Fuller555d8b72019-01-28 18:29:20 +0000306 ZygoteHooks.postForkCommon();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800307 }
308
Chris Wailesaa1c9622019-01-10 16:55:32 -0800309 private static native void nativeSpecializeBlastula(int uid, int gid, int[] gids,
310 int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
311 boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800312 String[] packagesForUID, String[] visibleVolIDs, String sandboxId);
Narayan Kamath973b4662014-03-31 13:41:26 +0100313
314 /**
Christopher Ferris2980de42017-06-20 16:13:40 -0700315 * Called to do any initialization before starting an application.
316 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800317 static native void nativePreApplicationInit();
Christopher Ferris2980de42017-06-20 16:13:40 -0700318
319 /**
Narayan Kamath973b4662014-03-31 13:41:26 +0100320 * Special method to start the system server process. In addition to the
321 * common actions performed in forkAndSpecialize, the pid of the child
322 * process is recorded such that the death of the child process will cause
323 * zygote to exit.
324 *
325 * @param uid the UNIX uid that the new process should setuid() to after
326 * fork()ing and and before spawning any threads.
327 * @param gid the UNIX gid that the new process should setgid() to after
328 * fork()ing and and before spawning any threads.
329 * @param gids null-ok; a list of UNIX gids that the new process should
330 * setgroups() to after fork and before spawning any threads.
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100331 * @param runtimeFlags bit flags that enable ART features.
Narayan Kamath973b4662014-03-31 13:41:26 +0100332 * @param rlimits null-ok an array of rlimit tuples, with the second
333 * dimension having a length of 3 and representing
334 * (resource, rlim_cur, rlim_max). These are set via the posix
335 * setrlimit(2) call.
336 * @param permittedCapabilities argument for setcap()
337 * @param effectiveCapabilities argument for setcap()
338 *
339 * @return 0 if this is the child, pid of the child
340 * if this is the parent, or -1 on error.
341 */
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100342 public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100343 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000344 ZygoteHooks.preFork();
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800345 // Resets nice priority for zygote process.
346 resetNicePriority();
Narayan Kamath973b4662014-03-31 13:41:26 +0100347 int pid = nativeForkSystemServer(
Chris Wailesaa1c9622019-01-10 16:55:32 -0800348 uid, gid, gids, runtimeFlags, rlimits,
349 permittedCapabilities, effectiveCapabilities);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100350 // Enable tracing as soon as we enter the system_server.
351 if (pid == 0) {
Andreas Gampe8f4eab22017-09-13 18:16:13 -0700352 Trace.setTracingEnabled(true, runtimeFlags);
Narayan Kamathfbb32f62015-06-12 15:34:35 +0100353 }
Neil Fuller555d8b72019-01-28 18:29:20 +0000354 ZygoteHooks.postForkCommon();
Narayan Kamath973b4662014-03-31 13:41:26 +0100355 return pid;
356 }
357
Chris Wailesaa1c9622019-01-10 16:55:32 -0800358 private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
Narayan Kamath973b4662014-03-31 13:41:26 +0100359 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
360
doheon1.lee885b7422016-01-20 13:07:27 +0900361 /**
Robert Sesek54e387d2016-12-02 17:27:50 -0500362 * Lets children of the zygote inherit open file descriptors to this path.
363 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800364 protected static native void nativeAllowFileAcrossFork(String path);
Robert Sesek54e387d2016-12-02 17:27:50 -0500365
366 /**
Martijn Coenen4b988162019-01-28 13:58:45 +0100367 * Lets children of the zygote inherit open file descriptors that belong to the
368 * ApplicationInfo that is passed in.
369 *
370 * @param appInfo ApplicationInfo of the application
371 */
372 protected static void allowAppFilesAcrossFork(ApplicationInfo appInfo) {
373 Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir);
374 if (appInfo.splitSourceDirs != null) {
375 for (String path : appInfo.splitSourceDirs) {
376 Zygote.nativeAllowFileAcrossFork(path);
377 }
378 }
379 // As well as its shared libs
380 if (appInfo.sharedLibraryFiles != null) {
381 for (String path : appInfo.sharedLibraryFiles) {
382 Zygote.nativeAllowFileAcrossFork(path);
383 }
384 }
385 }
386
387 /**
Martijn Coenen86f08a52019-01-03 16:23:01 +0100388 * Installs a seccomp filter that limits setresuid()/setresgid() to the passed-in range
389 * @param uidGidMin The smallest allowed uid/gid
390 * @param uidGidMax The largest allowed uid/gid
391 */
392 native protected static void nativeInstallSeccompUidGidFilter(int uidGidMin, int uidGidMax);
393
394 /**
doheon1.lee885b7422016-01-20 13:07:27 +0900395 * Zygote unmount storage space on initializing.
396 * This method is called once.
397 */
Chris Wailesaa1c9622019-01-10 16:55:32 -0800398 protected static native void nativeUnmountStorageOnInit();
399
Chris Wailescb0b37f2019-01-11 17:04:41 -0800400 /**
401 * Get socket file descriptors (opened by init) from the environment and
402 * store them for access from native code later.
403 *
404 * @param isPrimary True if this is the zygote process, false if it is zygote_secondary
405 */
406 public static void getSocketFDs(boolean isPrimary) {
407 nativeGetSocketFDs(isPrimary);
408 }
409
Chris Wailesaa1c9622019-01-10 16:55:32 -0800410 protected static native void nativeGetSocketFDs(boolean isPrimary);
411
Chris Wailescb0b37f2019-01-11 17:04:41 -0800412 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800413 * Returns the raw string value of a system property.
414 *
415 * Note that Device Config is not available without an application so SystemProperties is used
416 * instead.
417 *
418 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
419 * function to fetch it.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800420 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800421 public static String getSystemProperty(String propertyName, String defaultValue) {
422 return SystemProperties.get(
423 String.join(".",
424 "persist.device_config",
425 DeviceConfig.RuntimeNative.NAMESPACE,
426 propertyName),
427 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800428 }
429
430 /**
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800431 * Returns the value of a system property converted to a boolean using specific logic.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800432 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800433 * Note that Device Config is not available without an application so SystemProperties is used
434 * instead.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800435 *
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800436 * @see SystemProperties.getBoolean
437 *
438 * TODO (chriswailes): Cache the system property location in native code and then write a JNI
439 * function to fetch it.
Chris Wailescb0b37f2019-01-11 17:04:41 -0800440 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800441 public static boolean getSystemPropertyBoolean(String propertyName, Boolean defaultValue) {
442 return SystemProperties.getBoolean(
443 String.join(".",
444 "persist.device_config",
445 DeviceConfig.RuntimeNative.NAMESPACE,
446 propertyName),
447 defaultValue);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800448 }
449
450 /**
451 * @return Number of blastulas currently in the pool
452 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800453 static int getBlastulaPoolCount() {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800454 return nativeGetBlastulaPoolCount();
455 }
456
Chris Wailesaa1c9622019-01-10 16:55:32 -0800457 private static native int nativeGetBlastulaPoolCount();
458
Chris Wailescb0b37f2019-01-11 17:04:41 -0800459 /**
460 * @return The event FD used for communication between the signal handler and the ZygoteServer
461 * poll loop
462 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800463 static FileDescriptor getBlastulaPoolEventFD() {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800464 FileDescriptor fd = new FileDescriptor();
465 fd.setInt$(nativeGetBlastulaPoolEventFD());
466
467 return fd;
468 }
469
Chris Wailesaa1c9622019-01-10 16:55:32 -0800470 private static native int nativeGetBlastulaPoolEventFD();
471
Chris Wailescb0b37f2019-01-11 17:04:41 -0800472 /**
473 * Fork a new blastula process from the zygote
474 *
475 * @param sessionSocketRawFDs Anonymous session sockets that are currently open
476 * @return In the Zygote process this function will always return null; in blastula processes
477 * this function will return a Runnable object representing the new application that is
478 * passed up from blastulaMain.
479 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800480 static Runnable forkBlastula(LocalServerSocket blastulaPoolSocket,
481 int[] sessionSocketRawFDs) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800482 FileDescriptor[] pipeFDs = null;
483
484 try {
485 pipeFDs = Os.pipe2(O_CLOEXEC);
486 } catch (ErrnoException errnoEx) {
487 throw new IllegalStateException("Unable to create blastula pipe.", errnoEx);
488 }
489
490 int pid =
491 nativeForkBlastula(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
492
493 if (pid == 0) {
494 IoUtils.closeQuietly(pipeFDs[0]);
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800495 return blastulaMain(blastulaPoolSocket, pipeFDs[1]);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800496 } else {
497 // The read-end of the pipe will be closed by the native code.
498 // See removeBlastulaTableEntry();
499 IoUtils.closeQuietly(pipeFDs[1]);
500 return null;
501 }
502 }
503
Chris Wailesaa1c9622019-01-10 16:55:32 -0800504 private static native int nativeForkBlastula(int readPipeFD,
505 int writePipeFD,
506 int[] sessionSocketRawFDs);
507
Chris Wailescb0b37f2019-01-11 17:04:41 -0800508 /**
509 * This function is used by blastulas to wait for specialization requests from the system
510 * server.
511 *
512 * @param writePipe The write end of the reporting pipe used to communicate with the poll loop
513 * of the ZygoteServer.
514 * @return A runnable oject representing the new application.
515 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800516 private static Runnable blastulaMain(LocalServerSocket blastulaPoolSocket,
517 FileDescriptor writePipe) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800518 final int pid = Process.myPid();
519
520 LocalSocket sessionSocket = null;
521 DataOutputStream blastulaOutputStream = null;
522 Credentials peerCredentials = null;
523 String[] argStrings = null;
524
525 while (true) {
526 try {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800527 sessionSocket = blastulaPoolSocket.accept();
Chris Wailescb0b37f2019-01-11 17:04:41 -0800528
529 BufferedReader blastulaReader =
530 new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
531 blastulaOutputStream =
532 new DataOutputStream(sessionSocket.getOutputStream());
533
534 peerCredentials = sessionSocket.getPeerCredentials();
535
536 argStrings = readArgumentList(blastulaReader);
537
538 if (argStrings != null) {
539 break;
540 } else {
541 Log.e("Blastula", "Truncated command received.");
542 IoUtils.closeQuietly(sessionSocket);
543 }
544 } catch (IOException ioEx) {
545 Log.e("Blastula", "Failed to read command: " + ioEx.getMessage());
546 IoUtils.closeQuietly(sessionSocket);
547 }
548 }
549
550 ZygoteArguments args = new ZygoteArguments(argStrings);
551
552 // TODO (chriswailes): Should this only be run for debug builds?
553 validateBlastulaCommand(args);
554
555 applyUidSecurityPolicy(args, peerCredentials);
556 applyDebuggerSystemProperty(args);
557
558 int[][] rlimits = null;
559
560 if (args.mRLimits != null) {
561 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
562 }
563
564 // This must happen before the SELinux policy for this process is
565 // changed when specializing.
566 try {
567 // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
568 // Process.ProcessStartResult object.
569 blastulaOutputStream.writeInt(pid);
570 } catch (IOException ioEx) {
571 Log.e("Blastula", "Failed to write response to session socket: " + ioEx.getMessage());
572 System.exit(-1);
573 } finally {
574 IoUtils.closeQuietly(sessionSocket);
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800575 IoUtils.closeQuietly(blastulaPoolSocket);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800576 }
577
578 try {
579 ByteArrayOutputStream buffer =
580 new ByteArrayOutputStream(Zygote.BLASTULA_MANAGEMENT_MESSAGE_BYTES);
581 DataOutputStream outputStream = new DataOutputStream(buffer);
582
583 // This is written as a long so that the blastula reporting pipe and blastula pool
584 // event FD handlers in ZygoteServer.runSelectLoop can be unified. These two cases
585 // should both send/receive 8 bytes.
586 outputStream.writeLong(pid);
587 outputStream.flush();
588
589 Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
590 } catch (Exception ex) {
591 Log.e("Blastula",
592 String.format("Failed to write PID (%d) to pipe (%d): %s",
593 pid, writePipe.getInt$(), ex.getMessage()));
594 System.exit(-1);
595 } finally {
596 IoUtils.closeQuietly(writePipe);
597 }
598
599 specializeBlastula(args.mUid, args.mGid, args.mGids,
600 args.mRuntimeFlags, rlimits, args.mMountExternal,
601 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
602 args.mInstructionSet, args.mAppDataDir, args.mPackageName,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800603 args.mPackagesForUid, args.mVisibleVolIds, args.mSandboxId);
Chris Wailescb0b37f2019-01-11 17:04:41 -0800604
605 if (args.mNiceName != null) {
606 Process.setArgV0(args.mNiceName);
607 }
608
609 // End of the postFork event.
610 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
611
612 return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
613 args.mRemainingArgs,
614 null /* classLoader */);
615 }
616
617 private static final String BLASTULA_ERROR_PREFIX = "Invalid command to blastula: ";
618
619 /**
620 * Checks a set of zygote arguments to see if they can be handled by a blastula. Throws an
621 * exception if an invalid arugment is encountered.
622 * @param args The arguments to test
623 */
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800624 private static void validateBlastulaCommand(ZygoteArguments args) {
Chris Wailescb0b37f2019-01-11 17:04:41 -0800625 if (args.mAbiListQuery) {
626 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--query-abi-list");
627 } else if (args.mPidQuery) {
628 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--get-pid");
629 } else if (args.mPreloadDefault) {
630 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-default");
631 } else if (args.mPreloadPackage != null) {
632 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-package");
633 } else if (args.mPreloadApp != null) {
634 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--preload-app");
635 } else if (args.mStartChildZygote) {
636 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--start-child-zygote");
637 } else if (args.mApiBlacklistExemptions != null) {
638 throw new IllegalArgumentException(
639 BLASTULA_ERROR_PREFIX + "--set-api-blacklist-exemptions");
640 } else if (args.mHiddenApiAccessLogSampleRate != -1) {
641 throw new IllegalArgumentException(
642 BLASTULA_ERROR_PREFIX + "--hidden-api-log-sampling-rate=");
643 } else if (args.mInvokeWith != null) {
644 throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--invoke-with");
645 } else if (args.mPermittedCapabilities != 0 || args.mEffectiveCapabilities != 0) {
646 throw new ZygoteSecurityException("Client may not specify capabilities: "
647 + "permitted=0x" + Long.toHexString(args.mPermittedCapabilities)
648 + ", effective=0x" + Long.toHexString(args.mEffectiveCapabilities));
649 }
650 }
651
652 /**
653 * @return Raw file descriptors for the read-end of blastula reporting pipes.
654 */
655 protected static int[] getBlastulaPipeFDs() {
656 return nativeGetBlastulaPipeFDs();
657 }
658
Chris Wailesaa1c9622019-01-10 16:55:32 -0800659 private static native int[] nativeGetBlastulaPipeFDs();
660
Chris Wailescb0b37f2019-01-11 17:04:41 -0800661 /**
662 * Remove the blastula table entry for the provided process ID.
663 *
664 * @param blastulaPID Process ID of the entry to remove
665 * @return True if the entry was removed; false if it doesn't exist
666 */
667 protected static boolean removeBlastulaTableEntry(int blastulaPID) {
668 return nativeRemoveBlastulaTableEntry(blastulaPID);
669 }
670
Chris Wailesaa1c9622019-01-10 16:55:32 -0800671 private static native boolean nativeRemoveBlastulaTableEntry(int blastulaPID);
672
Chris Wailes2be26262019-01-11 16:14:43 -0800673 /**
674 * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
675 * operation. It may also specify any gid and setgroups() list it chooses.
676 * In factory test mode, it may specify any UID.
677 *
678 * @param args non-null; zygote spawner arguments
679 * @param peer non-null; peer credentials
680 * @throws ZygoteSecurityException
681 */
682 protected static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
683 throws ZygoteSecurityException {
684
685 if (peer.getUid() == Process.SYSTEM_UID) {
686 /* In normal operation, SYSTEM_UID can only specify a restricted
687 * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
688 */
689 boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
690
691 if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
692 throw new ZygoteSecurityException(
693 "System UID may not launch process with UID < "
694 + Process.SYSTEM_UID);
695 }
696 }
697
698 // If not otherwise specified, uid and gid are inherited from peer
699 if (!args.mUidSpecified) {
700 args.mUid = peer.getUid();
701 args.mUidSpecified = true;
702 }
703 if (!args.mGidSpecified) {
704 args.mGid = peer.getGid();
705 args.mGidSpecified = true;
706 }
707 }
708
709 /**
710 * Applies debugger system properties to the zygote arguments.
711 *
712 * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
713 * the debugger state is specified via the "--enable-jdwp" flag
714 * in the spawn request.
715 *
716 * @param args non-null; zygote spawner args
717 */
718 protected static void applyDebuggerSystemProperty(ZygoteArguments args) {
719 if (RoSystemProperties.DEBUGGABLE) {
720 args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
721 }
722 }
723
724 /**
725 * Applies zygote security policy.
726 * Based on the credentials of the process issuing a zygote command:
727 * <ol>
728 * <li> uid 0 (root) may specify --invoke-with to launch Zygote with a
729 * wrapper command.
730 * <li> Any other uid may not specify any invoke-with argument.
731 * </ul>
732 *
733 * @param args non-null; zygote spawner arguments
734 * @param peer non-null; peer credentials
735 * @throws ZygoteSecurityException
736 */
737 protected static void applyInvokeWithSecurityPolicy(ZygoteArguments args, Credentials peer)
738 throws ZygoteSecurityException {
739 int peerUid = peer.getUid();
740
741 if (args.mInvokeWith != null && peerUid != 0
742 && (args.mRuntimeFlags & Zygote.DEBUG_ENABLE_JDWP) == 0) {
743 throw new ZygoteSecurityException("Peer is permitted to specify an"
744 + "explicit invoke-with wrapper command only for debuggable"
745 + "applications.");
746 }
747 }
748
749 /**
750 * Applies invoke-with system properties to the zygote arguments.
751 *
752 * @param args non-null; zygote args
753 */
754 protected static void applyInvokeWithSystemProperty(ZygoteArguments args) {
755 if (args.mInvokeWith == null && args.mNiceName != null) {
756 String property = "wrap." + args.mNiceName;
757 args.mInvokeWith = SystemProperties.get(property);
758 if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
759 args.mInvokeWith = null;
760 }
761 }
762 }
763
764 /**
765 * Reads an argument list from the provided socket
766 * @return Argument list or null if EOF is reached
767 * @throws IOException passed straight through
768 */
769 static String[] readArgumentList(BufferedReader socketReader) throws IOException {
770
771 /**
772 * See android.os.Process.zygoteSendArgsAndGetPid()
773 * Presently the wire format to the zygote process is:
774 * a) a count of arguments (argc, in essence)
775 * b) a number of newline-separated argument strings equal to count
776 *
777 * After the zygote process reads these it will write the pid of
778 * the child or -1 on failure.
779 */
780
781 int argc;
782
783 try {
784 String argc_string = socketReader.readLine();
785
786 if (argc_string == null) {
787 // EOF reached.
788 return null;
789 }
790 argc = Integer.parseInt(argc_string);
791
792 } catch (NumberFormatException ex) {
793 Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
794 throw new IOException("Invalid wire format");
795 }
796
797 // See bug 1092107: large argc can be used for a DOS attack
798 if (argc > MAX_ZYGOTE_ARGC) {
799 throw new IOException("Max arg count exceeded");
800 }
801
802 String[] args = new String[argc];
803 for (int arg_index = 0; arg_index < argc; arg_index++) {
804 args[arg_index] = socketReader.readLine();
805 if (args[arg_index] == null) {
806 // We got an unexpected EOF.
807 throw new IOException("Truncated request");
808 }
809 }
810
811 return args;
812 }
813
Chris Wailescb0b37f2019-01-11 17:04:41 -0800814 /**
Chris Wailescb0b37f2019-01-11 17:04:41 -0800815 * Creates a managed LocalServerSocket object using a file descriptor
816 * created by an init.rc script. The init scripts that specify the
817 * sockets name can be found in system/core/rootdir. The socket is bound
818 * to the file system in the /dev/sockets/ directory, and the file
819 * descriptor is shared via the ANDROID_SOCKET_<socketName> environment
820 * variable.
821 */
822 static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
823 int fileDesc;
824 final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
825
826 try {
827 String env = System.getenv(fullSocketName);
828 fileDesc = Integer.parseInt(env);
829 } catch (RuntimeException ex) {
830 throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
831 }
832
833 try {
834 FileDescriptor fd = new FileDescriptor();
835 fd.setInt$(fileDesc);
836 return new LocalServerSocket(fd);
837 } catch (IOException ex) {
838 throw new RuntimeException(
839 "Error building socket from file descriptor: " + fileDesc, ex);
840 }
841 }
doheon1.lee885b7422016-01-20 13:07:27 +0900842
Orion Hodson46724e72018-10-19 13:05:33 +0100843 private static void callPostForkSystemServerHooks() {
844 // SystemServer specific post fork hooks run before child post fork hooks.
Neil Fuller555d8b72019-01-28 18:29:20 +0000845 ZygoteHooks.postForkSystemServer();
Orion Hodson46724e72018-10-19 13:05:33 +0100846 }
847
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100848 private static void callPostForkChildHooks(int runtimeFlags, boolean isSystemServer,
Robert Sesekd0a190df2018-02-12 18:46:01 -0500849 boolean isZygote, String instructionSet) {
Neil Fuller555d8b72019-01-28 18:29:20 +0000850 ZygoteHooks.postForkChild(runtimeFlags, isSystemServer, isZygote, instructionSet);
Narayan Kamath973b4662014-03-31 13:41:26 +0100851 }
852
Narayan Kamathb49996d2017-02-06 20:24:08 +0000853 /**
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800854 * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
855 * or nice value 0). This updates both the priority value in java.lang.Thread and
856 * the nice value (setpriority).
Narayan Kamathb49996d2017-02-06 20:24:08 +0000857 */
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800858 static void resetNicePriority() {
859 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
860 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100861
862 /**
863 * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
864 * This method throws a runtime exception if exec() failed, otherwise, this
865 * method never returns.
866 *
867 * @param command The shell command to execute.
868 */
869 public static void execShell(String command) {
870 String[] args = { "/system/bin/sh", "-c", command };
871 try {
Elliott Hughes860c5912014-04-28 19:19:13 -0700872 Os.execv(args[0], args);
Narayan Kamath973b4662014-03-31 13:41:26 +0100873 } catch (ErrnoException e) {
874 throw new RuntimeException(e);
875 }
876 }
877
878 /**
879 * Appends quotes shell arguments to the specified string builder.
880 * The arguments are quoted using single-quotes, escaped if necessary,
881 * prefixed with a space, and appended to the command.
882 *
883 * @param command A string builder for the shell command being constructed.
884 * @param args An array of argument strings to be quoted and appended to the command.
885 * @see #execShell(String)
886 */
887 public static void appendQuotedShellArgs(StringBuilder command, String[] args) {
888 for (String arg : args) {
889 command.append(" '").append(arg.replace("'", "'\\''")).append("'");
890 }
891 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100892}