blob: c208ce3276c6f1a71bf15fd6329292ab70a62727 [file] [log] [blame]
Narayan Kamath973b4662014-03-31 13:41:26 +01001/*
2 * Copyright (C) 2008 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
Chris Waileseac7f4e2019-01-17 14:57:10 -080017/*
18 * Disable optimization of this file if we are compiling with the address
19 * sanitizer. This is a mitigation for b/122921367 and can be removed once the
20 * bug is fixed.
21 */
22#if __has_feature(address_sanitizer)
23#pragma clang optimize off
24#endif
25
Colin Cross18cd9f52014-06-13 12:58:55 -070026#define LOG_TAG "Zygote"
Narayan Kamath973b4662014-03-31 13:41:26 +010027
28// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
29#include <sys/mount.h>
30#include <linux/fs.h>
31
Chris Wailesaa1c9622019-01-10 16:55:32 -080032#include <array>
33#include <atomic>
Chris Wailesaf594fc2018-11-02 11:00:07 -070034#include <functional>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070035#include <list>
Chris Wailesaf594fc2018-11-02 11:00:07 -070036#include <optional>
Andreas Gampeb053cce2015-11-17 16:38:59 -080037#include <sstream>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070038#include <string>
Chris Wailesaa1c9622019-01-10 16:55:32 -080039#include <string_view>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070040
Josh Gaod7951102018-06-26 16:05:12 -070041#include <android/fdsan.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080042#include <arpa/inet.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070043#include <fcntl.h>
Dan Albert46d84442014-11-18 16:07:51 -080044#include <grp.h>
45#include <inttypes.h>
Christopher Ferrisab16dd12017-05-15 16:50:29 -070046#include <malloc.h>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070047#include <mntent.h>
Narayan Kamath973b4662014-03-31 13:41:26 +010048#include <paths.h>
49#include <signal.h>
50#include <stdlib.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070051#include <sys/capability.h>
Robert Seseke4f8d692016-09-13 19:13:01 -040052#include <sys/cdefs.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080053#include <sys/eventfd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070054#include <sys/personality.h>
55#include <sys/prctl.h>
56#include <sys/resource.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080057#include <sys/socket.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070058#include <sys/stat.h>
Vitalii Tomkiv5cbce852016-05-18 17:43:02 -070059#include <sys/time.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070060#include <sys/types.h>
61#include <sys/utsname.h>
62#include <sys/wait.h>
Dan Albert46d84442014-11-18 16:07:51 -080063#include <unistd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070064
Chris Wailesaa1c9622019-01-10 16:55:32 -080065#include <android-base/logging.h>
Minchan Kim5fa8af22018-06-27 11:32:40 +090066#include <android-base/properties.h>
Carmen Jacksondd401252017-02-23 15:21:10 -080067#include <android-base/file.h>
68#include <android-base/stringprintf.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080069#include <android-base/unique_fd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070070#include <cutils/fs.h>
71#include <cutils/multiuser.h>
Sharvil Nanavati4990e4f2014-06-29 17:06:52 -070072#include <private/android_filesystem_config.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070073#include <utils/String8.h>
74#include <selinux/android.h>
Victor Hsiehc8176ef2018-01-08 12:43:00 -080075#include <seccomp_policy.h>
Howard Ro27330412018-10-02 12:08:28 -070076#include <stats_event_list.h>
Colin Cross0161bbc2014-06-03 13:26:58 -070077#include <processgroup/processgroup.h>
Suren Baghdasaryane4433262019-01-04 12:16:57 -080078#include <processgroup/sched_policy.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070079
Andreas Gampeed6b9df2014-11-20 22:02:20 -080080#include "core_jni_helpers.h"
Steven Moreland2279b252017-07-19 09:50:45 -070081#include <nativehelper/JNIHelp.h>
82#include <nativehelper/ScopedLocalRef.h>
83#include <nativehelper/ScopedPrimitiveArray.h>
84#include <nativehelper/ScopedUtfChars.h>
Robert Sesek8225b7c2016-12-16 14:02:31 -050085#include "fd_utils.h"
Narayan Kamath973b4662014-03-31 13:41:26 +010086
jgu212eacd062014-09-10 06:55:07 -040087#include "nativebridge/native_bridge.h"
88
Narayan Kamath973b4662014-03-31 13:41:26 +010089namespace {
90
Chris Wailesaa1c9622019-01-10 16:55:32 -080091// TODO (chriswailes): Add a function to initialize native Zygote data.
92// TODO (chriswailes): Fix mixed indentation style (2 and 4 spaces).
93
Chris Wailesaf594fc2018-11-02 11:00:07 -070094using namespace std::placeholders;
95
Narayan Kamath973b4662014-03-31 13:41:26 +010096using android::String8;
Sudheer Shanka663b1042018-07-30 17:34:21 -070097using android::base::StringAppendF;
Carmen Jacksondd401252017-02-23 15:21:10 -080098using android::base::StringPrintf;
99using android::base::WriteStringToFile;
Minchan Kim5fa8af22018-06-27 11:32:40 +0900100using android::base::GetBoolProperty;
Narayan Kamath973b4662014-03-31 13:41:26 +0100101
Andreas Gamped5758f62018-03-12 12:08:55 -0700102#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
103 append(StringPrintf(__VA_ARGS__))
104
Chris Wailesaa1c9622019-01-10 16:55:32 -0800105// This type is duplicated in fd_utils.h
106typedef const std::function<void(std::string)>& fail_fn_t;
107
Narayan Kamath973b4662014-03-31 13:41:26 +0100108static pid_t gSystemServerPid = 0;
109
Sudheer Shanka663b1042018-07-30 17:34:21 -0700110static const char kIsolatedStorage[] = "persist.sys.isolated_storage";
Sudheer Shankaa3801582019-01-17 17:19:11 -0800111static const char kIsolatedStorageSnapshot[] = "sys.isolated_storage_snapshot";
Narayan Kamath973b4662014-03-31 13:41:26 +0100112static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
113static jclass gZygoteClass;
Orion Hodson46724e72018-10-19 13:05:33 +0100114static jmethodID gCallPostForkSystemServerHooks;
Narayan Kamath973b4662014-03-31 13:41:26 +0100115static jmethodID gCallPostForkChildHooks;
116
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800117static bool g_is_security_enforced = true;
118
Chris Wailesaa1c9622019-01-10 16:55:32 -0800119/**
120 * The maximum number of characters (not including a null terminator) that a
121 * process name may contain.
122 */
123static constexpr size_t MAX_NAME_LENGTH = 15;
124
125/**
126 * The prefix string for environmental variables storing socket FDs created by
127 * init.
128 */
129
130static constexpr std::string_view ANDROID_SOCKET_PREFIX("ANDROID_SOCKET_");
131
132/**
133 * The file descriptor for the Zygote socket opened by init.
134 */
135
136static int gZygoteSocketFD = -1;
137
138/**
139 * The file descriptor for the Blastula pool socket opened by init.
140 */
141
142static int gBlastulaPoolSocketFD = -1;
143
144/**
145 * The number of Blastulas currently in this Zygote's pool.
146 */
147static std::atomic_uint32_t gBlastulaPoolCount = 0;
148
149/**
150 * Event file descriptor used to communicate reaped blastulas to the
151 * ZygoteServer.
152 */
153static int gBlastulaPoolEventFD = -1;
154
155/**
156 * The maximum value that the gBlastulaPoolMax variable may take. This value
157 * is a mirror of Zygote.BLASTULA_POOL_MAX_LIMIT
158 */
159static constexpr int BLASTULA_POOL_MAX_LIMIT = 10;
160
161/**
162 * A helper class containing accounting information for Blastulas.
163 */
164class BlastulaTableEntry {
165 public:
166 struct EntryStorage {
167 int32_t pid;
168 int32_t read_pipe_fd;
169
170 bool operator!=(const EntryStorage& other) {
171 return pid != other.pid || read_pipe_fd != other.read_pipe_fd;
172 }
173 };
174
175 private:
176 static constexpr EntryStorage INVALID_ENTRY_VALUE = {-1, -1};
177
178 std::atomic<EntryStorage> mStorage;
179 static_assert(decltype(mStorage)::is_always_lock_free);
180
181 public:
182 constexpr BlastulaTableEntry() : mStorage(INVALID_ENTRY_VALUE) {}
183
184 /**
185 * If the provided PID matches the one stored in this entry, the entry will
186 * be invalidated and the associated file descriptor will be closed. If the
187 * PIDs don't match nothing will happen.
188 *
189 * @param pid The ID of the process who's entry we want to clear.
190 * @return True if the entry was cleared; false otherwise
191 */
192 bool ClearForPID(int32_t pid) {
193 EntryStorage storage = mStorage.load();
194
195 if (storage.pid == pid) {
196 /*
197 * There are three possible outcomes from this compare-and-exchange:
198 * 1) It succeeds, in which case we close the FD
199 * 2) It fails and the new value is INVALID_ENTRY_VALUE, in which case
200 * the entry has already been cleared.
201 * 3) It fails and the new value isn't INVALID_ENTRY_VALUE, in which
202 * case the entry has already been cleared and re-used.
203 *
204 * In all three cases the goal of the caller has been met and we can
205 * return true.
206 */
207 if (mStorage.compare_exchange_strong(storage, INVALID_ENTRY_VALUE)) {
208 close(storage.read_pipe_fd);
209 }
210
211 return true;
212 } else {
213 return false;
214 }
215 }
216
217 /**
218 * @return A copy of the data stored in this entry.
219 */
220 std::optional<EntryStorage> GetValues() {
221 EntryStorage storage = mStorage.load();
222
223 if (storage != INVALID_ENTRY_VALUE) {
224 return storage;
225 } else {
226 return std::nullopt;
227 }
228 }
229
230 /**
231 * Sets the entry to the given values if it is currently invalid.
232 *
233 * @param pid The process ID for the new entry.
234 * @param read_pipe_fd The read end of the blastula control pipe for this
235 * process.
236 * @return True if the entry was set; false otherwise.
237 */
238 bool SetIfInvalid(int32_t pid, int32_t read_pipe_fd) {
239 EntryStorage new_value_storage;
240
241 new_value_storage.pid = pid;
242 new_value_storage.read_pipe_fd = read_pipe_fd;
243
244 EntryStorage expected = INVALID_ENTRY_VALUE;
245
246 return mStorage.compare_exchange_strong(expected, new_value_storage);
247 }
248};
249
250/**
251 * A table containing information about the Blastulas currently in the pool.
252 *
253 * Multiple threads may be attempting to modify the table, either from the
254 * signal handler or from the ZygoteServer poll loop. Atomic loads/stores in
255 * the BlastulaTableEntry class prevent data races during these concurrent
256 * operations.
257 */
258static std::array<BlastulaTableEntry, BLASTULA_POOL_MAX_LIMIT> gBlastulaTable;
259
260/**
261 * The list of open zygote file descriptors.
262 */
263static FileDescriptorTable* gOpenFdTable = nullptr;
264
Narayan Kamath973b4662014-03-31 13:41:26 +0100265// Must match values in com.android.internal.os.Zygote.
266enum MountExternalKind {
267 MOUNT_EXTERNAL_NONE = 0,
Jeff Sharkey48877892015-03-18 11:27:19 -0700268 MOUNT_EXTERNAL_DEFAULT = 1,
Jeff Sharkey9527b222015-06-24 15:24:48 -0700269 MOUNT_EXTERNAL_READ = 2,
270 MOUNT_EXTERNAL_WRITE = 3,
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800271 MOUNT_EXTERNAL_LEGACY = 4,
272 MOUNT_EXTERNAL_INSTALLER = 5,
273 MOUNT_EXTERNAL_FULL = 6,
Narayan Kamath973b4662014-03-31 13:41:26 +0100274};
275
Orion Hodson8d005a62018-12-05 12:28:53 +0000276// Must match values in com.android.internal.os.Zygote.
277enum RuntimeFlags : uint32_t {
278 DEBUG_ENABLE_JDWP = 1,
Yabin Cui4d8546d2019-01-29 16:29:20 -0800279 PROFILE_FROM_SHELL = 1 << 15,
Orion Hodson8d005a62018-12-05 12:28:53 +0000280};
281
Chris Wailesaa1c9622019-01-10 16:55:32 -0800282// Forward declaration so we don't have to move the signal handler.
283static bool RemoveBlastulaTableEntry(pid_t blastula_pid);
284
Andreas Gampeb053cce2015-11-17 16:38:59 -0800285static void RuntimeAbort(JNIEnv* env, int line, const char* msg) {
286 std::ostringstream oss;
287 oss << __FILE__ << ":" << line << ": " << msg;
288 env->FatalError(oss.str().c_str());
Narayan Kamath973b4662014-03-31 13:41:26 +0100289}
290
291// This signal handler is for zygote mode, since the zygote must reap its children
292static void SigChldHandler(int /*signal_number*/) {
293 pid_t pid;
294 int status;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800295 int64_t blastulas_removed = 0;
Narayan Kamath973b4662014-03-31 13:41:26 +0100296
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700297 // It's necessary to save and restore the errno during this function.
298 // Since errno is stored per thread, changing it here modifies the errno
299 // on the thread on which this signal handler executes. If a signal occurs
300 // between a call and an errno check, it's possible to get the errno set
301 // here.
302 // See b/23572286 for extra information.
303 int saved_errno = errno;
304
Narayan Kamath973b4662014-03-31 13:41:26 +0100305 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
306 // Log process-death status that we care about. In general it is
307 // not safe to call LOG(...) from a signal handler because of
308 // possible reentrancy. However, we know a priori that the
309 // current implementation of LOG() is safe to call from a SIGCHLD
310 // handler in the zygote process. If the LOG() implementation
311 // changes its locking strategy or its use of syscalls within the
312 // lazy-init critical section, its use here may become unsafe.
313 if (WIFEXITED(status)) {
Josh Gao6d747ca2017-08-02 12:54:05 -0700314 ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
Narayan Kamath973b4662014-03-31 13:41:26 +0100315 } else if (WIFSIGNALED(status)) {
Josh Gao6d747ca2017-08-02 12:54:05 -0700316 ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
Narayan Kamath973b4662014-03-31 13:41:26 +0100317 if (WCOREDUMP(status)) {
318 ALOGI("Process %d dumped core.", pid);
319 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100320 }
321
322 // If the just-crashed process is the system_server, bring down zygote
323 // so that it is restarted by init and system server will be restarted
324 // from there.
325 if (pid == gSystemServerPid) {
Dan Albert46d84442014-11-18 16:07:51 -0800326 ALOGE("Exit zygote because system server (%d) has terminated", pid);
Narayan Kamath973b4662014-03-31 13:41:26 +0100327 kill(getpid(), SIGKILL);
328 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800329
330 // Check to see if the PID is in the blastula pool and remove it if it is.
331 if (RemoveBlastulaTableEntry(pid)) {
332 ++blastulas_removed;
333 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100334 }
335
Narayan Kamath160992d2014-04-14 14:46:07 +0100336 // Note that we shouldn't consider ECHILD an error because
337 // the secondary zygote might have no children left to wait for.
338 if (pid < 0 && errno != ECHILD) {
339 ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100340 }
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700341
Chris Wailesaa1c9622019-01-10 16:55:32 -0800342 if (blastulas_removed > 0) {
343 if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) {
344 // If this write fails something went terribly wrong. We will now kill
345 // the zygote and let the system bring it back up.
346 ALOGE("Zygote failed to write to blastula pool event FD: %s", strerror(errno));
347 kill(getpid(), SIGKILL);
348 }
349 }
350
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700351 errno = saved_errno;
Narayan Kamath973b4662014-03-31 13:41:26 +0100352}
353
yuanhao435e84b2018-01-15 15:37:02 +0800354// Configures the SIGCHLD/SIGHUP handlers for the zygote process. This is
355// configured very late, because earlier in the runtime we may fork() and
356// exec() other processes, and we want to waitpid() for those rather than
Narayan Kamath973b4662014-03-31 13:41:26 +0100357// have them be harvested immediately.
358//
yuanhao435e84b2018-01-15 15:37:02 +0800359// Ignore SIGHUP because all processes forked by the zygote are in the same
360// process group as the zygote and we don't want to be notified if we become
361// an orphaned group and have one or more stopped processes. This is not a
362// theoretical concern :
363// - we can become an orphaned group if one of our direct descendants forks
364// and is subsequently killed before its children.
365// - crash_dump routinely STOPs the process it's tracing.
366//
367// See issues b/71965619 and b/25567761 for further details.
368//
Narayan Kamath973b4662014-03-31 13:41:26 +0100369// This ends up being called repeatedly before each fork(), but there's
370// no real harm in that.
yuanhao435e84b2018-01-15 15:37:02 +0800371static void SetSignalHandlers() {
372 struct sigaction sig_chld = {};
373 sig_chld.sa_handler = SigChldHandler;
Narayan Kamath973b4662014-03-31 13:41:26 +0100374
Chris Wailesaa1c9622019-01-10 16:55:32 -0800375 if (sigaction(SIGCHLD, &sig_chld, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700376 ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100377 }
yuanhao435e84b2018-01-15 15:37:02 +0800378
379 struct sigaction sig_hup = {};
380 sig_hup.sa_handler = SIG_IGN;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800381 if (sigaction(SIGHUP, &sig_hup, nullptr) < 0) {
yuanhao435e84b2018-01-15 15:37:02 +0800382 ALOGW("Error setting SIGHUP handler: %s", strerror(errno));
383 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100384}
385
386// Sets the SIGCHLD handler back to default behavior in zygote children.
yuanhao435e84b2018-01-15 15:37:02 +0800387static void UnsetChldSignalHandler() {
Narayan Kamath973b4662014-03-31 13:41:26 +0100388 struct sigaction sa;
389 memset(&sa, 0, sizeof(sa));
390 sa.sa_handler = SIG_DFL;
391
Chris Wailesaa1c9622019-01-10 16:55:32 -0800392 if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700393 ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100394 }
395}
396
397// Calls POSIX setgroups() using the int[] object as an argument.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800398// A nullptr argument is tolerated.
399static void SetGids(JNIEnv* env, jintArray managed_gids, fail_fn_t fail_fn) {
400 if (managed_gids == nullptr) {
401 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100402 }
403
Chris Wailesaa1c9622019-01-10 16:55:32 -0800404 ScopedIntArrayRO gids(env, managed_gids);
405 if (gids.get() == nullptr) {
406 fail_fn(CREATE_ERROR("Getting gids int array failed"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100407 }
Andreas Gamped5758f62018-03-12 12:08:55 -0700408
Chris Wailesaa1c9622019-01-10 16:55:32 -0800409 if (setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0])) == -1) {
410 fail_fn(CREATE_ERROR("setgroups failed: %s, gids.size=%zu", strerror(errno), gids.size()));
411 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100412}
413
414// Sets the resource limits via setrlimit(2) for the values in the
415// two-dimensional array of integers that's passed in. The second dimension
Chris Wailesaa1c9622019-01-10 16:55:32 -0800416// contains a tuple of length 3: (resource, rlim_cur, rlim_max). nullptr is
Narayan Kamath973b4662014-03-31 13:41:26 +0100417// treated as an empty array.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800418static void SetRLimits(JNIEnv* env, jobjectArray managed_rlimits, fail_fn_t fail_fn) {
419 if (managed_rlimits == nullptr) {
420 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100421 }
422
423 rlimit rlim;
424 memset(&rlim, 0, sizeof(rlim));
425
Chris Wailesaa1c9622019-01-10 16:55:32 -0800426 for (int i = 0; i < env->GetArrayLength(managed_rlimits); ++i) {
427 ScopedLocalRef<jobject>
428 managed_rlimit_object(env, env->GetObjectArrayElement(managed_rlimits, i));
429 ScopedIntArrayRO rlimit_handle(env, reinterpret_cast<jintArray>(managed_rlimit_object.get()));
430
431 if (rlimit_handle.size() != 3) {
432 fail_fn(CREATE_ERROR("rlimits array must have a second dimension of size 3"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100433 }
434
Chris Wailesaa1c9622019-01-10 16:55:32 -0800435 rlim.rlim_cur = rlimit_handle[1];
436 rlim.rlim_max = rlimit_handle[2];
Narayan Kamath973b4662014-03-31 13:41:26 +0100437
Chris Wailesaa1c9622019-01-10 16:55:32 -0800438 if (setrlimit(rlimit_handle[0], &rlim) == -1) {
439 fail_fn(CREATE_ERROR("setrlimit(%d, {%ld, %ld}) failed",
440 rlimit_handle[0], rlim.rlim_cur, rlim.rlim_max));
Narayan Kamath973b4662014-03-31 13:41:26 +0100441 }
442 }
443}
444
Orion Hodson8d005a62018-12-05 12:28:53 +0000445static void EnableDebugger() {
446 // To let a non-privileged gdbserver attach to this
447 // process, we must set our dumpable flag.
448 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
449 ALOGE("prctl(PR_SET_DUMPABLE) failed");
450 }
451
452 // A non-privileged native debugger should be able to attach to the debuggable app, even if Yama
453 // is enabled (see kernel/Documentation/security/Yama.txt).
454 if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) {
455 // if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this
456 // case since it's expected behaviour.
457 if (errno != EINVAL) {
458 ALOGE("prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed");
459 }
460 }
461
Orion Hodson2b71ad02018-12-07 16:44:33 +0000462 // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
463 if (!GetBoolProperty("persist.zygote.core_dump", false)) {
464 // Set the soft limit on core dump size to 0 without changing the hard limit.
465 rlimit rl;
466 if (getrlimit(RLIMIT_CORE, &rl) == -1) {
467 ALOGE("getrlimit(RLIMIT_CORE) failed");
468 } else {
469 rl.rlim_cur = 0;
470 if (setrlimit(RLIMIT_CORE, &rl) == -1) {
471 ALOGE("setrlimit(RLIMIT_CORE) failed");
472 }
Orion Hodson8d005a62018-12-05 12:28:53 +0000473 }
474 }
475}
476
Narayan Kamath973b4662014-03-31 13:41:26 +0100477// The debug malloc library needs to know whether it's the zygote or a child.
478extern "C" int gMallocLeakZygoteChild;
479
Christopher Ferris76de39e2017-06-20 16:13:40 -0700480static void PreApplicationInit() {
481 // The child process sets this to indicate it's not the zygote.
482 gMallocLeakZygoteChild = 1;
483
484 // Set the jemalloc decay time to 1.
485 mallopt(M_DECAY_TIME, 1);
486}
487
Martijn Coenen86f08a52019-01-03 16:23:01 +0100488static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800489 if (!g_is_security_enforced) {
490 ALOGI("seccomp disabled by setenforce 0");
491 return;
492 }
493
494 // Apply system or app filter based on uid.
Victor Hsiehfa046a12018-03-28 16:26:28 -0700495 if (uid >= AID_APP_START) {
Martijn Coenen86f08a52019-01-03 16:23:01 +0100496 if (is_child_zygote) {
Martijn Coenen6ef16802019-01-18 16:40:01 +0100497 set_app_zygote_seccomp_filter();
Martijn Coenen86f08a52019-01-03 16:23:01 +0100498 } else {
499 set_app_seccomp_filter();
500 }
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800501 } else {
502 set_system_seccomp_filter();
503 }
504}
505
Chris Wailesaa1c9622019-01-10 16:55:32 -0800506static void EnableKeepCapabilities(fail_fn_t fail_fn) {
507 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
508 fail_fn(CREATE_ERROR("prctl(PR_SET_KEEPCAPS) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100509 }
510}
511
Chris Wailesaa1c9622019-01-10 16:55:32 -0800512static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) {
513 for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {;
514 if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100515 if (errno == EINVAL) {
516 ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
517 "your kernel is compiled with file capabilities support");
518 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800519 fail_fn(CREATE_ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100520 }
521 }
522 }
523}
524
Chris Wailesaa1c9622019-01-10 16:55:32 -0800525static void SetInheritable(uint64_t inheritable, fail_fn_t fail_fn) {
Josh Gao45dab782017-02-01 14:56:09 -0800526 __user_cap_header_struct capheader;
527 memset(&capheader, 0, sizeof(capheader));
528 capheader.version = _LINUX_CAPABILITY_VERSION_3;
529 capheader.pid = 0;
530
531 __user_cap_data_struct capdata[2];
532 if (capget(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800533 fail_fn(CREATE_ERROR("capget failed: %s", strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800534 }
535
536 capdata[0].inheritable = inheritable;
537 capdata[1].inheritable = inheritable >> 32;
538
539 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800540 fail_fn(CREATE_ERROR("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800541 }
542}
543
Chris Wailesaa1c9622019-01-10 16:55:32 -0800544static void SetCapabilities(uint64_t permitted, uint64_t effective, uint64_t inheritable,
545 fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100546 __user_cap_header_struct capheader;
547 memset(&capheader, 0, sizeof(capheader));
548 capheader.version = _LINUX_CAPABILITY_VERSION_3;
549 capheader.pid = 0;
550
551 __user_cap_data_struct capdata[2];
552 memset(&capdata, 0, sizeof(capdata));
553 capdata[0].effective = effective;
554 capdata[1].effective = effective >> 32;
555 capdata[0].permitted = permitted;
556 capdata[1].permitted = permitted >> 32;
Josh Gao45dab782017-02-01 14:56:09 -0800557 capdata[0].inheritable = inheritable;
558 capdata[1].inheritable = inheritable >> 32;
Narayan Kamath973b4662014-03-31 13:41:26 +0100559
560 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800561 fail_fn(CREATE_ERROR("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") "
562 "failed: %s", permitted, effective, inheritable, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100563 }
564}
565
Chris Wailesaa1c9622019-01-10 16:55:32 -0800566static void SetSchedulerPolicy(fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100567 errno = -set_sched_policy(0, SP_DEFAULT);
568 if (errno != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800569 fail_fn(CREATE_ERROR("set_sched_policy(0, SP_DEFAULT) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100570 }
571}
572
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700573static int UnmountTree(const char* path) {
574 size_t path_len = strlen(path);
575
576 FILE* fp = setmntent("/proc/mounts", "r");
Chris Wailesaa1c9622019-01-10 16:55:32 -0800577 if (fp == nullptr) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700578 ALOGE("Error opening /proc/mounts: %s", strerror(errno));
579 return -errno;
580 }
581
582 // Some volumes can be stacked on each other, so force unmount in
583 // reverse order to give us the best chance of success.
584 std::list<std::string> toUnmount;
585 mntent* mentry;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800586 while ((mentry = getmntent(fp)) != nullptr) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700587 if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
588 toUnmount.push_front(std::string(mentry->mnt_dir));
589 }
590 }
591 endmntent(fp);
592
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800593 for (const auto& path : toUnmount) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700594 if (umount2(path.c_str(), MNT_DETACH)) {
595 ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
596 }
597 }
598 return 0;
599}
600
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800601static void CreateDir(const std::string& dir,
602 mode_t mode, uid_t uid, gid_t gid,
603 fail_fn_t fail_fn) {
604 if (TEMP_FAILURE_RETRY(access(dir.c_str(), F_OK)) == 0) {
605 return;
606 } else if (errno != ENOENT) {
607 fail_fn(CREATE_ERROR("Failed to stat %s: %s", dir.c_str(), strerror(errno)));
608 }
609 if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
610 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s",
611 dir.c_str(), strerror(errno)));
612 }
613}
614
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800615static void CreatePkgSandboxTarget(uid_t uid, const std::string& package_name, fail_fn_t fail_fn) {
Sudheer Shanka663b1042018-07-30 17:34:21 -0700616 // Create /mnt/user/0/package/<package-name>
617 userid_t user_id = multiuser_get_user_id(uid);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700618 std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800619 CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800620
Sudheer Shanka663b1042018-07-30 17:34:21 -0700621 StringAppendF(&pkg_sandbox_dir, "/package");
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800622 CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800623
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700624 StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str());
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800625 CreateDir(pkg_sandbox_dir, 0755, uid, uid, fail_fn);
Sudheer Shanka663b1042018-07-30 17:34:21 -0700626}
627
Chris Wailesaa1c9622019-01-10 16:55:32 -0800628static void BindMount(const std::string& sourceDir, const std::string& targetDir,
629 fail_fn_t fail_fn) {
630 if (TEMP_FAILURE_RETRY(mount(sourceDir.c_str(), targetDir.c_str(), nullptr,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800631 MS_BIND, nullptr)) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800632 fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
633 sourceDir.c_str(), targetDir.c_str(), strerror(errno)));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800634 }
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800635}
636
Chris Wailesaa1c9622019-01-10 16:55:32 -0800637static void MountPkgSpecificDir(const std::string& mntSourceRoot,
638 const std::string& mntTargetRoot,
639 const std::string& packageName,
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800640 uid_t uid,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800641 const char* dirName,
642 fail_fn_t fail_fn) {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700643 std::string mntSourceDir = StringPrintf("%s/Android/%s/%s",
644 mntSourceRoot.c_str(), dirName, packageName.c_str());
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800645
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700646 std::string mntTargetDir = StringPrintf("%s/Android/%s/%s",
647 mntTargetRoot.c_str(), dirName, packageName.c_str());
Chris Wailesaa1c9622019-01-10 16:55:32 -0800648
649 BindMount(mntSourceDir, mntTargetDir, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700650}
651
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800652static void CreateSubDirs(int dirfd, const std::string& parentDirPath,
653 const std::vector<std::string>& subDirs,
654 fail_fn_t fail_fn) {
655 for (auto& dirName : subDirs) {
656 struct stat sb;
657 if (TEMP_FAILURE_RETRY(fstatat(dirfd, dirName.c_str(), &sb, 0)) == 0) {
658 if (S_ISDIR(sb.st_mode)) {
659 continue;
660 } else if (TEMP_FAILURE_RETRY(unlinkat(dirfd, dirName.c_str(), 0)) == -1) {
661 fail_fn(CREATE_ERROR("Failed to unlinkat on %s/%s: %s",
662 parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
663 }
664 } else if (errno != ENOENT) {
665 fail_fn(CREATE_ERROR("Failed to fstatat on %s/%s: %s",
666 parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
667 }
668 if (TEMP_FAILURE_RETRY(mkdirat(dirfd, dirName.c_str(), 0700)) == -1) {
669 fail_fn(CREATE_ERROR("Failed to mkdirat on %s/%s: %s",
670 parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
671 }
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800672 }
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800673}
674
675static void EnsurePkgSpecificDirs(const std::string& path,
676 const std::vector<std::string>& packageNames,
677 bool createSandboxDir,
678 fail_fn_t fail_fn) {
679 std::string androidDir = StringPrintf("%s/Android", path.c_str());
680 android::base::unique_fd androidFd(
681 open(androidDir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
682 if (androidFd.get() < 0) {
683 if (errno == ENOENT || errno == ENOTDIR) {
684 if (errno == ENOTDIR && TEMP_FAILURE_RETRY(unlink(androidDir.c_str())) == -1) {
685 fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
686 androidDir.c_str(), strerror(errno)));
687 }
688 if (TEMP_FAILURE_RETRY(mkdir(androidDir.c_str(), 0700)) == -1) {
689 fail_fn(CREATE_ERROR("Failed to mkdir %s: %s",
690 androidDir.c_str(), strerror(errno)));
691 }
692 androidFd.reset(open(androidDir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
693 }
694
695 if (androidFd.get() < 0) {
696 fail_fn(CREATE_ERROR("Failed to open %s: %s", androidDir.c_str(), strerror(errno)));
697 }
698 }
699
700 std::vector<std::string> dataMediaObbDirs = {"data", "media", "obb"};
701 if (createSandboxDir) {
702 dataMediaObbDirs.push_back("sandbox");
703 }
704 CreateSubDirs(androidFd.get(), androidDir, dataMediaObbDirs, fail_fn);
705 if (createSandboxDir) {
706 dataMediaObbDirs.pop_back();
707 }
708 for (auto& dirName : dataMediaObbDirs) {
709 std::string dataDir = StringPrintf("%s/%s", androidDir.c_str(), dirName.c_str());
710 android::base::unique_fd dataFd(
711 openat(androidFd, dirName.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
712 if (dataFd.get() < 0) {
713 fail_fn(CREATE_ERROR("Failed to openat %s/%s: %s",
714 androidDir.c_str(), dirName.c_str(), strerror(errno)));
715 }
716 CreateSubDirs(dataFd.get(), dataDir, packageNames, fail_fn);
717 }
718}
719
720static void CreatePkgSandboxSource(const std::string& sandboxSource, fail_fn_t fail_fn) {
721
722 struct stat sb;
723 if (TEMP_FAILURE_RETRY(stat(sandboxSource.c_str(), &sb)) == 0) {
724 if (S_ISDIR(sb.st_mode)) {
725 return;
726 } else if (TEMP_FAILURE_RETRY(unlink(sandboxSource.c_str())) == -1) {
727 fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
728 sandboxSource.c_str(), strerror(errno)));
729 }
730 } else if (errno != ENOENT) {
731 fail_fn(CREATE_ERROR("Failed to stat %s: %s",
732 sandboxSource.c_str(), strerror(errno)));
733 }
734 if (TEMP_FAILURE_RETRY(mkdir(sandboxSource.c_str(), 0700)) == -1) {
735 fail_fn(CREATE_ERROR("Failed to mkdir %s: %s",
736 sandboxSource.c_str(), strerror(errno)));
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800737 }
738}
739
Chris Wailesaa1c9622019-01-10 16:55:32 -0800740static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
741 const std::vector<std::string>& volumeLabels,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800742 bool mountAllObbs, const std::string& sandboxId,
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800743 userid_t userId, uid_t uid, fail_fn_t fail_fn) {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700744 for (auto& label : volumeLabels) {
745 std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
746 std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
747 if (label == "emulated") {
748 StringAppendF(&mntSource, "/%d", userId);
749 StringAppendF(&mntTarget, "/%d", userId);
750 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800751
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800752 if (TEMP_FAILURE_RETRY(access(mntSource.c_str(), F_OK)) == -1) {
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800753 ALOGE("Can't access %s: %s", mntSource.c_str(), strerror(errno));
754 continue;
755 }
756
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800757 // Ensure /mnt/runtime/write/emulated/0/Android/{data,media,obb}
758 EnsurePkgSpecificDirs(mntSource, packageNames, true, fail_fn);
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800759
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800760 std::string sandboxSource = StringPrintf("%s/Android/sandbox/%s",
761 mntSource.c_str(), sandboxId.c_str());
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800762 CreatePkgSandboxSource(sandboxSource, fail_fn);
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800763 BindMount(sandboxSource, mntTarget, fail_fn);
764
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800765 // Ensure /storage/emulated/0/Android/{data,media,obb}
766 EnsurePkgSpecificDirs(mntTarget, packageNames, false, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700767 for (auto& package : packageNames) {
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800768 MountPkgSpecificDir(mntSource, mntTarget, package, uid, "data", fail_fn);
769 MountPkgSpecificDir(mntSource, mntTarget, package, uid, "media", fail_fn);
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800770 if (!mountAllObbs) {
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800771 MountPkgSpecificDir(mntSource, mntTarget, package, uid, "obb", fail_fn);
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800772 }
773 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800774
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800775 if (mountAllObbs) {
776 StringAppendF(&mntSource, "/Android/obb");
777 StringAppendF(&mntTarget, "/Android/obb");
Chris Wailesaa1c9622019-01-10 16:55:32 -0800778 BindMount(mntSource, mntTarget, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700779 }
780 }
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700781}
782
Narayan Kamath973b4662014-03-31 13:41:26 +0100783// Create a private mount namespace and bind mount appropriate emulated
784// storage for the given user.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800785static void MountEmulatedStorage(uid_t uid, jint mount_mode,
786 bool force_mount_namespace, const std::string& package_name,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700787 const std::vector<std::string>& packages_for_uid,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800788 const std::vector<std::string>& visible_vol_ids, const std::string& sandbox_id,
789 fail_fn_t fail_fn) {
Jeff Sharkey9527b222015-06-24 15:24:48 -0700790 // See storage config details at http://source.android.com/tech/storage/
791
Jeff Sharkey9527b222015-06-24 15:24:48 -0700792 String8 storageSource;
793 if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700794 storageSource = "/mnt/runtime/default";
Jeff Sharkey9527b222015-06-24 15:24:48 -0700795 } else if (mount_mode == MOUNT_EXTERNAL_READ) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700796 storageSource = "/mnt/runtime/read";
Jeff Sharkey9527b222015-06-24 15:24:48 -0700797 } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700798 storageSource = "/mnt/runtime/write";
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800799 } else if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
Jeff Sharkey9527b222015-06-24 15:24:48 -0700800 // Sane default of no storage visible
Chris Wailesaa1c9622019-01-10 16:55:32 -0800801 return;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700802 }
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400803
804 // Create a second private mount namespace for our process
805 if (unshare(CLONE_NEWNS) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800806 fail_fn(CREATE_ERROR("Failed to unshare(): %s", strerror(errno)));
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400807 }
808
Robert Sesek06f39302017-03-20 17:30:05 -0400809 // Handle force_mount_namespace with MOUNT_EXTERNAL_NONE.
810 if (mount_mode == MOUNT_EXTERNAL_NONE) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800811 return;
Robert Sesek06f39302017-03-20 17:30:05 -0400812 }
813
Jeff Sharkey06376802019-02-11 12:20:02 -0700814 if (GetBoolProperty(kIsolatedStorageSnapshot, GetBoolProperty(kIsolatedStorage, true))) {
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800815 if (mount_mode == MOUNT_EXTERNAL_FULL || mount_mode == MOUNT_EXTERNAL_LEGACY) {
816 storageSource = (mount_mode == MOUNT_EXTERNAL_FULL)
817 ? "/mnt/runtime/full" : "/mnt/runtime/write";
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700818 if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800819 NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
820 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
821 storageSource.string(),
822 strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700823 }
Jeff Sharkey9527b222015-06-24 15:24:48 -0700824
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700825 // Mount user-specific symlink helper into place
826 userid_t user_id = multiuser_get_user_id(uid);
827 const String8 userSource(String8::format("/mnt/user/%d", user_id));
828 if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800829 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s (%s)",
830 userSource.string(), strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700831 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800832
833 if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self", nullptr, MS_BIND,
834 nullptr)) == -1) {
835 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
836 userSource.string(),
837 strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700838 }
839 } else {
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800840 if (package_name.empty() || sandbox_id.empty()) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800841 return;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700842 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800843
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700844 userid_t user_id = multiuser_get_user_id(uid);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800845 std::string pkgSandboxDir =
846 StringPrintf("/mnt/user/%d/package/%s", user_id, package_name.c_str());
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700847 bool sandboxAlreadyCreated = true;
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800848 if (TEMP_FAILURE_RETRY(access(pkgSandboxDir.c_str(), F_OK)) == -1) {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700849 if (errno == ENOENT) {
850 ALOGD("Sandbox not yet created for %s", pkgSandboxDir.c_str());
851 sandboxAlreadyCreated = false;
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800852 CreatePkgSandboxTarget(uid, package_name, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700853 } else {
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800854 fail_fn(CREATE_ERROR("Failed to access %s: %s",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800855 pkgSandboxDir.c_str(), strerror(errno)));
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700856 }
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700857 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800858
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700859 if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800860 nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
861 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
862 pkgSandboxDir.c_str(), strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700863 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800864
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800865 if (TEMP_FAILURE_RETRY(access("/storage/obb_mount", F_OK)) == 0) {
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800866 if (mount_mode != MOUNT_EXTERNAL_INSTALLER) {
867 remove("/storage/obb_mount");
868 }
869 } else {
870 if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800871 int fd =
872 TEMP_FAILURE_RETRY(open("/storage/obb_mount", O_RDWR | O_CREAT, 0660));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800873 if (fd == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800874 fail_fn(CREATE_ERROR("Couldn't create /storage/obb_mount: %s",
875 strerror(errno)));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800876 }
877 close(fd);
878 }
879 }
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700880 // If the sandbox was already created by vold, only then set up the bind mounts for
881 // pkg specific directories. Otherwise, leave as is and bind mounts will be taken
882 // care of by vold later.
883 if (sandboxAlreadyCreated) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800884 PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800885 mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700886 }
Sudheer Shanka663b1042018-07-30 17:34:21 -0700887 }
888 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800889 if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage", nullptr,
890 MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
891 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
892 storageSource.string(),
893 strerror(errno)));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700894 }
895
896 // Mount user-specific symlink helper into place
897 userid_t user_id = multiuser_get_user_id(uid);
898 const String8 userSource(String8::format("/mnt/user/%d", user_id));
899 if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800900 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s",
901 userSource.string()));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700902 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800903
Sudheer Shanka663b1042018-07-30 17:34:21 -0700904 if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800905 nullptr, MS_BIND, nullptr)) == -1) {
906 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
907 userSource.string(), strerror(errno)));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700908 }
Jeff Sharkey9527b222015-06-24 15:24:48 -0700909 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100910}
911
Narayan Kamath973b4662014-03-31 13:41:26 +0100912static bool NeedsNoRandomizeWorkaround() {
913#if !defined(__arm__)
914 return false;
915#else
916 int major;
917 int minor;
918 struct utsname uts;
919 if (uname(&uts) == -1) {
920 return false;
921 }
922
923 if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
924 return false;
925 }
926
927 // Kernels before 3.4.* need the workaround.
928 return (major < 3) || ((major == 3) && (minor < 4));
929#endif
930}
Narayan Kamath973b4662014-03-31 13:41:26 +0100931
932// Utility to close down the Zygote socket file descriptors while
933// the child is still running as root with Zygote's privileges. Each
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800934// descriptor (if any) is closed via dup3(), replacing it with a valid
Narayan Kamath973b4662014-03-31 13:41:26 +0100935// (open) descriptor to /dev/null.
936
Chris Wailesaa1c9622019-01-10 16:55:32 -0800937static void DetachDescriptors(JNIEnv* env,
938 const std::vector<int>& fds_to_close,
939 fail_fn_t fail_fn) {
940
941 if (fds_to_close.size() > 0) {
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800942 android::base::unique_fd devnull_fd(open("/dev/null", O_RDWR | O_CLOEXEC));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800943 if (devnull_fd == -1) {
944 fail_fn(std::string("Failed to open /dev/null: ").append(strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100945 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800946
947 for (int fd : fds_to_close) {
948 ALOGV("Switching descriptor %d to /dev/null", fd);
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800949 if (dup3(devnull_fd, fd, O_CLOEXEC) == -1) {
950 fail_fn(StringPrintf("Failed dup3() on descriptor %d: %s", fd, strerror(errno)));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800951 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100952 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100953 }
954}
955
Chris Wailesaa1c9622019-01-10 16:55:32 -0800956void SetThreadName(const std::string& thread_name) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100957 bool hasAt = false;
958 bool hasDot = false;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800959
960 for (const char str_el : thread_name) {
961 if (str_el == '.') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100962 hasDot = true;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800963 } else if (str_el == '@') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100964 hasAt = true;
965 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100966 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800967
968 const char* name_start_ptr = thread_name.c_str();
969 if (thread_name.length() >= MAX_NAME_LENGTH && !hasAt && hasDot) {
970 name_start_ptr += thread_name.length() - MAX_NAME_LENGTH;
Narayan Kamath973b4662014-03-31 13:41:26 +0100971 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800972
Narayan Kamath973b4662014-03-31 13:41:26 +0100973 // pthread_setname_np fails rather than truncating long strings.
974 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
Chris Wailesaa1c9622019-01-10 16:55:32 -0800975 strlcpy(buf, name_start_ptr, sizeof(buf) - 1);
Narayan Kamath973b4662014-03-31 13:41:26 +0100976 errno = pthread_setname_np(pthread_self(), buf);
977 if (errno != 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700978 ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100979 }
Andreas Gampe041483a2018-03-05 13:00:42 -0800980 // Update base::logging default tag.
981 android::base::SetDefaultTag(buf);
Narayan Kamath973b4662014-03-31 13:41:26 +0100982}
983
Chris Wailesaa1c9622019-01-10 16:55:32 -0800984/**
985 * A failure function used to report fatal errors to the managed runtime. This
986 * function is often curried with the process name information and then passed
987 * to called functions.
988 *
989 * @param env Managed runtime environment
990 * @param process_name A native representation of the process name
991 * @param managed_process_name A managed representation of the process name
992 * @param msg The error message to be reported
993 */
Chris Wailesaf594fc2018-11-02 11:00:07 -0700994[[noreturn]]
995static void ZygoteFailure(JNIEnv* env,
996 const char* process_name,
997 jstring managed_process_name,
998 const std::string& msg) {
999 std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr;
1000 if (managed_process_name != nullptr) {
1001 scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name));
1002 if (scoped_managed_process_name_ptr->c_str() != nullptr) {
1003 process_name = scoped_managed_process_name_ptr->c_str();
David Sehrde8d0bd2018-06-22 10:45:36 -07001004 }
1005 }
1006
Chris Wailesaf594fc2018-11-02 11:00:07 -07001007 const std::string& error_msg =
1008 (process_name == nullptr) ? msg : StringPrintf("(%s) %s", process_name, msg.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -07001009
Chris Wailesaf594fc2018-11-02 11:00:07 -07001010 env->FatalError(error_msg.c_str());
1011 __builtin_unreachable();
1012}
David Sehrde8d0bd2018-06-22 10:45:36 -07001013
Chris Wailesaa1c9622019-01-10 16:55:32 -08001014/**
1015 * A helper method for converting managed strings to native strings. A fatal
1016 * error is generated if a problem is encountered in extracting a non-null
1017 * string.
1018 *
1019 * @param env Managed runtime environment
1020 * @param process_name A native representation of the process name
1021 * @param managed_process_name A managed representation of the process name
1022 * @param managed_string The managed string to extract
1023 *
1024 * @return An empty option if the managed string is null. A optional-wrapped
1025 * string otherwise.
1026 */
Chris Wailesaf594fc2018-11-02 11:00:07 -07001027static std::optional<std::string> ExtractJString(JNIEnv* env,
1028 const char* process_name,
1029 jstring managed_process_name,
1030 jstring managed_string) {
1031 if (managed_string == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001032 return std::nullopt;
Chris Wailesaf594fc2018-11-02 11:00:07 -07001033 } else {
1034 ScopedUtfChars scoped_string_chars(env, managed_string);
1035
1036 if (scoped_string_chars.c_str() != nullptr) {
1037 return std::optional<std::string>(scoped_string_chars.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -07001038 } else {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001039 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JString.");
David Sehrde8d0bd2018-06-22 10:45:36 -07001040 }
1041 }
David Sehrde8d0bd2018-06-22 10:45:36 -07001042}
1043
Chris Wailesaa1c9622019-01-10 16:55:32 -08001044/**
1045 * A helper method for converting managed string arrays to native vectors. A
1046 * fatal error is generated if a problem is encountered in extracting a non-null array.
1047 *
1048 * @param env Managed runtime environment
1049 * @param process_name A native representation of the process name
1050 * @param managed_process_name A managed representation of the process name
1051 * @param managed_array The managed integer array to extract
1052 *
1053 * @return An empty option if the managed array is null. A optional-wrapped
1054 * vector otherwise.
1055 */
1056static std::optional<std::vector<int>> ExtractJIntArray(JNIEnv* env,
1057 const char* process_name,
1058 jstring managed_process_name,
1059 jintArray managed_array) {
1060 if (managed_array == nullptr) {
1061 return std::nullopt;
1062 } else {
1063 ScopedIntArrayRO managed_array_handle(env, managed_array);
Narayan Kamath973b4662014-03-31 13:41:26 +01001064
Chris Wailesaa1c9622019-01-10 16:55:32 -08001065 if (managed_array_handle.get() != nullptr) {
1066 std::vector<int> native_array;
1067 native_array.reserve(managed_array_handle.size());
1068
1069 for (size_t array_index = 0; array_index < managed_array_handle.size(); ++array_index) {
1070 native_array.push_back(managed_array_handle[array_index]);
1071 }
1072
1073 return std::move(native_array);
1074
1075 } else {
1076 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JIntArray.");
1077 }
1078 }
1079}
1080
1081/**
1082 * A helper method for converting managed string arrays to native vectors. A
1083 * fatal error is generated if a problem is encountered in extracting a non-null array.
1084 *
1085 * @param env Managed runtime environment
1086 * @param process_name A native representation of the process name
1087 * @param managed_process_name A managed representation of the process name
1088 * @param managed_array The managed string array to extract
1089 *
1090 * @return An empty option if the managed array is null. A optional-wrapped
1091 * vector otherwise.
1092 */
1093static std::optional<std::vector<std::string>> ExtractJStringArray(JNIEnv* env,
1094 const char* process_name,
1095 jstring managed_process_name,
1096 jobjectArray managed_array) {
1097 if (managed_array == nullptr) {
1098 return std::nullopt;
1099 } else {
1100 jsize element_count = env->GetArrayLength(managed_array);
1101 std::vector<std::string> native_string_vector;
1102 native_string_vector.reserve(element_count);
1103
1104 for (jsize array_index = 0; array_index < element_count; ++array_index) {
1105 jstring managed_string = (jstring) env->GetObjectArrayElement(managed_array, array_index);
1106 auto native_string = ExtractJString(env, process_name, managed_process_name, managed_string);
1107
1108 if (LIKELY(native_string.has_value())) {
1109 native_string_vector.emplace_back(std::move(native_string.value()));
1110 } else {
1111 ZygoteFailure(env, process_name, managed_process_name,
1112 "Null string found in managed string array.");
1113 }
1114 }
1115
1116 return std::move(native_string_vector);
1117 }
1118}
1119
1120/**
1121 * A utility function for blocking signals.
1122 *
1123 * @param signum Signal number to block
1124 * @param fail_fn Fatal error reporting function
1125 *
1126 * @see ZygoteFailure
1127 */
1128static void BlockSignal(int signum, fail_fn_t fail_fn) {
1129 sigset_t sigs;
1130 sigemptyset(&sigs);
1131 sigaddset(&sigs, signum);
1132
1133 if (sigprocmask(SIG_BLOCK, &sigs, nullptr) == -1) {
1134 fail_fn(CREATE_ERROR("Failed to block signal %s: %s", strsignal(signum), strerror(errno)));
1135 }
1136}
1137
1138
1139/**
1140 * A utility function for unblocking signals.
1141 *
1142 * @param signum Signal number to unblock
1143 * @param fail_fn Fatal error reporting function
1144 *
1145 * @see ZygoteFailure
1146 */
1147static void UnblockSignal(int signum, fail_fn_t fail_fn) {
1148 sigset_t sigs;
1149 sigemptyset(&sigs);
1150 sigaddset(&sigs, signum);
1151
1152 if (sigprocmask(SIG_UNBLOCK, &sigs, nullptr) == -1) {
1153 fail_fn(CREATE_ERROR("Failed to un-block signal %s: %s", strsignal(signum), strerror(errno)));
1154 }
1155}
1156
1157// Utility routine to fork a process from the zygote.
1158static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
1159 const std::vector<int>& fds_to_close,
1160 const std::vector<int>& fds_to_ignore) {
1161 SetSignalHandlers();
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001162
Chris Wailesaf594fc2018-11-02 11:00:07 -07001163 // Curry a failure function.
1164 auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
1165 nullptr, _1);
Andreas Gamped5758f62018-03-12 12:08:55 -07001166
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001167 // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
1168 // log, which would result in the logging FDs we close being reopened.
1169 // This would cause failures because the FDs are not whitelisted.
1170 //
1171 // Note that the zygote process is single threaded at this point.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001172 BlockSignal(SIGCHLD, fail_fn);
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001173
Narayan Kamath3764a262016-08-30 15:36:19 +01001174 // Close any logging related FDs before we start evaluating the list of
1175 // file descriptors.
1176 __android_log_close();
Howard Ro27330412018-10-02 12:08:28 -07001177 stats_log_close();
Narayan Kamath3764a262016-08-30 15:36:19 +01001178
Chris Wailesaf594fc2018-11-02 11:00:07 -07001179 // If this is the first fork for this zygote, create the open FD table. If
1180 // it isn't, we just need to check whether the list of open files has changed
1181 // (and it shouldn't in the normal case).
Chris Wailesaf594fc2018-11-02 11:00:07 -07001182 if (gOpenFdTable == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001183 gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
1184 } else {
1185 gOpenFdTable->Restat(fds_to_ignore, fail_fn);
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001186 }
1187
Josh Gaod7951102018-06-26 16:05:12 -07001188 android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
1189
Narayan Kamath973b4662014-03-31 13:41:26 +01001190 pid_t pid = fork();
1191
1192 if (pid == 0) {
David Sehrde8d0bd2018-06-22 10:45:36 -07001193 // The child process.
Christopher Ferris76de39e2017-06-20 16:13:40 -07001194 PreApplicationInit();
Christopher Ferrisab16dd12017-05-15 16:50:29 -07001195
Narayan Kamath973b4662014-03-31 13:41:26 +01001196 // Clean up any descriptors which must be closed immediately
Chris Wailesaa1c9622019-01-10 16:55:32 -08001197 DetachDescriptors(env, fds_to_close, fail_fn);
Narayan Kamath973b4662014-03-31 13:41:26 +01001198
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001199 // Re-open all remaining open file descriptors so that they aren't shared
1200 // with the zygote across a fork.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001201 gOpenFdTable->ReopenOrDetach(fail_fn);
Josh Gaod7951102018-06-26 16:05:12 -07001202
1203 // Turn fdsan back on.
1204 android_fdsan_set_error_level(fdsan_error_level);
David Sehrde8d0bd2018-06-22 10:45:36 -07001205 }
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001206
David Sehrde8d0bd2018-06-22 10:45:36 -07001207 // We blocked SIGCHLD prior to a fork, we unblock it here.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001208 UnblockSignal(SIGCHLD, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001209
Narayan Kamath973b4662014-03-31 13:41:26 +01001210 return pid;
1211}
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001212
Chris Wailesaf594fc2018-11-02 11:00:07 -07001213// Utility routine to specialize a zygote child process.
1214static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
1215 jint runtime_flags, jobjectArray rlimits,
1216 jlong permitted_capabilities, jlong effective_capabilities,
1217 jint mount_external, jstring managed_se_info,
1218 jstring managed_nice_name, bool is_system_server,
1219 bool is_child_zygote, jstring managed_instruction_set,
1220 jstring managed_app_data_dir, jstring managed_package_name,
1221 jobjectArray managed_pacakges_for_uid,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001222 jobjectArray managed_visible_vol_ids, jstring managed_sandbox_id) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001223 const char* process_name = is_system_server ? "system_server" : "zygote";
1224 auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
1225 auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001226
1227 auto se_info = extract_fn(managed_se_info);
1228 auto nice_name = extract_fn(managed_nice_name);
1229 auto instruction_set = extract_fn(managed_instruction_set);
1230 auto app_data_dir = extract_fn(managed_app_data_dir);
1231 auto package_name = extract_fn(managed_package_name);
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001232 auto sandbox_id = extract_fn(managed_sandbox_id);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001233
Chris Wailesaf594fc2018-11-02 11:00:07 -07001234 // Keep capabilities across UID change, unless we're staying root.
1235 if (uid != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001236 EnableKeepCapabilities(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001237 }
1238
Chris Wailesaa1c9622019-01-10 16:55:32 -08001239 SetInheritable(permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001240
Chris Wailesaa1c9622019-01-10 16:55:32 -08001241 DropCapabilitiesBoundingSet(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001242
1243 bool use_native_bridge = !is_system_server &&
1244 instruction_set.has_value() &&
1245 android::NativeBridgeAvailable() &&
1246 android::NeedsNativeBridge(instruction_set.value().c_str());
1247
1248 if (use_native_bridge && !app_data_dir.has_value()) {
1249 // The app_data_dir variable should never be empty if we need to use a
1250 // native bridge. In general, app_data_dir will never be empty for normal
1251 // applications. It can only happen in special cases (for isolated
1252 // processes which are not associated with any app). These are launched by
1253 // the framework and should not be emulated anyway.
1254 use_native_bridge = false;
1255 ALOGW("Native bridge will not be used because managed_app_data_dir == nullptr.");
1256 }
1257
1258 if (!package_name.has_value()) {
1259 if (is_system_server) {
1260 package_name.emplace("android");
1261 } else {
1262 package_name.emplace("");
1263 }
1264 }
1265
Chris Wailesaa1c9622019-01-10 16:55:32 -08001266 std::vector<std::string> packages_for_uid =
1267 ExtractJStringArray(env, process_name, managed_nice_name, managed_pacakges_for_uid).
1268 value_or(std::vector<std::string>());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001269
Chris Wailesaa1c9622019-01-10 16:55:32 -08001270 std::vector<std::string> visible_vol_ids =
1271 ExtractJStringArray(env, process_name, managed_nice_name, managed_visible_vol_ids).
1272 value_or(std::vector<std::string>());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001273
Chris Wailesaa1c9622019-01-10 16:55:32 -08001274 MountEmulatedStorage(uid, mount_external, use_native_bridge, package_name.value(),
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001275 packages_for_uid, visible_vol_ids, sandbox_id.value_or(""), fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001276
1277 // If this zygote isn't root, it won't be able to create a process group,
1278 // since the directory is owned by root.
1279 if (!is_system_server && getuid() == 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001280 const int rc = createProcessGroup(uid, getpid());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001281 if (rc == -EROFS) {
1282 ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
1283 } else if (rc != 0) {
1284 ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
1285 }
1286 }
1287
Chris Wailesaa1c9622019-01-10 16:55:32 -08001288 SetGids(env, gids, fail_fn);
1289 SetRLimits(env, rlimits, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001290
1291 if (use_native_bridge) {
1292 // Due to the logic behind use_native_bridge we know that both app_data_dir
1293 // and instruction_set contain values.
1294 android::PreInitializeNativeBridge(app_data_dir.value().c_str(),
1295 instruction_set.value().c_str());
1296 }
1297
1298 if (setresgid(gid, gid, gid) == -1) {
1299 fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
1300 }
1301
1302 // Must be called when the new process still has CAP_SYS_ADMIN, in this case,
1303 // before changing uid from 0, which clears capabilities. The other
1304 // alternative is to call prctl(PR_SET_NO_NEW_PRIVS, 1) afterward, but that
1305 // breaks SELinux domain transition (see b/71859146). As the result,
1306 // privileged syscalls used below still need to be accessible in app process.
Martijn Coenen86f08a52019-01-03 16:23:01 +01001307 SetUpSeccompFilter(uid, is_child_zygote);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001308
1309 if (setresuid(uid, uid, uid) == -1) {
1310 fail_fn(CREATE_ERROR("setresuid(%d) failed: %s", uid, strerror(errno)));
1311 }
1312
1313 // The "dumpable" flag of a process, which controls core dump generation, is
1314 // overwritten by the value in /proc/sys/fs/suid_dumpable when the effective
1315 // user or group ID changes. See proc(5) for possible values. In most cases,
1316 // the value is 0, so core dumps are disabled for zygote children. However,
1317 // when running in a Chrome OS container, the value is already set to 2,
1318 // which allows the external crash reporter to collect all core dumps. Since
1319 // only system crashes are interested, core dump is disabled for app
1320 // processes. This also ensures compliance with CTS.
1321 int dumpable = prctl(PR_GET_DUMPABLE);
1322 if (dumpable == -1) {
1323 ALOGE("prctl(PR_GET_DUMPABLE) failed: %s", strerror(errno));
1324 RuntimeAbort(env, __LINE__, "prctl(PR_GET_DUMPABLE) failed");
1325 }
1326
1327 if (dumpable == 2 && uid >= AID_APP) {
1328 if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) {
1329 ALOGE("prctl(PR_SET_DUMPABLE, 0) failed: %s", strerror(errno));
1330 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 0) failed");
1331 }
1332 }
1333
Orion Hodson8d005a62018-12-05 12:28:53 +00001334 // Set process properties to enable debugging if required.
1335 if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_JDWP) != 0) {
1336 EnableDebugger();
1337 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001338 if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) {
1339 // simpleperf needs the process to be dumpable to profile it.
1340 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
1341 ALOGE("prctl(PR_SET_DUMPABLE) failed: %s", strerror(errno));
1342 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 1) failed");
1343 }
1344 }
Orion Hodson8d005a62018-12-05 12:28:53 +00001345
Chris Wailesaf594fc2018-11-02 11:00:07 -07001346 if (NeedsNoRandomizeWorkaround()) {
1347 // Work around ARM kernel ASLR lossage (http://b/5817320).
1348 int old_personality = personality(0xffffffff);
1349 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
1350 if (new_personality == -1) {
1351 ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
1352 }
1353 }
1354
Chris Wailesaa1c9622019-01-10 16:55:32 -08001355 SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001356
Chris Wailesaa1c9622019-01-10 16:55:32 -08001357 SetSchedulerPolicy(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001358
1359 const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
1360 const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
1361
1362 if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
1363 fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
1364 uid, is_system_server, se_info_ptr, nice_name_ptr));
1365 }
1366
1367 // Make it easier to debug audit logs by setting the main thread's name to the
1368 // nice name rather than "app_process".
1369 if (nice_name.has_value()) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001370 SetThreadName(nice_name.value());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001371 } else if (is_system_server) {
1372 SetThreadName("system_server");
1373 }
1374
1375 // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
1376 UnsetChldSignalHandler();
1377
1378 if (is_system_server) {
1379 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
1380 if (env->ExceptionCheck()) {
1381 fail_fn("Error calling post fork system server hooks.");
1382 }
Chris Wailesaa1c9622019-01-10 16:55:32 -08001383
Chris Wailesaf594fc2018-11-02 11:00:07 -07001384 // TODO(oth): Remove hardcoded label here (b/117874058).
1385 static const char* kSystemServerLabel = "u:r:system_server:s0";
1386 if (selinux_android_setcon(kSystemServerLabel) != 0) {
1387 fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));
1388 }
1389 }
1390
1391 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
1392 is_system_server, is_child_zygote, managed_instruction_set);
1393
1394 if (env->ExceptionCheck()) {
1395 fail_fn("Error calling post fork hooks.");
1396 }
1397}
1398
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001399static uint64_t GetEffectiveCapabilityMask(JNIEnv* env) {
1400 __user_cap_header_struct capheader;
1401 memset(&capheader, 0, sizeof(capheader));
1402 capheader.version = _LINUX_CAPABILITY_VERSION_3;
1403 capheader.pid = 0;
1404
1405 __user_cap_data_struct capdata[2];
1406 if (capget(&capheader, &capdata[0]) == -1) {
1407 ALOGE("capget failed: %s", strerror(errno));
1408 RuntimeAbort(env, __LINE__, "capget failed");
1409 }
1410
Chris Wailesaf594fc2018-11-02 11:00:07 -07001411 return capdata[0].effective | (static_cast<uint64_t>(capdata[1].effective) << 32);
1412}
1413
1414static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gids,
1415 bool is_child_zygote) {
1416 jlong capabilities = 0;
1417
1418 /*
1419 * Grant the following capabilities to the Bluetooth user:
1420 * - CAP_WAKE_ALARM
1421 * - CAP_NET_RAW
1422 * - CAP_NET_BIND_SERVICE (for DHCP client functionality)
1423 * - CAP_SYS_NICE (for setting RT priority for audio-related threads)
1424 */
1425
1426 if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
1427 capabilities |= (1LL << CAP_WAKE_ALARM);
1428 capabilities |= (1LL << CAP_NET_RAW);
1429 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1430 capabilities |= (1LL << CAP_SYS_NICE);
1431 }
1432
Remi NGUYEN VANc094a542018-12-07 16:52:24 +09001433 if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
1434 capabilities |= (1LL << CAP_NET_ADMIN);
1435 capabilities |= (1LL << CAP_NET_BROADCAST);
1436 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1437 capabilities |= (1LL << CAP_NET_RAW);
1438 }
1439
Chris Wailesaf594fc2018-11-02 11:00:07 -07001440 /*
1441 * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
1442 */
1443
1444 bool gid_wakelock_found = false;
1445 if (gid == AID_WAKELOCK) {
1446 gid_wakelock_found = true;
1447 } else if (gids != nullptr) {
1448 jsize gids_num = env->GetArrayLength(gids);
1449 ScopedIntArrayRO native_gid_proxy(env, gids);
1450
1451 if (native_gid_proxy.get() == nullptr) {
1452 RuntimeAbort(env, __LINE__, "Bad gids array");
1453 }
1454
1455 for (int gid_index = gids_num; --gids_num >= 0;) {
1456 if (native_gid_proxy[gid_index] == AID_WAKELOCK) {
1457 gid_wakelock_found = true;
1458 break;
1459 }
1460 }
1461 }
1462
1463 if (gid_wakelock_found) {
1464 capabilities |= (1LL << CAP_BLOCK_SUSPEND);
1465 }
1466
1467 /*
1468 * Grant child Zygote processes the following capabilities:
1469 * - CAP_SETUID (change UID of child processes)
1470 * - CAP_SETGID (change GID of child processes)
1471 * - CAP_SETPCAP (change capabilities of child processes)
1472 */
1473
1474 if (is_child_zygote) {
1475 capabilities |= (1LL << CAP_SETUID);
1476 capabilities |= (1LL << CAP_SETGID);
1477 capabilities |= (1LL << CAP_SETPCAP);
1478 }
1479
1480 /*
1481 * Containers run without some capabilities, so drop any caps that are not
1482 * available.
1483 */
1484
1485 return capabilities & GetEffectiveCapabilityMask(env);
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001486}
Chris Wailesaa1c9622019-01-10 16:55:32 -08001487
1488/**
1489 * Adds the given information about a newly created blastula to the Zygote's
1490 * blastula table.
1491 *
1492 * @param blastula_pid Process ID of the newly created blastula
1493 * @param read_pipe_fd File descriptor for the read end of the blastula
1494 * reporting pipe. Used in the ZygoteServer poll loop to track blastula
1495 * specialization.
1496 */
1497static void AddBlastulaTableEntry(pid_t blastula_pid, int read_pipe_fd) {
1498 static int sBlastulaTableInsertIndex = 0;
1499
1500 int search_index = sBlastulaTableInsertIndex;
1501
1502 do {
1503 if (gBlastulaTable[search_index].SetIfInvalid(blastula_pid, read_pipe_fd)) {
1504 // Start our next search right after where we finished this one.
1505 sBlastulaTableInsertIndex = (search_index + 1) % gBlastulaTable.size();
1506
1507 return;
1508 }
1509
1510 search_index = (search_index + 1) % gBlastulaTable.size();
1511 } while (search_index != sBlastulaTableInsertIndex);
1512
1513 // Much like money in the banana stand, there should always be an entry
1514 // in the blastula table.
1515 __builtin_unreachable();
1516}
1517
1518/**
1519 * Invalidates the entry in the BlastulaTable corresponding to the provided
1520 * process ID if it is present. If an entry was removed the blastula pool
1521 * count is decremented.
1522 *
1523 * @param blastula_pid Process ID of the blastula entry to invalidate
1524 * @return True if an entry was invalidated; false otherwise
1525 */
1526static bool RemoveBlastulaTableEntry(pid_t blastula_pid) {
1527 for (BlastulaTableEntry& entry : gBlastulaTable) {
1528 if (entry.ClearForPID(blastula_pid)) {
1529 --gBlastulaPoolCount;
1530 return true;
1531 }
1532 }
1533
1534 return false;
1535}
1536
1537/**
1538 * @return A vector of the read pipe FDs for each of the active blastulas.
1539 */
1540std::vector<int> MakeBlastulaPipeReadFDVector() {
1541 std::vector<int> fd_vec;
1542 fd_vec.reserve(gBlastulaTable.size());
1543
1544 for (BlastulaTableEntry& entry : gBlastulaTable) {
1545 auto entry_values = entry.GetValues();
1546
1547 if (entry_values.has_value()) {
1548 fd_vec.push_back(entry_values.value().read_pipe_fd);
1549 }
1550 }
1551
1552 return fd_vec;
1553}
1554
Narayan Kamath973b4662014-03-31 13:41:26 +01001555} // anonymous namespace
1556
1557namespace android {
1558
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001559static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001560 // security_getenforce is not allowed on app process. Initialize and cache
1561 // the value before zygote forks.
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001562 g_is_security_enforced = security_getenforce();
1563}
1564
Christopher Ferris76de39e2017-06-20 16:13:40 -07001565static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
1566 PreApplicationInit();
1567}
1568
Narayan Kamath973b4662014-03-31 13:41:26 +01001569static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
1570 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +01001571 jint runtime_flags, jobjectArray rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001572 jint mount_external, jstring se_info, jstring nice_name,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001573 jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001574 jstring instruction_set, jstring app_data_dir, jstring package_name,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001575 jobjectArray packages_for_uid, jobjectArray visible_vol_ids, jstring sandbox_id) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001576 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
Pavlin Radoslavovfbd59042015-11-23 17:13:25 -08001577
Chris Wailesaa1c9622019-01-10 16:55:32 -08001578 if (UNLIKELY(managed_fds_to_close == nullptr)) {
1579 ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
1580 }
1581
1582 std::vector<int> fds_to_close =
1583 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
1584 std::vector<int> fds_to_ignore =
1585 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
1586 .value_or(std::vector<int>());
1587
1588 std::vector<int> blastula_pipes = MakeBlastulaPipeReadFDVector();
1589
1590 fds_to_close.insert(fds_to_close.end(), blastula_pipes.begin(), blastula_pipes.end());
1591 fds_to_ignore.insert(fds_to_ignore.end(), blastula_pipes.begin(), blastula_pipes.end());
1592
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001593 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001594
1595 if (gBlastulaPoolEventFD != -1) {
1596 fds_to_close.push_back(gBlastulaPoolEventFD);
1597 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1598 }
1599
Chris Wailesaf594fc2018-11-02 11:00:07 -07001600 pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001601
David Sehrde8d0bd2018-06-22 10:45:36 -07001602 if (pid == 0) {
1603 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1604 capabilities, capabilities,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001605 mount_external, se_info, nice_name, false,
1606 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001607 package_name, packages_for_uid, visible_vol_ids, sandbox_id);
David Sehrde8d0bd2018-06-22 10:45:36 -07001608 }
1609 return pid;
Narayan Kamath973b4662014-03-31 13:41:26 +01001610}
1611
1612static jint com_android_internal_os_Zygote_nativeForkSystemServer(
1613 JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001614 jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
1615 jlong effective_capabilities) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001616 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1617 fds_to_ignore(fds_to_close);
1618
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001619 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001620
1621 if (gBlastulaPoolEventFD != -1) {
1622 fds_to_close.push_back(gBlastulaPoolEventFD);
1623 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1624 }
1625
Chris Wailesaf594fc2018-11-02 11:00:07 -07001626 pid_t pid = ForkCommon(env, true,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001627 fds_to_close,
1628 fds_to_ignore);
David Sehrde8d0bd2018-06-22 10:45:36 -07001629 if (pid == 0) {
1630 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001631 permitted_capabilities, effective_capabilities,
1632 MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001633 false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
David Sehrde8d0bd2018-06-22 10:45:36 -07001634 } else if (pid > 0) {
Narayan Kamath973b4662014-03-31 13:41:26 +01001635 // The zygote process checks whether the child process has died or not.
1636 ALOGI("System server process %d has been created", pid);
1637 gSystemServerPid = pid;
1638 // There is a slight window that the system server process has crashed
1639 // but it went unnoticed because we haven't published its pid yet. So
1640 // we recheck here just to make sure that all is well.
1641 int status;
1642 if (waitpid(pid, &status, WNOHANG) == pid) {
1643 ALOGE("System server process %d has died. Restarting Zygote!", pid);
Andreas Gampeb053cce2015-11-17 16:38:59 -08001644 RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
Narayan Kamath973b4662014-03-31 13:41:26 +01001645 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001646
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001647 if (UsePerAppMemcg()) {
Minchan Kim5fa8af22018-06-27 11:32:40 +09001648 // Assign system_server to the correct memory cgroup.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001649 // Not all devices mount memcg so check if it is mounted first
Minchan Kim5fa8af22018-06-27 11:32:40 +09001650 // to avoid unnecessarily printing errors and denials in the logs.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001651 if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
1652 ALOGE("couldn't add process %d into system memcg group", pid);
Minchan Kim5fa8af22018-06-27 11:32:40 +09001653 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001654 }
Narayan Kamath973b4662014-03-31 13:41:26 +01001655 }
1656 return pid;
1657}
1658
Chris Wailesaa1c9622019-01-10 16:55:32 -08001659/**
1660 * A JNI function that forks a blastula from the Zygote while ensuring proper
1661 * file descriptor hygiene.
1662 *
1663 * @param env Managed runtime environment
1664 * @param read_pipe_fd The read FD for the blastula reporting pipe. Manually closed by blastlas
1665 * in managed code.
1666 * @param write_pipe_fd The write FD for the blastula reporting pipe. Manually closed by the
1667 * zygote in managed code.
1668 * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by
1669 * the FD hygiene code and automatically "closed" in the new blastula.
1670 * @return
1671 */
1672static jint com_android_internal_os_Zygote_nativeForkBlastula(JNIEnv* env, jclass,
1673 jint read_pipe_fd, jint write_pipe_fd, jintArray managed_session_socket_fds) {
1674 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1675 fds_to_ignore(fds_to_close);
1676
1677 std::vector<int> session_socket_fds =
1678 ExtractJIntArray(env, "blastula", nullptr, managed_session_socket_fds)
1679 .value_or(std::vector<int>());
1680
1681 // The Blastula Pool Event FD is created during the initialization of the
1682 // blastula pool and should always be valid here.
1683
1684 fds_to_close.push_back(gZygoteSocketFD);
1685 fds_to_close.push_back(gBlastulaPoolEventFD);
1686 fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
1687
1688 fds_to_ignore.push_back(gZygoteSocketFD);
1689 fds_to_ignore.push_back(gBlastulaPoolSocketFD);
1690 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1691 fds_to_ignore.push_back(read_pipe_fd);
1692 fds_to_ignore.push_back(write_pipe_fd);
1693 fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
1694
1695 pid_t blastula_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
1696
1697 if (blastula_pid != 0) {
1698 ++gBlastulaPoolCount;
1699 AddBlastulaTableEntry(blastula_pid, read_pipe_fd);
1700 }
1701
1702 return blastula_pid;
1703}
1704
Robert Sesek54e387d2016-12-02 17:27:50 -05001705static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
1706 JNIEnv* env, jclass, jstring path) {
1707 ScopedUtfChars path_native(env, path);
1708 const char* path_cstr = path_native.c_str();
1709 if (!path_cstr) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001710 RuntimeAbort(env, __LINE__, "path_cstr == nullptr");
Robert Sesek54e387d2016-12-02 17:27:50 -05001711 }
1712 FileDescriptorWhitelist::Get()->Allow(path_cstr);
1713}
1714
doheon1.lee885b7422016-01-20 13:07:27 +09001715static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* env, jclass) {
1716 // Zygote process unmount root storage space initially before every child processes are forked.
1717 // Every forked child processes (include SystemServer) only mount their own root storage space
Robert Seseke4f8d692016-09-13 19:13:01 -04001718 // and no need unmount storage operation in MountEmulatedStorage method.
1719 // Zygote process does not utilize root storage spaces and unshares its mount namespace below.
1720
1721 // See storage config details at http://source.android.com/tech/storage/
1722 // Create private mount namespace shared by all children
1723 if (unshare(CLONE_NEWNS) == -1) {
1724 RuntimeAbort(env, __LINE__, "Failed to unshare()");
1725 return;
1726 }
1727
1728 // Mark rootfs as being a slave so that changes from default
1729 // namespace only flow into our children.
1730 if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
1731 RuntimeAbort(env, __LINE__, "Failed to mount() rootfs as MS_SLAVE");
1732 return;
1733 }
1734
1735 // Create a staging tmpfs that is shared by our children; they will
1736 // bind mount storage into their respective private namespaces, which
1737 // are isolated from each other.
1738 const char* target_base = getenv("EMULATED_STORAGE_TARGET");
1739 if (target_base != nullptr) {
1740#define STRINGIFY_UID(x) __STRING(x)
1741 if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV,
1742 "uid=0,gid=" STRINGIFY_UID(AID_SDCARD_R) ",mode=0751") == -1) {
1743 ALOGE("Failed to mount tmpfs to %s", target_base);
1744 RuntimeAbort(env, __LINE__, "Failed to mount tmpfs");
1745 return;
1746 }
1747#undef STRINGIFY_UID
1748 }
doheon1.lee885b7422016-01-20 13:07:27 +09001749
1750 UnmountTree("/storage");
doheon1.lee885b7422016-01-20 13:07:27 +09001751}
1752
Martijn Coenen86f08a52019-01-03 16:23:01 +01001753static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter(
1754 JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) {
1755 if (!g_is_security_enforced) {
1756 ALOGI("seccomp disabled by setenforce 0");
1757 return;
1758 }
1759
Martijn Coenen86f08a52019-01-03 16:23:01 +01001760 bool installed = install_setuidgid_seccomp_filter(uidGidMin, uidGidMax);
1761 if (!installed) {
1762 RuntimeAbort(env, __LINE__, "Could not install setuid/setgid seccomp filter.");
1763 }
Martijn Coenen86f08a52019-01-03 16:23:01 +01001764}
1765
Chris Wailesaa1c9622019-01-10 16:55:32 -08001766/**
1767 * Called from a blastula to specialize the process for a specific application.
1768 *
1769 * @param env Managed runtime environment
1770 * @param uid User ID of the new application
1771 * @param gid Group ID of the new application
1772 * @param gids Extra groups that the process belongs to
1773 * @param runtime_flags Flags for changing the behavior of the managed runtime
1774 * @param rlimits Resource limits
1775 * @param mount_external The mode (read/write/normal) that external storage will be mounted with
1776 * @param se_info SELinux policy information
1777 * @param nice_name New name for this process
1778 * @param is_child_zygote If the process is to become a WebViewZygote
1779 * @param instruction_set The instruction set expected/requested by the new application
1780 * @param app_data_dir Path to the application's data directory
1781 */
1782static void com_android_internal_os_Zygote_nativeSpecializeBlastula(
1783 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
1784 jint runtime_flags, jobjectArray rlimits,
1785 jint mount_external, jstring se_info, jstring nice_name,
1786 jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001787 jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids,
1788 jstring sandbox_id) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001789 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
1790
1791 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1792 capabilities, capabilities,
1793 mount_external, se_info, nice_name, false,
1794 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001795 package_name, packages_for_uid, visible_vol_ids, sandbox_id);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001796}
1797
1798/**
1799 * A helper method for fetching socket file descriptors that were opened by init from the
1800 * environment.
1801 *
1802 * @param env Managed runtime environment
1803 * @param is_primary If this process is the primary or secondary Zygote; used to compute the name
1804 * of the environment variable storing the file descriptors.
1805 */
1806static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclass,
1807 jboolean is_primary) {
1808 std::string android_socket_prefix(ANDROID_SOCKET_PREFIX);
1809 std::string env_var_name = android_socket_prefix + (is_primary ? "zygote" : "zygote_secondary");
1810 char* env_var_val = getenv(env_var_name.c_str());
1811
1812 if (env_var_val != nullptr) {
1813 gZygoteSocketFD = atoi(env_var_val);
1814 ALOGV("Zygote:zygoteSocketFD = %d", gZygoteSocketFD);
1815 } else {
1816 ALOGE("Unable to fetch Zygote socket file descriptor");
1817 }
1818
1819 env_var_name = android_socket_prefix + (is_primary ? "blastula_pool" : "blastula_pool_secondary");
1820 env_var_val = getenv(env_var_name.c_str());
1821
1822 if (env_var_val != nullptr) {
1823 gBlastulaPoolSocketFD = atoi(env_var_val);
1824 ALOGV("Zygote:blastulaPoolSocketFD = %d", gBlastulaPoolSocketFD);
1825 } else {
1826 ALOGE("Unable to fetch Blastula pool socket file descriptor");
1827 }
1828}
1829
1830/**
1831 * @param env Managed runtime environment
1832 * @return A managed array of raw file descriptors for the read ends of the blastula reporting
1833 * pipes.
1834 */
1835static jintArray com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs(JNIEnv* env, jclass) {
1836 std::vector<int> blastula_fds = MakeBlastulaPipeReadFDVector();
1837
1838 jintArray managed_blastula_fds = env->NewIntArray(blastula_fds.size());
1839 env->SetIntArrayRegion(managed_blastula_fds, 0, blastula_fds.size(), blastula_fds.data());
1840
1841 return managed_blastula_fds;
1842}
1843
1844/**
1845 * A JNI wrapper around RemoveBlastulaTableEntry.
1846 *
1847 * @param env Managed runtime environment
1848 * @param blastula_pid Process ID of the blastula entry to invalidate
1849 * @return True if an entry was invalidated; false otherwise.
1850 */
1851static jboolean com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry(JNIEnv* env, jclass,
1852 jint blastula_pid) {
1853 return RemoveBlastulaTableEntry(blastula_pid);
1854}
1855
1856/**
1857 * Creates the blastula pool event FD if it doesn't exist and returns it. This is used by the
1858 * ZygoteServer poll loop to know when to re-fill the blastula pool.
1859 *
1860 * @param env Managed runtime environment
1861 * @return A raw event file descriptor used to communicate (from the signal handler) when the
1862 * Zygote receives a SIGCHLD for a blastula
1863 */
1864static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD(JNIEnv* env, jclass) {
1865 if (gBlastulaPoolEventFD == -1) {
1866 if ((gBlastulaPoolEventFD = eventfd(0, 0)) == -1) {
1867 ZygoteFailure(env, "zygote", nullptr, StringPrintf("Unable to create eventfd: %s", strerror(errno)));
1868 }
1869 }
1870
1871 return gBlastulaPoolEventFD;
1872}
1873
1874/**
1875 * @param env Managed runtime environment
1876 * @return The number of blastulas currently in the blastula pool
1877 */
1878static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolCount(JNIEnv* env, jclass) {
1879 return gBlastulaPoolCount;
1880}
1881
Daniel Micay76f6a862015-09-19 17:31:01 -04001882static const JNINativeMethod gMethods[] = {
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001883 { "nativeSecurityInit", "()V",
1884 (void *) com_android_internal_os_Zygote_nativeSecurityInit },
Andreas Gampeaec67dc2014-09-02 21:23:06 -07001885 { "nativeForkAndSpecialize",
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001886 "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I",
Narayan Kamath973b4662014-03-31 13:41:26 +01001887 (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
1888 { "nativeForkSystemServer", "(II[II[[IJJ)I",
doheon1.lee885b7422016-01-20 13:07:27 +09001889 (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
Robert Sesek54e387d2016-12-02 17:27:50 -05001890 { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
1891 (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
doheon1.lee885b7422016-01-20 13:07:27 +09001892 { "nativeUnmountStorageOnInit", "()V",
Christopher Ferris76de39e2017-06-20 16:13:40 -07001893 (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit },
1894 { "nativePreApplicationInit", "()V",
Martijn Coenen86f08a52019-01-03 16:23:01 +01001895 (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
1896 { "nativeInstallSeccompUidGidFilter", "(II)V",
Chris Wailesaa1c9622019-01-10 16:55:32 -08001897 (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
1898 { "nativeForkBlastula", "(II[I)I",
1899 (void *) com_android_internal_os_Zygote_nativeForkBlastula },
1900 { "nativeSpecializeBlastula",
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001901 "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V",
Chris Wailesaa1c9622019-01-10 16:55:32 -08001902 (void *) com_android_internal_os_Zygote_nativeSpecializeBlastula },
1903 { "nativeGetSocketFDs", "(Z)V",
1904 (void *) com_android_internal_os_Zygote_nativeGetSocketFDs },
1905 { "nativeGetBlastulaPipeFDs", "()[I",
1906 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs },
1907 { "nativeRemoveBlastulaTableEntry", "(I)Z",
1908 (void *) com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry },
1909 { "nativeGetBlastulaPoolEventFD", "()I",
1910 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD },
1911 { "nativeGetBlastulaPoolCount", "()I",
1912 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolCount }
Narayan Kamath973b4662014-03-31 13:41:26 +01001913};
1914
1915int register_com_android_internal_os_Zygote(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001916 gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
Orion Hodson46724e72018-10-19 13:05:33 +01001917 gCallPostForkSystemServerHooks = GetStaticMethodIDOrDie(env, gZygoteClass,
1918 "callPostForkSystemServerHooks",
1919 "()V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001920 gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
Robert Sesekd0a190df2018-02-12 18:46:01 -05001921 "(IZZLjava/lang/String;)V");
Narayan Kamath973b4662014-03-31 13:41:26 +01001922
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001923 return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
Narayan Kamath973b4662014-03-31 13:41:26 +01001924}
1925} // namespace android