blob: 2ccb01adfd3e1e908930ceeb9267552d2d84beeb [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
wangmingming16d0dd1a2018-11-14 10:43:36 +080028#include <async_safe/log.h>
29
Narayan Kamath973b4662014-03-31 13:41:26 +010030// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
31#include <sys/mount.h>
32#include <linux/fs.h>
33
Chris Wailesaa1c9622019-01-10 16:55:32 -080034#include <array>
35#include <atomic>
Chris Wailesaf594fc2018-11-02 11:00:07 -070036#include <functional>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070037#include <list>
Chris Wailesaf594fc2018-11-02 11:00:07 -070038#include <optional>
Andreas Gampeb053cce2015-11-17 16:38:59 -080039#include <sstream>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070040#include <string>
Chris Wailesaa1c9622019-01-10 16:55:32 -080041#include <string_view>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070042
Josh Gaod7951102018-06-26 16:05:12 -070043#include <android/fdsan.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080044#include <arpa/inet.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070045#include <fcntl.h>
Dan Albert46d84442014-11-18 16:07:51 -080046#include <grp.h>
47#include <inttypes.h>
Christopher Ferrisab16dd12017-05-15 16:50:29 -070048#include <malloc.h>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070049#include <mntent.h>
Narayan Kamath973b4662014-03-31 13:41:26 +010050#include <paths.h>
51#include <signal.h>
52#include <stdlib.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070053#include <sys/capability.h>
Robert Seseke4f8d692016-09-13 19:13:01 -040054#include <sys/cdefs.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080055#include <sys/eventfd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070056#include <sys/personality.h>
57#include <sys/prctl.h>
58#include <sys/resource.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080059#include <sys/socket.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070060#include <sys/stat.h>
Vitalii Tomkiv5cbce852016-05-18 17:43:02 -070061#include <sys/time.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070062#include <sys/types.h>
63#include <sys/utsname.h>
64#include <sys/wait.h>
Dan Albert46d84442014-11-18 16:07:51 -080065#include <unistd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070066
Chris Wailesaa1c9622019-01-10 16:55:32 -080067#include <android-base/logging.h>
Minchan Kim5fa8af22018-06-27 11:32:40 +090068#include <android-base/properties.h>
Carmen Jacksondd401252017-02-23 15:21:10 -080069#include <android-base/file.h>
70#include <android-base/stringprintf.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080071#include <android-base/unique_fd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070072#include <cutils/fs.h>
73#include <cutils/multiuser.h>
Sharvil Nanavati4990e4f2014-06-29 17:06:52 -070074#include <private/android_filesystem_config.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070075#include <utils/String8.h>
76#include <selinux/android.h>
Victor Hsiehc8176ef2018-01-08 12:43:00 -080077#include <seccomp_policy.h>
Howard Ro27330412018-10-02 12:08:28 -070078#include <stats_event_list.h>
Colin Cross0161bbc2014-06-03 13:26:58 -070079#include <processgroup/processgroup.h>
Suren Baghdasaryane4433262019-01-04 12:16:57 -080080#include <processgroup/sched_policy.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070081
Andreas Gampeed6b9df2014-11-20 22:02:20 -080082#include "core_jni_helpers.h"
Steven Moreland2279b252017-07-19 09:50:45 -070083#include <nativehelper/JNIHelp.h>
84#include <nativehelper/ScopedLocalRef.h>
85#include <nativehelper/ScopedPrimitiveArray.h>
86#include <nativehelper/ScopedUtfChars.h>
Robert Sesek8225b7c2016-12-16 14:02:31 -050087#include "fd_utils.h"
Narayan Kamath973b4662014-03-31 13:41:26 +010088
jgu212eacd062014-09-10 06:55:07 -040089#include "nativebridge/native_bridge.h"
90
Narayan Kamath973b4662014-03-31 13:41:26 +010091namespace {
92
Chris Wailesaa1c9622019-01-10 16:55:32 -080093// TODO (chriswailes): Add a function to initialize native Zygote data.
94// TODO (chriswailes): Fix mixed indentation style (2 and 4 spaces).
95
Chris Wailesaf594fc2018-11-02 11:00:07 -070096using namespace std::placeholders;
97
Narayan Kamath973b4662014-03-31 13:41:26 +010098using android::String8;
Sudheer Shanka663b1042018-07-30 17:34:21 -070099using android::base::StringAppendF;
Carmen Jacksondd401252017-02-23 15:21:10 -0800100using android::base::StringPrintf;
101using android::base::WriteStringToFile;
Minchan Kim5fa8af22018-06-27 11:32:40 +0900102using android::base::GetBoolProperty;
Narayan Kamath973b4662014-03-31 13:41:26 +0100103
Andreas Gamped5758f62018-03-12 12:08:55 -0700104#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
105 append(StringPrintf(__VA_ARGS__))
106
Chris Wailesaa1c9622019-01-10 16:55:32 -0800107// This type is duplicated in fd_utils.h
108typedef const std::function<void(std::string)>& fail_fn_t;
109
Narayan Kamath973b4662014-03-31 13:41:26 +0100110static pid_t gSystemServerPid = 0;
111
Sudheer Shanka663b1042018-07-30 17:34:21 -0700112static const char kIsolatedStorage[] = "persist.sys.isolated_storage";
Sudheer Shankaa3801582019-01-17 17:19:11 -0800113static const char kIsolatedStorageSnapshot[] = "sys.isolated_storage_snapshot";
Narayan Kamath973b4662014-03-31 13:41:26 +0100114static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
115static jclass gZygoteClass;
Orion Hodson46724e72018-10-19 13:05:33 +0100116static jmethodID gCallPostForkSystemServerHooks;
Narayan Kamath973b4662014-03-31 13:41:26 +0100117static jmethodID gCallPostForkChildHooks;
118
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800119static bool g_is_security_enforced = true;
120
Chris Wailesaa1c9622019-01-10 16:55:32 -0800121/**
122 * The maximum number of characters (not including a null terminator) that a
123 * process name may contain.
124 */
125static constexpr size_t MAX_NAME_LENGTH = 15;
126
127/**
128 * The prefix string for environmental variables storing socket FDs created by
129 * init.
130 */
131
132static constexpr std::string_view ANDROID_SOCKET_PREFIX("ANDROID_SOCKET_");
133
134/**
135 * The file descriptor for the Zygote socket opened by init.
136 */
137
138static int gZygoteSocketFD = -1;
139
140/**
141 * The file descriptor for the Blastula pool socket opened by init.
142 */
143
144static int gBlastulaPoolSocketFD = -1;
145
146/**
147 * The number of Blastulas currently in this Zygote's pool.
148 */
149static std::atomic_uint32_t gBlastulaPoolCount = 0;
150
151/**
152 * Event file descriptor used to communicate reaped blastulas to the
153 * ZygoteServer.
154 */
155static int gBlastulaPoolEventFD = -1;
156
157/**
Chris Wailesdb132a32019-02-20 10:49:27 -0800158 * The maximum value that the gBlastulaPoolSizeMax variable may take. This value
159 * is a mirror of ZygoteServer.BLASTULA_POOL_SIZE_MAX_LIMIT
Chris Wailesaa1c9622019-01-10 16:55:32 -0800160 */
Chris Wailesdb132a32019-02-20 10:49:27 -0800161static constexpr int BLASTULA_POOL_SIZE_MAX_LIMIT = 100;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800162
163/**
164 * A helper class containing accounting information for Blastulas.
165 */
166class BlastulaTableEntry {
167 public:
168 struct EntryStorage {
169 int32_t pid;
170 int32_t read_pipe_fd;
171
172 bool operator!=(const EntryStorage& other) {
173 return pid != other.pid || read_pipe_fd != other.read_pipe_fd;
174 }
175 };
176
177 private:
178 static constexpr EntryStorage INVALID_ENTRY_VALUE = {-1, -1};
179
180 std::atomic<EntryStorage> mStorage;
181 static_assert(decltype(mStorage)::is_always_lock_free);
182
183 public:
184 constexpr BlastulaTableEntry() : mStorage(INVALID_ENTRY_VALUE) {}
185
186 /**
187 * If the provided PID matches the one stored in this entry, the entry will
188 * be invalidated and the associated file descriptor will be closed. If the
189 * PIDs don't match nothing will happen.
190 *
191 * @param pid The ID of the process who's entry we want to clear.
192 * @return True if the entry was cleared; false otherwise
193 */
194 bool ClearForPID(int32_t pid) {
195 EntryStorage storage = mStorage.load();
196
197 if (storage.pid == pid) {
198 /*
199 * There are three possible outcomes from this compare-and-exchange:
200 * 1) It succeeds, in which case we close the FD
201 * 2) It fails and the new value is INVALID_ENTRY_VALUE, in which case
202 * the entry has already been cleared.
203 * 3) It fails and the new value isn't INVALID_ENTRY_VALUE, in which
204 * case the entry has already been cleared and re-used.
205 *
206 * In all three cases the goal of the caller has been met and we can
207 * return true.
208 */
209 if (mStorage.compare_exchange_strong(storage, INVALID_ENTRY_VALUE)) {
210 close(storage.read_pipe_fd);
211 }
212
213 return true;
214 } else {
215 return false;
216 }
217 }
218
Chris Wailesae937142019-01-24 12:57:33 -0800219 void Clear() {
Chris Wailesdb132a32019-02-20 10:49:27 -0800220 EntryStorage storage = mStorage.load();
221
222 if (storage != INVALID_ENTRY_VALUE) {
223 close(storage.read_pipe_fd);
224 mStorage.store(INVALID_ENTRY_VALUE);
225 }
226 }
227
228 void Invalidate() {
Chris Wailesae937142019-01-24 12:57:33 -0800229 mStorage.store(INVALID_ENTRY_VALUE);
230 }
231
Chris Wailesaa1c9622019-01-10 16:55:32 -0800232 /**
233 * @return A copy of the data stored in this entry.
234 */
235 std::optional<EntryStorage> GetValues() {
236 EntryStorage storage = mStorage.load();
237
238 if (storage != INVALID_ENTRY_VALUE) {
239 return storage;
240 } else {
241 return std::nullopt;
242 }
243 }
244
245 /**
246 * Sets the entry to the given values if it is currently invalid.
247 *
248 * @param pid The process ID for the new entry.
249 * @param read_pipe_fd The read end of the blastula control pipe for this
250 * process.
251 * @return True if the entry was set; false otherwise.
252 */
253 bool SetIfInvalid(int32_t pid, int32_t read_pipe_fd) {
254 EntryStorage new_value_storage;
255
256 new_value_storage.pid = pid;
257 new_value_storage.read_pipe_fd = read_pipe_fd;
258
259 EntryStorage expected = INVALID_ENTRY_VALUE;
260
261 return mStorage.compare_exchange_strong(expected, new_value_storage);
262 }
263};
264
265/**
266 * A table containing information about the Blastulas currently in the pool.
267 *
268 * Multiple threads may be attempting to modify the table, either from the
269 * signal handler or from the ZygoteServer poll loop. Atomic loads/stores in
270 * the BlastulaTableEntry class prevent data races during these concurrent
271 * operations.
272 */
Chris Wailesdb132a32019-02-20 10:49:27 -0800273static std::array<BlastulaTableEntry, BLASTULA_POOL_SIZE_MAX_LIMIT> gBlastulaTable;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800274
275/**
276 * The list of open zygote file descriptors.
277 */
278static FileDescriptorTable* gOpenFdTable = nullptr;
279
Narayan Kamath973b4662014-03-31 13:41:26 +0100280// Must match values in com.android.internal.os.Zygote.
281enum MountExternalKind {
282 MOUNT_EXTERNAL_NONE = 0,
Jeff Sharkey48877892015-03-18 11:27:19 -0700283 MOUNT_EXTERNAL_DEFAULT = 1,
Jeff Sharkey9527b222015-06-24 15:24:48 -0700284 MOUNT_EXTERNAL_READ = 2,
285 MOUNT_EXTERNAL_WRITE = 3,
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800286 MOUNT_EXTERNAL_LEGACY = 4,
287 MOUNT_EXTERNAL_INSTALLER = 5,
288 MOUNT_EXTERNAL_FULL = 6,
Narayan Kamath973b4662014-03-31 13:41:26 +0100289};
290
Orion Hodson8d005a62018-12-05 12:28:53 +0000291// Must match values in com.android.internal.os.Zygote.
292enum RuntimeFlags : uint32_t {
293 DEBUG_ENABLE_JDWP = 1,
Yabin Cui4d8546d2019-01-29 16:29:20 -0800294 PROFILE_FROM_SHELL = 1 << 15,
Orion Hodson8d005a62018-12-05 12:28:53 +0000295};
296
Chris Wailesaa1c9622019-01-10 16:55:32 -0800297// Forward declaration so we don't have to move the signal handler.
298static bool RemoveBlastulaTableEntry(pid_t blastula_pid);
299
Andreas Gampeb053cce2015-11-17 16:38:59 -0800300static void RuntimeAbort(JNIEnv* env, int line, const char* msg) {
301 std::ostringstream oss;
302 oss << __FILE__ << ":" << line << ": " << msg;
303 env->FatalError(oss.str().c_str());
Narayan Kamath973b4662014-03-31 13:41:26 +0100304}
305
306// This signal handler is for zygote mode, since the zygote must reap its children
307static void SigChldHandler(int /*signal_number*/) {
308 pid_t pid;
309 int status;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800310 int64_t blastulas_removed = 0;
Narayan Kamath973b4662014-03-31 13:41:26 +0100311
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700312 // It's necessary to save and restore the errno during this function.
313 // Since errno is stored per thread, changing it here modifies the errno
314 // on the thread on which this signal handler executes. If a signal occurs
315 // between a call and an errno check, it's possible to get the errno set
316 // here.
317 // See b/23572286 for extra information.
318 int saved_errno = errno;
319
Narayan Kamath973b4662014-03-31 13:41:26 +0100320 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
wangmingming16d0dd1a2018-11-14 10:43:36 +0800321 // Log process-death status that we care about.
Narayan Kamath973b4662014-03-31 13:41:26 +0100322 if (WIFEXITED(status)) {
wangmingming16d0dd1a2018-11-14 10:43:36 +0800323 async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
324 "Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
Narayan Kamath973b4662014-03-31 13:41:26 +0100325 } else if (WIFSIGNALED(status)) {
wangmingming16d0dd1a2018-11-14 10:43:36 +0800326 async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
327 "Process %d exited due to signal %d (%s)%s", pid,
328 WTERMSIG(status), strsignal(WTERMSIG(status)),
329 WCOREDUMP(status) ? "; core dumped" : "");
Narayan Kamath973b4662014-03-31 13:41:26 +0100330 }
331
332 // If the just-crashed process is the system_server, bring down zygote
333 // so that it is restarted by init and system server will be restarted
334 // from there.
335 if (pid == gSystemServerPid) {
wangmingming16d0dd1a2018-11-14 10:43:36 +0800336 async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
337 "Exit zygote because system server (pid %d) has terminated", pid);
Narayan Kamath973b4662014-03-31 13:41:26 +0100338 kill(getpid(), SIGKILL);
339 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800340
341 // Check to see if the PID is in the blastula pool and remove it if it is.
342 if (RemoveBlastulaTableEntry(pid)) {
343 ++blastulas_removed;
344 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100345 }
346
Narayan Kamath160992d2014-04-14 14:46:07 +0100347 // Note that we shouldn't consider ECHILD an error because
348 // the secondary zygote might have no children left to wait for.
349 if (pid < 0 && errno != ECHILD) {
wangmingming16d0dd1a2018-11-14 10:43:36 +0800350 async_safe_format_log(ANDROID_LOG_WARN, LOG_TAG,
351 "Zygote SIGCHLD error in waitpid: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100352 }
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700353
Chris Wailesaa1c9622019-01-10 16:55:32 -0800354 if (blastulas_removed > 0) {
355 if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) {
356 // If this write fails something went terribly wrong. We will now kill
357 // the zygote and let the system bring it back up.
wangmingming16d0dd1a2018-11-14 10:43:36 +0800358 async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
359 "Zygote failed to write to blastula pool event FD: %s",
360 strerror(errno));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800361 kill(getpid(), SIGKILL);
362 }
363 }
364
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700365 errno = saved_errno;
Narayan Kamath973b4662014-03-31 13:41:26 +0100366}
367
yuanhao435e84b2018-01-15 15:37:02 +0800368// Configures the SIGCHLD/SIGHUP handlers for the zygote process. This is
369// configured very late, because earlier in the runtime we may fork() and
370// exec() other processes, and we want to waitpid() for those rather than
Narayan Kamath973b4662014-03-31 13:41:26 +0100371// have them be harvested immediately.
372//
yuanhao435e84b2018-01-15 15:37:02 +0800373// Ignore SIGHUP because all processes forked by the zygote are in the same
374// process group as the zygote and we don't want to be notified if we become
375// an orphaned group and have one or more stopped processes. This is not a
376// theoretical concern :
377// - we can become an orphaned group if one of our direct descendants forks
378// and is subsequently killed before its children.
379// - crash_dump routinely STOPs the process it's tracing.
380//
381// See issues b/71965619 and b/25567761 for further details.
382//
Narayan Kamath973b4662014-03-31 13:41:26 +0100383// This ends up being called repeatedly before each fork(), but there's
384// no real harm in that.
yuanhao435e84b2018-01-15 15:37:02 +0800385static void SetSignalHandlers() {
386 struct sigaction sig_chld = {};
387 sig_chld.sa_handler = SigChldHandler;
Narayan Kamath973b4662014-03-31 13:41:26 +0100388
Chris Wailesaa1c9622019-01-10 16:55:32 -0800389 if (sigaction(SIGCHLD, &sig_chld, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700390 ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100391 }
yuanhao435e84b2018-01-15 15:37:02 +0800392
393 struct sigaction sig_hup = {};
394 sig_hup.sa_handler = SIG_IGN;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800395 if (sigaction(SIGHUP, &sig_hup, nullptr) < 0) {
yuanhao435e84b2018-01-15 15:37:02 +0800396 ALOGW("Error setting SIGHUP handler: %s", strerror(errno));
397 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100398}
399
400// Sets the SIGCHLD handler back to default behavior in zygote children.
yuanhao435e84b2018-01-15 15:37:02 +0800401static void UnsetChldSignalHandler() {
Narayan Kamath973b4662014-03-31 13:41:26 +0100402 struct sigaction sa;
403 memset(&sa, 0, sizeof(sa));
404 sa.sa_handler = SIG_DFL;
405
Chris Wailesaa1c9622019-01-10 16:55:32 -0800406 if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700407 ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100408 }
409}
410
411// Calls POSIX setgroups() using the int[] object as an argument.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800412// A nullptr argument is tolerated.
413static void SetGids(JNIEnv* env, jintArray managed_gids, fail_fn_t fail_fn) {
414 if (managed_gids == nullptr) {
415 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100416 }
417
Chris Wailesaa1c9622019-01-10 16:55:32 -0800418 ScopedIntArrayRO gids(env, managed_gids);
419 if (gids.get() == nullptr) {
420 fail_fn(CREATE_ERROR("Getting gids int array failed"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100421 }
Andreas Gamped5758f62018-03-12 12:08:55 -0700422
Chris Wailesaa1c9622019-01-10 16:55:32 -0800423 if (setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0])) == -1) {
424 fail_fn(CREATE_ERROR("setgroups failed: %s, gids.size=%zu", strerror(errno), gids.size()));
425 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100426}
427
428// Sets the resource limits via setrlimit(2) for the values in the
429// two-dimensional array of integers that's passed in. The second dimension
Chris Wailesaa1c9622019-01-10 16:55:32 -0800430// contains a tuple of length 3: (resource, rlim_cur, rlim_max). nullptr is
Narayan Kamath973b4662014-03-31 13:41:26 +0100431// treated as an empty array.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800432static void SetRLimits(JNIEnv* env, jobjectArray managed_rlimits, fail_fn_t fail_fn) {
433 if (managed_rlimits == nullptr) {
434 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100435 }
436
437 rlimit rlim;
438 memset(&rlim, 0, sizeof(rlim));
439
Chris Wailesaa1c9622019-01-10 16:55:32 -0800440 for (int i = 0; i < env->GetArrayLength(managed_rlimits); ++i) {
441 ScopedLocalRef<jobject>
442 managed_rlimit_object(env, env->GetObjectArrayElement(managed_rlimits, i));
443 ScopedIntArrayRO rlimit_handle(env, reinterpret_cast<jintArray>(managed_rlimit_object.get()));
444
445 if (rlimit_handle.size() != 3) {
446 fail_fn(CREATE_ERROR("rlimits array must have a second dimension of size 3"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100447 }
448
Chris Wailesaa1c9622019-01-10 16:55:32 -0800449 rlim.rlim_cur = rlimit_handle[1];
450 rlim.rlim_max = rlimit_handle[2];
Narayan Kamath973b4662014-03-31 13:41:26 +0100451
Chris Wailesaa1c9622019-01-10 16:55:32 -0800452 if (setrlimit(rlimit_handle[0], &rlim) == -1) {
453 fail_fn(CREATE_ERROR("setrlimit(%d, {%ld, %ld}) failed",
454 rlimit_handle[0], rlim.rlim_cur, rlim.rlim_max));
Narayan Kamath973b4662014-03-31 13:41:26 +0100455 }
456 }
457}
458
Orion Hodson8d005a62018-12-05 12:28:53 +0000459static void EnableDebugger() {
460 // To let a non-privileged gdbserver attach to this
461 // process, we must set our dumpable flag.
462 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
463 ALOGE("prctl(PR_SET_DUMPABLE) failed");
464 }
465
466 // A non-privileged native debugger should be able to attach to the debuggable app, even if Yama
467 // is enabled (see kernel/Documentation/security/Yama.txt).
468 if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) {
469 // if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this
470 // case since it's expected behaviour.
471 if (errno != EINVAL) {
472 ALOGE("prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed");
473 }
474 }
475
Orion Hodson2b71ad02018-12-07 16:44:33 +0000476 // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
477 if (!GetBoolProperty("persist.zygote.core_dump", false)) {
478 // Set the soft limit on core dump size to 0 without changing the hard limit.
479 rlimit rl;
480 if (getrlimit(RLIMIT_CORE, &rl) == -1) {
481 ALOGE("getrlimit(RLIMIT_CORE) failed");
482 } else {
483 rl.rlim_cur = 0;
484 if (setrlimit(RLIMIT_CORE, &rl) == -1) {
485 ALOGE("setrlimit(RLIMIT_CORE) failed");
486 }
Orion Hodson8d005a62018-12-05 12:28:53 +0000487 }
488 }
489}
490
Narayan Kamath973b4662014-03-31 13:41:26 +0100491// The debug malloc library needs to know whether it's the zygote or a child.
492extern "C" int gMallocLeakZygoteChild;
493
Christopher Ferris76de39e2017-06-20 16:13:40 -0700494static void PreApplicationInit() {
495 // The child process sets this to indicate it's not the zygote.
496 gMallocLeakZygoteChild = 1;
497
498 // Set the jemalloc decay time to 1.
499 mallopt(M_DECAY_TIME, 1);
500}
501
Martijn Coenen86f08a52019-01-03 16:23:01 +0100502static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800503 if (!g_is_security_enforced) {
504 ALOGI("seccomp disabled by setenforce 0");
505 return;
506 }
507
508 // Apply system or app filter based on uid.
Victor Hsiehfa046a12018-03-28 16:26:28 -0700509 if (uid >= AID_APP_START) {
Martijn Coenen86f08a52019-01-03 16:23:01 +0100510 if (is_child_zygote) {
Martijn Coenen6ef16802019-01-18 16:40:01 +0100511 set_app_zygote_seccomp_filter();
Martijn Coenen86f08a52019-01-03 16:23:01 +0100512 } else {
513 set_app_seccomp_filter();
514 }
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800515 } else {
516 set_system_seccomp_filter();
517 }
518}
519
Chris Wailesaa1c9622019-01-10 16:55:32 -0800520static void EnableKeepCapabilities(fail_fn_t fail_fn) {
521 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
522 fail_fn(CREATE_ERROR("prctl(PR_SET_KEEPCAPS) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100523 }
524}
525
Chris Wailesaa1c9622019-01-10 16:55:32 -0800526static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) {
527 for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {;
528 if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100529 if (errno == EINVAL) {
530 ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
531 "your kernel is compiled with file capabilities support");
532 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800533 fail_fn(CREATE_ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100534 }
535 }
536 }
537}
538
Chris Wailesaa1c9622019-01-10 16:55:32 -0800539static void SetInheritable(uint64_t inheritable, fail_fn_t fail_fn) {
Josh Gao45dab782017-02-01 14:56:09 -0800540 __user_cap_header_struct capheader;
541 memset(&capheader, 0, sizeof(capheader));
542 capheader.version = _LINUX_CAPABILITY_VERSION_3;
543 capheader.pid = 0;
544
545 __user_cap_data_struct capdata[2];
546 if (capget(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800547 fail_fn(CREATE_ERROR("capget failed: %s", strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800548 }
549
550 capdata[0].inheritable = inheritable;
551 capdata[1].inheritable = inheritable >> 32;
552
553 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800554 fail_fn(CREATE_ERROR("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800555 }
556}
557
Chris Wailesaa1c9622019-01-10 16:55:32 -0800558static void SetCapabilities(uint64_t permitted, uint64_t effective, uint64_t inheritable,
559 fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100560 __user_cap_header_struct capheader;
561 memset(&capheader, 0, sizeof(capheader));
562 capheader.version = _LINUX_CAPABILITY_VERSION_3;
563 capheader.pid = 0;
564
565 __user_cap_data_struct capdata[2];
566 memset(&capdata, 0, sizeof(capdata));
567 capdata[0].effective = effective;
568 capdata[1].effective = effective >> 32;
569 capdata[0].permitted = permitted;
570 capdata[1].permitted = permitted >> 32;
Josh Gao45dab782017-02-01 14:56:09 -0800571 capdata[0].inheritable = inheritable;
572 capdata[1].inheritable = inheritable >> 32;
Narayan Kamath973b4662014-03-31 13:41:26 +0100573
574 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800575 fail_fn(CREATE_ERROR("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") "
576 "failed: %s", permitted, effective, inheritable, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100577 }
578}
579
Chris Wailesaa1c9622019-01-10 16:55:32 -0800580static void SetSchedulerPolicy(fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100581 errno = -set_sched_policy(0, SP_DEFAULT);
582 if (errno != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800583 fail_fn(CREATE_ERROR("set_sched_policy(0, SP_DEFAULT) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100584 }
585}
586
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700587static int UnmountTree(const char* path) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800588 size_t path_len = strlen(path);
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700589
Sudheer Shanka74584a52019-02-22 13:04:41 -0800590 FILE* fp = setmntent("/proc/mounts", "r");
591 if (fp == nullptr) {
592 ALOGE("Error opening /proc/mounts: %s", strerror(errno));
593 return -errno;
594 }
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700595
Sudheer Shanka74584a52019-02-22 13:04:41 -0800596 // Some volumes can be stacked on each other, so force unmount in
597 // reverse order to give us the best chance of success.
598 std::list<std::string> to_unmount;
599 mntent* mentry;
600 while ((mentry = getmntent(fp)) != nullptr) {
601 if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
602 to_unmount.push_front(std::string(mentry->mnt_dir));
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700603 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800604 }
605 endmntent(fp);
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700606
Sudheer Shanka74584a52019-02-22 13:04:41 -0800607 for (const auto& path : to_unmount) {
608 if (umount2(path.c_str(), MNT_DETACH)) {
609 ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700610 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800611 }
612 return 0;
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700613}
614
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800615static void CreateDir(const std::string& dir,
616 mode_t mode, uid_t uid, gid_t gid,
617 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800618 if (TEMP_FAILURE_RETRY(access(dir.c_str(), F_OK)) == 0) {
619 return;
620 } else if (errno != ENOENT) {
621 fail_fn(CREATE_ERROR("Failed to stat %s: %s", dir.c_str(), strerror(errno)));
622 }
623 if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
624 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s",
625 dir.c_str(), strerror(errno)));
626 }
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800627}
628
Sudheer Shanka74584a52019-02-22 13:04:41 -0800629static void CreatePkgSandboxTarget(userid_t user_id, fail_fn_t fail_fn) {
630 // Create /mnt/user/0/package
631 std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
632 CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800633
Sudheer Shanka74584a52019-02-22 13:04:41 -0800634 StringAppendF(&pkg_sandbox_dir, "/package");
635 CreateDir(pkg_sandbox_dir, 0755, AID_ROOT, AID_ROOT, fail_fn);
Sudheer Shanka663b1042018-07-30 17:34:21 -0700636}
637
Sudheer Shanka74584a52019-02-22 13:04:41 -0800638static void BindMount(const std::string& source_dir, const std::string& target_dir,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800639 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800640 if (TEMP_FAILURE_RETRY(mount(source_dir.c_str(), target_dir.c_str(), nullptr,
641 MS_BIND, nullptr)) == -1) {
642 fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
643 source_dir.c_str(), target_dir.c_str(), strerror(errno)));
644 }
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800645}
646
Sudheer Shanka74584a52019-02-22 13:04:41 -0800647static void MountPkgSpecificDir(const std::string& mnt_source_root,
648 const std::string& mnt_target_root,
649 const std::string& package_name,
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800650 uid_t uid,
Sudheer Shanka74584a52019-02-22 13:04:41 -0800651 const char* dir_name,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800652 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800653 std::string mnt_source_dir = StringPrintf("%s/Android/%s/%s",
654 mnt_source_root.c_str(), dir_name, package_name.c_str());
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800655
Sudheer Shanka74584a52019-02-22 13:04:41 -0800656 std::string mnt_target_dir = StringPrintf("%s/Android/%s/%s",
657 mnt_target_root.c_str(), dir_name, package_name.c_str());
Chris Wailesaa1c9622019-01-10 16:55:32 -0800658
Sudheer Shanka74584a52019-02-22 13:04:41 -0800659 BindMount(mnt_source_dir, mnt_target_dir, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700660}
661
Sudheer Shanka74584a52019-02-22 13:04:41 -0800662static void CreateSubDirs(int parent_fd, const std::string& parent_path,
663 const std::vector<std::string>& sub_dirs,
Sudheer Shankac8cd0c12019-02-14 19:09:48 +0000664 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800665 for (auto& dir_name : sub_dirs) {
666 struct stat sb;
667 if (TEMP_FAILURE_RETRY(fstatat(parent_fd, dir_name.c_str(), &sb, 0)) == 0) {
668 if (S_ISDIR(sb.st_mode)) {
669 continue;
670 } else if (TEMP_FAILURE_RETRY(unlinkat(parent_fd, dir_name.c_str(), 0)) == -1) {
671 fail_fn(CREATE_ERROR("Failed to unlinkat on %s/%s: %s",
672 parent_path.c_str(), dir_name.c_str(), strerror(errno)));
673 }
674 } else if (errno != ENOENT) {
675 fail_fn(CREATE_ERROR("Failed to fstatat on %s/%s: %s",
676 parent_path.c_str(), dir_name.c_str(), strerror(errno)));
Sudheer Shankad8b4f102019-02-12 19:01:21 -0800677 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800678 if (TEMP_FAILURE_RETRY(mkdirat(parent_fd, dir_name.c_str(), 0700)) == -1 && errno != EEXIST) {
679 fail_fn(CREATE_ERROR("Failed to mkdirat on %s/%s: %s",
680 parent_path.c_str(), dir_name.c_str(), strerror(errno)));
681 }
682 }
Sudheer Shankac8cd0c12019-02-14 19:09:48 +0000683}
684
685static void EnsurePkgSpecificDirs(const std::string& path,
Sudheer Shanka74584a52019-02-22 13:04:41 -0800686 const std::vector<std::string>& package_names,
687 bool create_sandbox_dir,
Sudheer Shankac8cd0c12019-02-14 19:09:48 +0000688 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800689 std::string android_dir = StringPrintf("%s/Android", path.c_str());
690 android::base::unique_fd android_fd(open(android_dir.c_str(),
691 O_RDONLY | O_DIRECTORY | O_CLOEXEC));
692 if (android_fd.get() < 0) {
693 if (errno == ENOENT || errno == ENOTDIR) {
694 if (errno == ENOTDIR && TEMP_FAILURE_RETRY(unlink(android_dir.c_str())) == -1) {
695 fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
696 android_dir.c_str(), strerror(errno)));
697 }
698 if (TEMP_FAILURE_RETRY(mkdir(android_dir.c_str(), 0700)) == -1
699 && errno != EEXIST) {
Sudheer Shankac8cd0c12019-02-14 19:09:48 +0000700 fail_fn(CREATE_ERROR("Failed to mkdir %s: %s",
Sudheer Shanka74584a52019-02-22 13:04:41 -0800701 android_dir.c_str(), strerror(errno)));
702 }
703 android_fd.reset(open(android_dir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800704 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800705
706 if (android_fd.get() < 0) {
707 fail_fn(CREATE_ERROR("Failed to open %s: %s", android_dir.c_str(), strerror(errno)));
708 }
709 }
710
711 std::vector<std::string> data_media_obb_dirs = {"data", "media", "obb"};
712 if (create_sandbox_dir) {
713 data_media_obb_dirs.push_back("sandbox");
714 }
715 CreateSubDirs(android_fd.get(), android_dir, data_media_obb_dirs, fail_fn);
716 if (create_sandbox_dir) {
717 data_media_obb_dirs.pop_back();
718 }
719 for (auto& dir_name : data_media_obb_dirs) {
720 std::string data_dir = StringPrintf("%s/%s", android_dir.c_str(), dir_name.c_str());
721 android::base::unique_fd data_fd(openat(android_fd, dir_name.c_str(),
722 O_RDONLY | O_DIRECTORY | O_CLOEXEC));
723 if (data_fd.get() < 0) {
724 fail_fn(CREATE_ERROR("Failed to openat %s/%s: %s",
725 android_dir.c_str(), dir_name.c_str(), strerror(errno)));
726 }
727 CreateSubDirs(data_fd.get(), data_dir, package_names, fail_fn);
728 }
Sudheer Shanka932d51d2019-02-08 10:43:10 -0800729}
730
Sudheer Shanka74584a52019-02-22 13:04:41 -0800731static void CreatePkgSandboxSource(const std::string& sandbox_source, fail_fn_t fail_fn) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800732
Sudheer Shanka74584a52019-02-22 13:04:41 -0800733 struct stat sb;
734 if (TEMP_FAILURE_RETRY(stat(sandbox_source.c_str(), &sb)) == 0) {
735 if (S_ISDIR(sb.st_mode)) {
736 return;
737 } else if (TEMP_FAILURE_RETRY(unlink(sandbox_source.c_str())) == -1) {
738 fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
739 sandbox_source.c_str(), strerror(errno)));
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700740 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800741 } else if (errno != ENOENT) {
742 fail_fn(CREATE_ERROR("Failed to stat %s: %s",
743 sandbox_source.c_str(), strerror(errno)));
744 }
745 if (TEMP_FAILURE_RETRY(mkdir(sandbox_source.c_str(), 0700)) == -1 && errno != EEXIST) {
746 fail_fn(CREATE_ERROR("Failed to mkdir %s: %s",
747 sandbox_source.c_str(), strerror(errno)));
748 }
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700749}
750
Sudheer Shanka74584a52019-02-22 13:04:41 -0800751static void PreparePkgSpecificDirs(const std::vector<std::string>& package_names,
Sudheer Shanka74584a52019-02-22 13:04:41 -0800752 bool mount_all_obbs, const std::string& sandbox_id,
753 userid_t user_id, uid_t uid, fail_fn_t fail_fn) {
Sudheer Shankae51005d2019-02-24 10:24:09 -0800754 std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir("/storage"), closedir);
755 if (!dirp) {
756 fail_fn(CREATE_ERROR("Failed to opendir /storage: %s", strerror(errno)));
757 }
758 struct dirent* ent;
759 while ((ent = readdir(dirp.get()))) {
760 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "self")) {
761 continue;
762 }
763 std::string label(ent->d_name);
764
Sudheer Shanka74584a52019-02-22 13:04:41 -0800765 std::string mnt_source = StringPrintf("/mnt/runtime/write/%s", label.c_str());
766 std::string mnt_target = StringPrintf("/storage/%s", label.c_str());
767 if (label == "emulated") {
768 StringAppendF(&mnt_source, "/%d", user_id);
769 StringAppendF(&mnt_target, "/%d", user_id);
770 }
771
772 if (TEMP_FAILURE_RETRY(access(mnt_source.c_str(), F_OK)) == -1) {
773 ALOGE("Can't access %s: %s", mnt_source.c_str(), strerror(errno));
774 continue;
775 } else if (TEMP_FAILURE_RETRY(access(mnt_target.c_str(), F_OK)) == -1) {
776 ALOGE("Can't access %s: %s", mnt_target.c_str(), strerror(errno));
777 continue;
778 }
779
780 // Ensure /mnt/runtime/write/emulated/0/Android/{data,media,obb}
781 EnsurePkgSpecificDirs(mnt_source, package_names, true, fail_fn);
782
783 std::string sandbox_source = StringPrintf("%s/Android/sandbox/%s",
784 mnt_source.c_str(), sandbox_id.c_str());
785 CreatePkgSandboxSource(sandbox_source, fail_fn);
786 BindMount(sandbox_source, mnt_target, fail_fn);
787
788 // Ensure /storage/emulated/0/Android/{data,media,obb}
789 EnsurePkgSpecificDirs(mnt_target, package_names, false, fail_fn);
790 for (auto& package : package_names) {
791 MountPkgSpecificDir(mnt_source, mnt_target, package, uid, "data", fail_fn);
792 MountPkgSpecificDir(mnt_source, mnt_target, package, uid, "media", fail_fn);
793 if (!mount_all_obbs) {
794 MountPkgSpecificDir(mnt_source, mnt_target, package, uid, "obb", fail_fn);
795 }
796 }
797
798 if (mount_all_obbs) {
799 StringAppendF(&mnt_source, "/Android/obb");
800 StringAppendF(&mnt_target, "/Android/obb");
801 BindMount(mnt_source, mnt_target, fail_fn);
802 }
803 }
804}
805
806static void HandleMountModeInstaller(int mount_mode,
807 userid_t user_id,
808 const std::string& sandbox_id,
Sudheer Shanka03b20ec2019-02-21 15:11:00 -0800809 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800810 std::string obb_mount_dir = StringPrintf("/mnt/user/%d/obb_mount", user_id);
811 std::string obb_mount_file = StringPrintf("%s/%s", obb_mount_dir.c_str(), sandbox_id.c_str());
812 if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
813 if (TEMP_FAILURE_RETRY(access(obb_mount_file.c_str(), F_OK)) != -1) {
814 return;
815 } else if (errno != ENOENT) {
816 fail_fn(CREATE_ERROR("Failed to access %s: %s", obb_mount_file.c_str(), strerror(errno)));
Sudheer Shanka03b20ec2019-02-21 15:11:00 -0800817 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800818 if (fs_prepare_dir(obb_mount_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
819 fail_fn(CREATE_ERROR("Failed to fs_prepare_dir %s: %s",
820 obb_mount_dir.c_str(), strerror(errno)));
821 }
822 const android::base::unique_fd fd(TEMP_FAILURE_RETRY(
823 open(obb_mount_file.c_str(), O_RDWR | O_CREAT, 0600)));
824 if (fd.get() < 0) {
825 fail_fn(CREATE_ERROR("Failed to create %s: %s", obb_mount_file.c_str(), strerror(errno)));
826 }
827 } else {
828 if (TEMP_FAILURE_RETRY(access(obb_mount_file.c_str(), F_OK)) != -1) {
829 if (TEMP_FAILURE_RETRY(unlink(obb_mount_file.c_str())) == -1) {
830 fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
831 obb_mount_dir.c_str(), strerror(errno)));
832 }
833 } else if (errno != ENOENT) {
834 fail_fn(CREATE_ERROR("Failed to access %s: %s", obb_mount_file.c_str(), strerror(errno)));
835 }
836 }
Sudheer Shanka03b20ec2019-02-21 15:11:00 -0800837}
838
Narayan Kamath973b4662014-03-31 13:41:26 +0100839// Create a private mount namespace and bind mount appropriate emulated
840// storage for the given user.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800841static void MountEmulatedStorage(uid_t uid, jint mount_mode,
842 bool force_mount_namespace, const std::string& package_name,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700843 const std::vector<std::string>& packages_for_uid,
Sudheer Shankae51005d2019-02-24 10:24:09 -0800844 const std::string& sandbox_id,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -0800845 fail_fn_t fail_fn) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800846 // See storage config details at http://source.android.com/tech/storage/
Jeff Sharkey9527b222015-06-24 15:24:48 -0700847
Sudheer Shanka74584a52019-02-22 13:04:41 -0800848 String8 storage_source;
849 if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
850 storage_source = "/mnt/runtime/default";
851 } else if (mount_mode == MOUNT_EXTERNAL_READ) {
852 storage_source = "/mnt/runtime/read";
853 } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
854 storage_source = "/mnt/runtime/write";
855 } else if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
856 // Sane default of no storage visible
857 return;
858 }
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400859
Sudheer Shanka74584a52019-02-22 13:04:41 -0800860 // Create a second private mount namespace for our process
861 if (unshare(CLONE_NEWNS) == -1) {
862 fail_fn(CREATE_ERROR("Failed to unshare(): %s", strerror(errno)));
863 }
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400864
Sudheer Shanka74584a52019-02-22 13:04:41 -0800865 // Handle force_mount_namespace with MOUNT_EXTERNAL_NONE.
866 if (mount_mode == MOUNT_EXTERNAL_NONE) {
867 return;
868 }
Robert Sesek06f39302017-03-20 17:30:05 -0400869
Sudheer Shanka74584a52019-02-22 13:04:41 -0800870 if (GetBoolProperty(kIsolatedStorageSnapshot, GetBoolProperty(kIsolatedStorage, true))) {
871 if (mount_mode == MOUNT_EXTERNAL_FULL || mount_mode == MOUNT_EXTERNAL_LEGACY) {
872 storage_source = (mount_mode == MOUNT_EXTERNAL_FULL)
873 ? "/mnt/runtime/full" : "/mnt/runtime/write";
874 if (TEMP_FAILURE_RETRY(mount(storage_source.string(), "/storage",
875 NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
876 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
877 storage_source.string(),
878 strerror(errno)));
879 }
Jeff Sharkey9527b222015-06-24 15:24:48 -0700880
Sudheer Shanka74584a52019-02-22 13:04:41 -0800881 // Mount user-specific symlink helper into place
882 userid_t user_id = multiuser_get_user_id(uid);
883 const String8 user_source(String8::format("/mnt/user/%d", user_id));
884 if (fs_prepare_dir(user_source.string(), 0751, 0, 0) == -1) {
885 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s (%s)",
886 user_source.string(), strerror(errno)));
887 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800888
Sudheer Shanka74584a52019-02-22 13:04:41 -0800889 if (TEMP_FAILURE_RETRY(mount(user_source.string(), "/storage/self", nullptr, MS_BIND,
890 nullptr)) == -1) {
891 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
892 user_source.string(),
893 strerror(errno)));
894 }
Sudheer Shanka663b1042018-07-30 17:34:21 -0700895 } else {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800896 if (package_name.empty() || sandbox_id.empty()) {
897 return;
898 }
Sudheer Shanka663b1042018-07-30 17:34:21 -0700899
Sudheer Shanka74584a52019-02-22 13:04:41 -0800900 userid_t user_id = multiuser_get_user_id(uid);
901 CreatePkgSandboxTarget(user_id, fail_fn);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800902
Sudheer Shankae51005d2019-02-24 10:24:09 -0800903 std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d/package", user_id);
904 if (TEMP_FAILURE_RETRY(mount(pkg_sandbox_dir.c_str(), "/storage",
Sudheer Shanka74584a52019-02-22 13:04:41 -0800905 nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
906 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
Sudheer Shankae51005d2019-02-24 10:24:09 -0800907 pkg_sandbox_dir.c_str(), strerror(errno)));
Sudheer Shanka74584a52019-02-22 13:04:41 -0800908 }
909
910 HandleMountModeInstaller(mount_mode, user_id, sandbox_id, fail_fn);
911
Sudheer Shankae51005d2019-02-24 10:24:09 -0800912 PreparePkgSpecificDirs(packages_for_uid,
Sudheer Shanka74584a52019-02-22 13:04:41 -0800913 mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn);
Jeff Sharkey9527b222015-06-24 15:24:48 -0700914 }
Sudheer Shanka74584a52019-02-22 13:04:41 -0800915 } else {
916 if (TEMP_FAILURE_RETRY(mount(storage_source.string(), "/storage", nullptr,
917 MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
918 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
919 storage_source.string(),
920 strerror(errno)));
921 }
922
923 // Mount user-specific symlink helper into place
924 userid_t user_id = multiuser_get_user_id(uid);
Sudheer Shankae51005d2019-02-24 10:24:09 -0800925 const String8 user_source(String8::format("/mnt/user/%d", user_id));
926 if (fs_prepare_dir(user_source.string(), 0751, 0, 0) == -1) {
Sudheer Shanka74584a52019-02-22 13:04:41 -0800927 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s",
Sudheer Shankae51005d2019-02-24 10:24:09 -0800928 user_source.string()));
Sudheer Shanka74584a52019-02-22 13:04:41 -0800929 }
930
Sudheer Shankae51005d2019-02-24 10:24:09 -0800931 if (TEMP_FAILURE_RETRY(mount(user_source.string(), "/storage/self",
Sudheer Shanka74584a52019-02-22 13:04:41 -0800932 nullptr, MS_BIND, nullptr)) == -1) {
933 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
Sudheer Shankae51005d2019-02-24 10:24:09 -0800934 user_source.string(), strerror(errno)));
Sudheer Shanka74584a52019-02-22 13:04:41 -0800935 }
936 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100937}
938
Narayan Kamath973b4662014-03-31 13:41:26 +0100939static bool NeedsNoRandomizeWorkaround() {
940#if !defined(__arm__)
941 return false;
942#else
943 int major;
944 int minor;
945 struct utsname uts;
946 if (uname(&uts) == -1) {
947 return false;
948 }
949
950 if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
951 return false;
952 }
953
954 // Kernels before 3.4.* need the workaround.
955 return (major < 3) || ((major == 3) && (minor < 4));
956#endif
957}
Narayan Kamath973b4662014-03-31 13:41:26 +0100958
959// Utility to close down the Zygote socket file descriptors while
960// the child is still running as root with Zygote's privileges. Each
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800961// descriptor (if any) is closed via dup3(), replacing it with a valid
Narayan Kamath973b4662014-03-31 13:41:26 +0100962// (open) descriptor to /dev/null.
963
Chris Wailesaa1c9622019-01-10 16:55:32 -0800964static void DetachDescriptors(JNIEnv* env,
965 const std::vector<int>& fds_to_close,
966 fail_fn_t fail_fn) {
967
968 if (fds_to_close.size() > 0) {
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800969 android::base::unique_fd devnull_fd(open("/dev/null", O_RDWR | O_CLOEXEC));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800970 if (devnull_fd == -1) {
971 fail_fn(std::string("Failed to open /dev/null: ").append(strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100972 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800973
974 for (int fd : fds_to_close) {
975 ALOGV("Switching descriptor %d to /dev/null", fd);
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800976 if (dup3(devnull_fd, fd, O_CLOEXEC) == -1) {
977 fail_fn(StringPrintf("Failed dup3() on descriptor %d: %s", fd, strerror(errno)));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800978 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100979 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100980 }
981}
982
Chris Wailesaa1c9622019-01-10 16:55:32 -0800983void SetThreadName(const std::string& thread_name) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100984 bool hasAt = false;
985 bool hasDot = false;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800986
987 for (const char str_el : thread_name) {
988 if (str_el == '.') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100989 hasDot = true;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800990 } else if (str_el == '@') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100991 hasAt = true;
992 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100993 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800994
995 const char* name_start_ptr = thread_name.c_str();
996 if (thread_name.length() >= MAX_NAME_LENGTH && !hasAt && hasDot) {
997 name_start_ptr += thread_name.length() - MAX_NAME_LENGTH;
Narayan Kamath973b4662014-03-31 13:41:26 +0100998 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800999
Narayan Kamath973b4662014-03-31 13:41:26 +01001000 // pthread_setname_np fails rather than truncating long strings.
1001 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
Chris Wailesaa1c9622019-01-10 16:55:32 -08001002 strlcpy(buf, name_start_ptr, sizeof(buf) - 1);
Narayan Kamath973b4662014-03-31 13:41:26 +01001003 errno = pthread_setname_np(pthread_self(), buf);
1004 if (errno != 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -07001005 ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +01001006 }
Andreas Gampe041483a2018-03-05 13:00:42 -08001007 // Update base::logging default tag.
1008 android::base::SetDefaultTag(buf);
Narayan Kamath973b4662014-03-31 13:41:26 +01001009}
1010
Chris Wailesaa1c9622019-01-10 16:55:32 -08001011/**
1012 * A failure function used to report fatal errors to the managed runtime. This
1013 * function is often curried with the process name information and then passed
1014 * to called functions.
1015 *
1016 * @param env Managed runtime environment
1017 * @param process_name A native representation of the process name
1018 * @param managed_process_name A managed representation of the process name
1019 * @param msg The error message to be reported
1020 */
Chris Wailesaf594fc2018-11-02 11:00:07 -07001021[[noreturn]]
1022static void ZygoteFailure(JNIEnv* env,
1023 const char* process_name,
1024 jstring managed_process_name,
1025 const std::string& msg) {
1026 std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr;
1027 if (managed_process_name != nullptr) {
1028 scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name));
1029 if (scoped_managed_process_name_ptr->c_str() != nullptr) {
1030 process_name = scoped_managed_process_name_ptr->c_str();
David Sehrde8d0bd2018-06-22 10:45:36 -07001031 }
1032 }
1033
Chris Wailesaf594fc2018-11-02 11:00:07 -07001034 const std::string& error_msg =
1035 (process_name == nullptr) ? msg : StringPrintf("(%s) %s", process_name, msg.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -07001036
Chris Wailesaf594fc2018-11-02 11:00:07 -07001037 env->FatalError(error_msg.c_str());
1038 __builtin_unreachable();
1039}
David Sehrde8d0bd2018-06-22 10:45:36 -07001040
Chris Wailesaa1c9622019-01-10 16:55:32 -08001041/**
1042 * A helper method for converting managed strings to native strings. A fatal
1043 * error is generated if a problem is encountered in extracting a non-null
1044 * string.
1045 *
1046 * @param env Managed runtime environment
1047 * @param process_name A native representation of the process name
1048 * @param managed_process_name A managed representation of the process name
1049 * @param managed_string The managed string to extract
1050 *
1051 * @return An empty option if the managed string is null. A optional-wrapped
1052 * string otherwise.
1053 */
Chris Wailesaf594fc2018-11-02 11:00:07 -07001054static std::optional<std::string> ExtractJString(JNIEnv* env,
1055 const char* process_name,
1056 jstring managed_process_name,
1057 jstring managed_string) {
1058 if (managed_string == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001059 return std::nullopt;
Chris Wailesaf594fc2018-11-02 11:00:07 -07001060 } else {
1061 ScopedUtfChars scoped_string_chars(env, managed_string);
1062
1063 if (scoped_string_chars.c_str() != nullptr) {
1064 return std::optional<std::string>(scoped_string_chars.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -07001065 } else {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001066 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JString.");
David Sehrde8d0bd2018-06-22 10:45:36 -07001067 }
1068 }
David Sehrde8d0bd2018-06-22 10:45:36 -07001069}
1070
Chris Wailesaa1c9622019-01-10 16:55:32 -08001071/**
1072 * A helper method for converting managed string arrays to native vectors. A
1073 * fatal error is generated if a problem is encountered in extracting a non-null array.
1074 *
1075 * @param env Managed runtime environment
1076 * @param process_name A native representation of the process name
1077 * @param managed_process_name A managed representation of the process name
1078 * @param managed_array The managed integer array to extract
1079 *
1080 * @return An empty option if the managed array is null. A optional-wrapped
1081 * vector otherwise.
1082 */
1083static std::optional<std::vector<int>> ExtractJIntArray(JNIEnv* env,
1084 const char* process_name,
1085 jstring managed_process_name,
1086 jintArray managed_array) {
1087 if (managed_array == nullptr) {
1088 return std::nullopt;
1089 } else {
1090 ScopedIntArrayRO managed_array_handle(env, managed_array);
Narayan Kamath973b4662014-03-31 13:41:26 +01001091
Chris Wailesaa1c9622019-01-10 16:55:32 -08001092 if (managed_array_handle.get() != nullptr) {
1093 std::vector<int> native_array;
1094 native_array.reserve(managed_array_handle.size());
1095
1096 for (size_t array_index = 0; array_index < managed_array_handle.size(); ++array_index) {
1097 native_array.push_back(managed_array_handle[array_index]);
1098 }
1099
1100 return std::move(native_array);
1101
1102 } else {
1103 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JIntArray.");
1104 }
1105 }
1106}
1107
1108/**
1109 * A helper method for converting managed string arrays to native vectors. A
1110 * fatal error is generated if a problem is encountered in extracting a non-null array.
1111 *
1112 * @param env Managed runtime environment
1113 * @param process_name A native representation of the process name
1114 * @param managed_process_name A managed representation of the process name
1115 * @param managed_array The managed string array to extract
1116 *
1117 * @return An empty option if the managed array is null. A optional-wrapped
1118 * vector otherwise.
1119 */
1120static std::optional<std::vector<std::string>> ExtractJStringArray(JNIEnv* env,
1121 const char* process_name,
1122 jstring managed_process_name,
1123 jobjectArray managed_array) {
1124 if (managed_array == nullptr) {
1125 return std::nullopt;
1126 } else {
1127 jsize element_count = env->GetArrayLength(managed_array);
1128 std::vector<std::string> native_string_vector;
1129 native_string_vector.reserve(element_count);
1130
1131 for (jsize array_index = 0; array_index < element_count; ++array_index) {
1132 jstring managed_string = (jstring) env->GetObjectArrayElement(managed_array, array_index);
1133 auto native_string = ExtractJString(env, process_name, managed_process_name, managed_string);
1134
1135 if (LIKELY(native_string.has_value())) {
1136 native_string_vector.emplace_back(std::move(native_string.value()));
1137 } else {
1138 ZygoteFailure(env, process_name, managed_process_name,
1139 "Null string found in managed string array.");
1140 }
1141 }
1142
1143 return std::move(native_string_vector);
1144 }
1145}
1146
1147/**
1148 * A utility function for blocking signals.
1149 *
1150 * @param signum Signal number to block
1151 * @param fail_fn Fatal error reporting function
1152 *
1153 * @see ZygoteFailure
1154 */
1155static void BlockSignal(int signum, fail_fn_t fail_fn) {
1156 sigset_t sigs;
1157 sigemptyset(&sigs);
1158 sigaddset(&sigs, signum);
1159
1160 if (sigprocmask(SIG_BLOCK, &sigs, nullptr) == -1) {
1161 fail_fn(CREATE_ERROR("Failed to block signal %s: %s", strsignal(signum), strerror(errno)));
1162 }
1163}
1164
1165
1166/**
1167 * A utility function for unblocking signals.
1168 *
1169 * @param signum Signal number to unblock
1170 * @param fail_fn Fatal error reporting function
1171 *
1172 * @see ZygoteFailure
1173 */
1174static void UnblockSignal(int signum, fail_fn_t fail_fn) {
1175 sigset_t sigs;
1176 sigemptyset(&sigs);
1177 sigaddset(&sigs, signum);
1178
1179 if (sigprocmask(SIG_UNBLOCK, &sigs, nullptr) == -1) {
1180 fail_fn(CREATE_ERROR("Failed to un-block signal %s: %s", strsignal(signum), strerror(errno)));
1181 }
1182}
1183
Chris Wailesae937142019-01-24 12:57:33 -08001184static void ClearBlastulaTable() {
1185 for (BlastulaTableEntry& entry : gBlastulaTable) {
1186 entry.Clear();
1187 }
1188
1189 gBlastulaPoolCount = 0;
1190}
1191
Chris Wailesaa1c9622019-01-10 16:55:32 -08001192// Utility routine to fork a process from the zygote.
1193static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
1194 const std::vector<int>& fds_to_close,
1195 const std::vector<int>& fds_to_ignore) {
1196 SetSignalHandlers();
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001197
Chris Wailesaf594fc2018-11-02 11:00:07 -07001198 // Curry a failure function.
1199 auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
1200 nullptr, _1);
Andreas Gamped5758f62018-03-12 12:08:55 -07001201
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001202 // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
1203 // log, which would result in the logging FDs we close being reopened.
1204 // This would cause failures because the FDs are not whitelisted.
1205 //
1206 // Note that the zygote process is single threaded at this point.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001207 BlockSignal(SIGCHLD, fail_fn);
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001208
Narayan Kamath3764a262016-08-30 15:36:19 +01001209 // Close any logging related FDs before we start evaluating the list of
1210 // file descriptors.
1211 __android_log_close();
Howard Ro27330412018-10-02 12:08:28 -07001212 stats_log_close();
Narayan Kamath3764a262016-08-30 15:36:19 +01001213
Chris Wailesaf594fc2018-11-02 11:00:07 -07001214 // If this is the first fork for this zygote, create the open FD table. If
1215 // it isn't, we just need to check whether the list of open files has changed
1216 // (and it shouldn't in the normal case).
Chris Wailesaf594fc2018-11-02 11:00:07 -07001217 if (gOpenFdTable == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001218 gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
1219 } else {
1220 gOpenFdTable->Restat(fds_to_ignore, fail_fn);
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001221 }
1222
Josh Gaod7951102018-06-26 16:05:12 -07001223 android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
1224
Narayan Kamath973b4662014-03-31 13:41:26 +01001225 pid_t pid = fork();
1226
1227 if (pid == 0) {
David Sehrde8d0bd2018-06-22 10:45:36 -07001228 // The child process.
Christopher Ferris76de39e2017-06-20 16:13:40 -07001229 PreApplicationInit();
Christopher Ferrisab16dd12017-05-15 16:50:29 -07001230
Narayan Kamath973b4662014-03-31 13:41:26 +01001231 // Clean up any descriptors which must be closed immediately
Chris Wailesaa1c9622019-01-10 16:55:32 -08001232 DetachDescriptors(env, fds_to_close, fail_fn);
Narayan Kamath973b4662014-03-31 13:41:26 +01001233
Chris Wailesae937142019-01-24 12:57:33 -08001234 // Invalidate the entries in the blastula table.
1235 ClearBlastulaTable();
1236
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001237 // Re-open all remaining open file descriptors so that they aren't shared
1238 // with the zygote across a fork.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001239 gOpenFdTable->ReopenOrDetach(fail_fn);
Josh Gaod7951102018-06-26 16:05:12 -07001240
1241 // Turn fdsan back on.
1242 android_fdsan_set_error_level(fdsan_error_level);
Martin Stjernholma9bd8c32019-02-23 02:35:07 +00001243 } else {
1244 ALOGD("Forked child process %d", pid);
David Sehrde8d0bd2018-06-22 10:45:36 -07001245 }
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001246
David Sehrde8d0bd2018-06-22 10:45:36 -07001247 // We blocked SIGCHLD prior to a fork, we unblock it here.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001248 UnblockSignal(SIGCHLD, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001249
Narayan Kamath973b4662014-03-31 13:41:26 +01001250 return pid;
1251}
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001252
Chris Wailesaf594fc2018-11-02 11:00:07 -07001253// Utility routine to specialize a zygote child process.
1254static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
1255 jint runtime_flags, jobjectArray rlimits,
1256 jlong permitted_capabilities, jlong effective_capabilities,
1257 jint mount_external, jstring managed_se_info,
1258 jstring managed_nice_name, bool is_system_server,
1259 bool is_child_zygote, jstring managed_instruction_set,
1260 jstring managed_app_data_dir, jstring managed_package_name,
1261 jobjectArray managed_pacakges_for_uid,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001262 jstring managed_sandbox_id) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001263 const char* process_name = is_system_server ? "system_server" : "zygote";
1264 auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
1265 auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001266
1267 auto se_info = extract_fn(managed_se_info);
1268 auto nice_name = extract_fn(managed_nice_name);
1269 auto instruction_set = extract_fn(managed_instruction_set);
1270 auto app_data_dir = extract_fn(managed_app_data_dir);
1271 auto package_name = extract_fn(managed_package_name);
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001272 auto sandbox_id = extract_fn(managed_sandbox_id);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001273
Chris Wailesaf594fc2018-11-02 11:00:07 -07001274 // Keep capabilities across UID change, unless we're staying root.
1275 if (uid != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001276 EnableKeepCapabilities(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001277 }
1278
Chris Wailesaa1c9622019-01-10 16:55:32 -08001279 SetInheritable(permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001280
Chris Wailesaa1c9622019-01-10 16:55:32 -08001281 DropCapabilitiesBoundingSet(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001282
1283 bool use_native_bridge = !is_system_server &&
1284 instruction_set.has_value() &&
1285 android::NativeBridgeAvailable() &&
1286 android::NeedsNativeBridge(instruction_set.value().c_str());
1287
1288 if (use_native_bridge && !app_data_dir.has_value()) {
1289 // The app_data_dir variable should never be empty if we need to use a
1290 // native bridge. In general, app_data_dir will never be empty for normal
1291 // applications. It can only happen in special cases (for isolated
1292 // processes which are not associated with any app). These are launched by
1293 // the framework and should not be emulated anyway.
1294 use_native_bridge = false;
1295 ALOGW("Native bridge will not be used because managed_app_data_dir == nullptr.");
1296 }
1297
1298 if (!package_name.has_value()) {
1299 if (is_system_server) {
1300 package_name.emplace("android");
1301 } else {
1302 package_name.emplace("");
1303 }
1304 }
1305
Chris Wailesaa1c9622019-01-10 16:55:32 -08001306 std::vector<std::string> packages_for_uid =
1307 ExtractJStringArray(env, process_name, managed_nice_name, managed_pacakges_for_uid).
1308 value_or(std::vector<std::string>());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001309
Chris Wailesaa1c9622019-01-10 16:55:32 -08001310 MountEmulatedStorage(uid, mount_external, use_native_bridge, package_name.value(),
Sudheer Shankae51005d2019-02-24 10:24:09 -08001311 packages_for_uid, sandbox_id.value_or(""), fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001312
1313 // If this zygote isn't root, it won't be able to create a process group,
1314 // since the directory is owned by root.
1315 if (!is_system_server && getuid() == 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001316 const int rc = createProcessGroup(uid, getpid());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001317 if (rc == -EROFS) {
1318 ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
1319 } else if (rc != 0) {
1320 ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
1321 }
1322 }
1323
Chris Wailesaa1c9622019-01-10 16:55:32 -08001324 SetGids(env, gids, fail_fn);
1325 SetRLimits(env, rlimits, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001326
1327 if (use_native_bridge) {
1328 // Due to the logic behind use_native_bridge we know that both app_data_dir
1329 // and instruction_set contain values.
1330 android::PreInitializeNativeBridge(app_data_dir.value().c_str(),
1331 instruction_set.value().c_str());
1332 }
1333
1334 if (setresgid(gid, gid, gid) == -1) {
1335 fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
1336 }
1337
1338 // Must be called when the new process still has CAP_SYS_ADMIN, in this case,
1339 // before changing uid from 0, which clears capabilities. The other
1340 // alternative is to call prctl(PR_SET_NO_NEW_PRIVS, 1) afterward, but that
1341 // breaks SELinux domain transition (see b/71859146). As the result,
1342 // privileged syscalls used below still need to be accessible in app process.
Martijn Coenen86f08a52019-01-03 16:23:01 +01001343 SetUpSeccompFilter(uid, is_child_zygote);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001344
1345 if (setresuid(uid, uid, uid) == -1) {
1346 fail_fn(CREATE_ERROR("setresuid(%d) failed: %s", uid, strerror(errno)));
1347 }
1348
1349 // The "dumpable" flag of a process, which controls core dump generation, is
1350 // overwritten by the value in /proc/sys/fs/suid_dumpable when the effective
1351 // user or group ID changes. See proc(5) for possible values. In most cases,
1352 // the value is 0, so core dumps are disabled for zygote children. However,
1353 // when running in a Chrome OS container, the value is already set to 2,
1354 // which allows the external crash reporter to collect all core dumps. Since
1355 // only system crashes are interested, core dump is disabled for app
1356 // processes. This also ensures compliance with CTS.
1357 int dumpable = prctl(PR_GET_DUMPABLE);
1358 if (dumpable == -1) {
1359 ALOGE("prctl(PR_GET_DUMPABLE) failed: %s", strerror(errno));
1360 RuntimeAbort(env, __LINE__, "prctl(PR_GET_DUMPABLE) failed");
1361 }
1362
1363 if (dumpable == 2 && uid >= AID_APP) {
1364 if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) {
1365 ALOGE("prctl(PR_SET_DUMPABLE, 0) failed: %s", strerror(errno));
1366 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 0) failed");
1367 }
1368 }
1369
Orion Hodson8d005a62018-12-05 12:28:53 +00001370 // Set process properties to enable debugging if required.
1371 if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_JDWP) != 0) {
1372 EnableDebugger();
1373 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001374 if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) {
1375 // simpleperf needs the process to be dumpable to profile it.
1376 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
1377 ALOGE("prctl(PR_SET_DUMPABLE) failed: %s", strerror(errno));
1378 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 1) failed");
1379 }
1380 }
Orion Hodson8d005a62018-12-05 12:28:53 +00001381
Chris Wailesaf594fc2018-11-02 11:00:07 -07001382 if (NeedsNoRandomizeWorkaround()) {
1383 // Work around ARM kernel ASLR lossage (http://b/5817320).
1384 int old_personality = personality(0xffffffff);
1385 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
1386 if (new_personality == -1) {
1387 ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
1388 }
1389 }
1390
Chris Wailesaa1c9622019-01-10 16:55:32 -08001391 SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001392
Chris Wailesaa1c9622019-01-10 16:55:32 -08001393 SetSchedulerPolicy(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001394
Mathieu Chartier0bccbf72019-01-30 15:56:17 -08001395 __android_log_close();
1396 stats_log_close();
1397
Chris Wailesaf594fc2018-11-02 11:00:07 -07001398 const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
1399 const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
1400
1401 if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
1402 fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
1403 uid, is_system_server, se_info_ptr, nice_name_ptr));
1404 }
1405
1406 // Make it easier to debug audit logs by setting the main thread's name to the
1407 // nice name rather than "app_process".
1408 if (nice_name.has_value()) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001409 SetThreadName(nice_name.value());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001410 } else if (is_system_server) {
1411 SetThreadName("system_server");
1412 }
1413
1414 // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
1415 UnsetChldSignalHandler();
1416
1417 if (is_system_server) {
1418 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
1419 if (env->ExceptionCheck()) {
1420 fail_fn("Error calling post fork system server hooks.");
1421 }
Chris Wailesaa1c9622019-01-10 16:55:32 -08001422
Chris Wailesaf594fc2018-11-02 11:00:07 -07001423 // TODO(oth): Remove hardcoded label here (b/117874058).
1424 static const char* kSystemServerLabel = "u:r:system_server:s0";
1425 if (selinux_android_setcon(kSystemServerLabel) != 0) {
1426 fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));
1427 }
1428 }
1429
1430 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
1431 is_system_server, is_child_zygote, managed_instruction_set);
1432
1433 if (env->ExceptionCheck()) {
1434 fail_fn("Error calling post fork hooks.");
1435 }
1436}
1437
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001438static uint64_t GetEffectiveCapabilityMask(JNIEnv* env) {
1439 __user_cap_header_struct capheader;
1440 memset(&capheader, 0, sizeof(capheader));
1441 capheader.version = _LINUX_CAPABILITY_VERSION_3;
1442 capheader.pid = 0;
1443
1444 __user_cap_data_struct capdata[2];
1445 if (capget(&capheader, &capdata[0]) == -1) {
1446 ALOGE("capget failed: %s", strerror(errno));
1447 RuntimeAbort(env, __LINE__, "capget failed");
1448 }
1449
Chris Wailesaf594fc2018-11-02 11:00:07 -07001450 return capdata[0].effective | (static_cast<uint64_t>(capdata[1].effective) << 32);
1451}
1452
1453static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gids,
1454 bool is_child_zygote) {
1455 jlong capabilities = 0;
1456
1457 /*
1458 * Grant the following capabilities to the Bluetooth user:
1459 * - CAP_WAKE_ALARM
1460 * - CAP_NET_RAW
1461 * - CAP_NET_BIND_SERVICE (for DHCP client functionality)
1462 * - CAP_SYS_NICE (for setting RT priority for audio-related threads)
1463 */
1464
1465 if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
1466 capabilities |= (1LL << CAP_WAKE_ALARM);
1467 capabilities |= (1LL << CAP_NET_RAW);
1468 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1469 capabilities |= (1LL << CAP_SYS_NICE);
1470 }
1471
Remi NGUYEN VANc094a542018-12-07 16:52:24 +09001472 if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
1473 capabilities |= (1LL << CAP_NET_ADMIN);
1474 capabilities |= (1LL << CAP_NET_BROADCAST);
1475 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1476 capabilities |= (1LL << CAP_NET_RAW);
1477 }
1478
Chris Wailesaf594fc2018-11-02 11:00:07 -07001479 /*
1480 * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
1481 */
1482
1483 bool gid_wakelock_found = false;
1484 if (gid == AID_WAKELOCK) {
1485 gid_wakelock_found = true;
1486 } else if (gids != nullptr) {
1487 jsize gids_num = env->GetArrayLength(gids);
1488 ScopedIntArrayRO native_gid_proxy(env, gids);
1489
1490 if (native_gid_proxy.get() == nullptr) {
1491 RuntimeAbort(env, __LINE__, "Bad gids array");
1492 }
1493
Chris Wailes31c52c92019-02-14 11:20:02 -08001494 for (int gids_index = 0; gids_index < gids_num; ++gids_index) {
1495 if (native_gid_proxy[gids_index] == AID_WAKELOCK) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001496 gid_wakelock_found = true;
1497 break;
1498 }
1499 }
1500 }
1501
1502 if (gid_wakelock_found) {
1503 capabilities |= (1LL << CAP_BLOCK_SUSPEND);
1504 }
1505
1506 /*
1507 * Grant child Zygote processes the following capabilities:
1508 * - CAP_SETUID (change UID of child processes)
1509 * - CAP_SETGID (change GID of child processes)
1510 * - CAP_SETPCAP (change capabilities of child processes)
1511 */
1512
1513 if (is_child_zygote) {
1514 capabilities |= (1LL << CAP_SETUID);
1515 capabilities |= (1LL << CAP_SETGID);
1516 capabilities |= (1LL << CAP_SETPCAP);
1517 }
1518
1519 /*
1520 * Containers run without some capabilities, so drop any caps that are not
1521 * available.
1522 */
1523
1524 return capabilities & GetEffectiveCapabilityMask(env);
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001525}
Chris Wailesaa1c9622019-01-10 16:55:32 -08001526
1527/**
1528 * Adds the given information about a newly created blastula to the Zygote's
1529 * blastula table.
1530 *
1531 * @param blastula_pid Process ID of the newly created blastula
1532 * @param read_pipe_fd File descriptor for the read end of the blastula
1533 * reporting pipe. Used in the ZygoteServer poll loop to track blastula
1534 * specialization.
1535 */
1536static void AddBlastulaTableEntry(pid_t blastula_pid, int read_pipe_fd) {
1537 static int sBlastulaTableInsertIndex = 0;
1538
1539 int search_index = sBlastulaTableInsertIndex;
1540
1541 do {
1542 if (gBlastulaTable[search_index].SetIfInvalid(blastula_pid, read_pipe_fd)) {
1543 // Start our next search right after where we finished this one.
1544 sBlastulaTableInsertIndex = (search_index + 1) % gBlastulaTable.size();
1545
1546 return;
1547 }
1548
1549 search_index = (search_index + 1) % gBlastulaTable.size();
1550 } while (search_index != sBlastulaTableInsertIndex);
1551
1552 // Much like money in the banana stand, there should always be an entry
1553 // in the blastula table.
1554 __builtin_unreachable();
1555}
1556
1557/**
1558 * Invalidates the entry in the BlastulaTable corresponding to the provided
1559 * process ID if it is present. If an entry was removed the blastula pool
1560 * count is decremented.
1561 *
1562 * @param blastula_pid Process ID of the blastula entry to invalidate
1563 * @return True if an entry was invalidated; false otherwise
1564 */
1565static bool RemoveBlastulaTableEntry(pid_t blastula_pid) {
1566 for (BlastulaTableEntry& entry : gBlastulaTable) {
1567 if (entry.ClearForPID(blastula_pid)) {
1568 --gBlastulaPoolCount;
1569 return true;
1570 }
1571 }
1572
1573 return false;
1574}
1575
1576/**
1577 * @return A vector of the read pipe FDs for each of the active blastulas.
1578 */
1579std::vector<int> MakeBlastulaPipeReadFDVector() {
1580 std::vector<int> fd_vec;
1581 fd_vec.reserve(gBlastulaTable.size());
1582
1583 for (BlastulaTableEntry& entry : gBlastulaTable) {
1584 auto entry_values = entry.GetValues();
1585
1586 if (entry_values.has_value()) {
1587 fd_vec.push_back(entry_values.value().read_pipe_fd);
1588 }
1589 }
1590
1591 return fd_vec;
1592}
1593
Narayan Kamath973b4662014-03-31 13:41:26 +01001594} // anonymous namespace
1595
1596namespace android {
1597
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001598static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001599 // security_getenforce is not allowed on app process. Initialize and cache
1600 // the value before zygote forks.
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001601 g_is_security_enforced = security_getenforce();
1602}
1603
Christopher Ferris76de39e2017-06-20 16:13:40 -07001604static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
1605 PreApplicationInit();
1606}
1607
Narayan Kamath973b4662014-03-31 13:41:26 +01001608static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
1609 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +01001610 jint runtime_flags, jobjectArray rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001611 jint mount_external, jstring se_info, jstring nice_name,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001612 jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001613 jstring instruction_set, jstring app_data_dir, jstring package_name,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001614 jobjectArray packages_for_uid, jstring sandbox_id) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001615 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
Pavlin Radoslavovfbd59042015-11-23 17:13:25 -08001616
Chris Wailesaa1c9622019-01-10 16:55:32 -08001617 if (UNLIKELY(managed_fds_to_close == nullptr)) {
1618 ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
1619 }
1620
1621 std::vector<int> fds_to_close =
1622 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
1623 std::vector<int> fds_to_ignore =
1624 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
1625 .value_or(std::vector<int>());
1626
1627 std::vector<int> blastula_pipes = MakeBlastulaPipeReadFDVector();
1628
1629 fds_to_close.insert(fds_to_close.end(), blastula_pipes.begin(), blastula_pipes.end());
1630 fds_to_ignore.insert(fds_to_ignore.end(), blastula_pipes.begin(), blastula_pipes.end());
1631
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001632 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001633
1634 if (gBlastulaPoolEventFD != -1) {
1635 fds_to_close.push_back(gBlastulaPoolEventFD);
1636 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1637 }
1638
Chris Wailesaf594fc2018-11-02 11:00:07 -07001639 pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001640
David Sehrde8d0bd2018-06-22 10:45:36 -07001641 if (pid == 0) {
1642 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1643 capabilities, capabilities,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001644 mount_external, se_info, nice_name, false,
1645 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001646 package_name, packages_for_uid, sandbox_id);
David Sehrde8d0bd2018-06-22 10:45:36 -07001647 }
1648 return pid;
Narayan Kamath973b4662014-03-31 13:41:26 +01001649}
1650
1651static jint com_android_internal_os_Zygote_nativeForkSystemServer(
1652 JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001653 jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
1654 jlong effective_capabilities) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001655 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1656 fds_to_ignore(fds_to_close);
1657
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001658 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001659
1660 if (gBlastulaPoolEventFD != -1) {
1661 fds_to_close.push_back(gBlastulaPoolEventFD);
1662 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1663 }
1664
Chris Wailesaf594fc2018-11-02 11:00:07 -07001665 pid_t pid = ForkCommon(env, true,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001666 fds_to_close,
1667 fds_to_ignore);
David Sehrde8d0bd2018-06-22 10:45:36 -07001668 if (pid == 0) {
1669 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001670 permitted_capabilities, effective_capabilities,
1671 MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001672 false, nullptr, nullptr, nullptr, nullptr, nullptr);
David Sehrde8d0bd2018-06-22 10:45:36 -07001673 } else if (pid > 0) {
Narayan Kamath973b4662014-03-31 13:41:26 +01001674 // The zygote process checks whether the child process has died or not.
1675 ALOGI("System server process %d has been created", pid);
1676 gSystemServerPid = pid;
1677 // There is a slight window that the system server process has crashed
1678 // but it went unnoticed because we haven't published its pid yet. So
1679 // we recheck here just to make sure that all is well.
1680 int status;
1681 if (waitpid(pid, &status, WNOHANG) == pid) {
1682 ALOGE("System server process %d has died. Restarting Zygote!", pid);
Andreas Gampeb053cce2015-11-17 16:38:59 -08001683 RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
Narayan Kamath973b4662014-03-31 13:41:26 +01001684 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001685
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001686 if (UsePerAppMemcg()) {
Minchan Kim5fa8af22018-06-27 11:32:40 +09001687 // Assign system_server to the correct memory cgroup.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001688 // Not all devices mount memcg so check if it is mounted first
Minchan Kim5fa8af22018-06-27 11:32:40 +09001689 // to avoid unnecessarily printing errors and denials in the logs.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001690 if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
1691 ALOGE("couldn't add process %d into system memcg group", pid);
Minchan Kim5fa8af22018-06-27 11:32:40 +09001692 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001693 }
Narayan Kamath973b4662014-03-31 13:41:26 +01001694 }
1695 return pid;
1696}
1697
Chris Wailesaa1c9622019-01-10 16:55:32 -08001698/**
1699 * A JNI function that forks a blastula from the Zygote while ensuring proper
1700 * file descriptor hygiene.
1701 *
1702 * @param env Managed runtime environment
1703 * @param read_pipe_fd The read FD for the blastula reporting pipe. Manually closed by blastlas
1704 * in managed code.
1705 * @param write_pipe_fd The write FD for the blastula reporting pipe. Manually closed by the
1706 * zygote in managed code.
1707 * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by
1708 * the FD hygiene code and automatically "closed" in the new blastula.
1709 * @return
1710 */
1711static jint com_android_internal_os_Zygote_nativeForkBlastula(JNIEnv* env, jclass,
1712 jint read_pipe_fd, jint write_pipe_fd, jintArray managed_session_socket_fds) {
1713 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1714 fds_to_ignore(fds_to_close);
1715
1716 std::vector<int> session_socket_fds =
1717 ExtractJIntArray(env, "blastula", nullptr, managed_session_socket_fds)
1718 .value_or(std::vector<int>());
1719
1720 // The Blastula Pool Event FD is created during the initialization of the
1721 // blastula pool and should always be valid here.
1722
1723 fds_to_close.push_back(gZygoteSocketFD);
1724 fds_to_close.push_back(gBlastulaPoolEventFD);
1725 fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
1726
1727 fds_to_ignore.push_back(gZygoteSocketFD);
1728 fds_to_ignore.push_back(gBlastulaPoolSocketFD);
1729 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1730 fds_to_ignore.push_back(read_pipe_fd);
1731 fds_to_ignore.push_back(write_pipe_fd);
1732 fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
1733
1734 pid_t blastula_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
1735
1736 if (blastula_pid != 0) {
1737 ++gBlastulaPoolCount;
1738 AddBlastulaTableEntry(blastula_pid, read_pipe_fd);
1739 }
1740
1741 return blastula_pid;
1742}
1743
Robert Sesek54e387d2016-12-02 17:27:50 -05001744static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
1745 JNIEnv* env, jclass, jstring path) {
1746 ScopedUtfChars path_native(env, path);
1747 const char* path_cstr = path_native.c_str();
1748 if (!path_cstr) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001749 RuntimeAbort(env, __LINE__, "path_cstr == nullptr");
Robert Sesek54e387d2016-12-02 17:27:50 -05001750 }
1751 FileDescriptorWhitelist::Get()->Allow(path_cstr);
1752}
1753
doheon1.lee885b7422016-01-20 13:07:27 +09001754static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* env, jclass) {
1755 // Zygote process unmount root storage space initially before every child processes are forked.
1756 // Every forked child processes (include SystemServer) only mount their own root storage space
Robert Seseke4f8d692016-09-13 19:13:01 -04001757 // and no need unmount storage operation in MountEmulatedStorage method.
1758 // Zygote process does not utilize root storage spaces and unshares its mount namespace below.
1759
1760 // See storage config details at http://source.android.com/tech/storage/
1761 // Create private mount namespace shared by all children
1762 if (unshare(CLONE_NEWNS) == -1) {
1763 RuntimeAbort(env, __LINE__, "Failed to unshare()");
1764 return;
1765 }
1766
1767 // Mark rootfs as being a slave so that changes from default
1768 // namespace only flow into our children.
1769 if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
1770 RuntimeAbort(env, __LINE__, "Failed to mount() rootfs as MS_SLAVE");
1771 return;
1772 }
1773
1774 // Create a staging tmpfs that is shared by our children; they will
1775 // bind mount storage into their respective private namespaces, which
1776 // are isolated from each other.
1777 const char* target_base = getenv("EMULATED_STORAGE_TARGET");
1778 if (target_base != nullptr) {
1779#define STRINGIFY_UID(x) __STRING(x)
1780 if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV,
1781 "uid=0,gid=" STRINGIFY_UID(AID_SDCARD_R) ",mode=0751") == -1) {
1782 ALOGE("Failed to mount tmpfs to %s", target_base);
1783 RuntimeAbort(env, __LINE__, "Failed to mount tmpfs");
1784 return;
1785 }
1786#undef STRINGIFY_UID
1787 }
doheon1.lee885b7422016-01-20 13:07:27 +09001788
1789 UnmountTree("/storage");
doheon1.lee885b7422016-01-20 13:07:27 +09001790}
1791
Martijn Coenen86f08a52019-01-03 16:23:01 +01001792static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter(
1793 JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) {
1794 if (!g_is_security_enforced) {
1795 ALOGI("seccomp disabled by setenforce 0");
1796 return;
1797 }
1798
Martijn Coenen86f08a52019-01-03 16:23:01 +01001799 bool installed = install_setuidgid_seccomp_filter(uidGidMin, uidGidMax);
1800 if (!installed) {
1801 RuntimeAbort(env, __LINE__, "Could not install setuid/setgid seccomp filter.");
1802 }
Martijn Coenen86f08a52019-01-03 16:23:01 +01001803}
1804
Chris Wailesaa1c9622019-01-10 16:55:32 -08001805/**
1806 * Called from a blastula to specialize the process for a specific application.
1807 *
1808 * @param env Managed runtime environment
1809 * @param uid User ID of the new application
1810 * @param gid Group ID of the new application
1811 * @param gids Extra groups that the process belongs to
1812 * @param runtime_flags Flags for changing the behavior of the managed runtime
1813 * @param rlimits Resource limits
1814 * @param mount_external The mode (read/write/normal) that external storage will be mounted with
1815 * @param se_info SELinux policy information
1816 * @param nice_name New name for this process
1817 * @param is_child_zygote If the process is to become a WebViewZygote
1818 * @param instruction_set The instruction set expected/requested by the new application
1819 * @param app_data_dir Path to the application's data directory
1820 */
1821static void com_android_internal_os_Zygote_nativeSpecializeBlastula(
1822 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
1823 jint runtime_flags, jobjectArray rlimits,
1824 jint mount_external, jstring se_info, jstring nice_name,
1825 jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001826 jstring package_name, jobjectArray packages_for_uid,
Sudheer Shanka03fd40b2019-02-06 12:39:14 -08001827 jstring sandbox_id) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001828 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
1829
1830 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1831 capabilities, capabilities,
1832 mount_external, se_info, nice_name, false,
1833 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
Sudheer Shankae51005d2019-02-24 10:24:09 -08001834 package_name, packages_for_uid, sandbox_id);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001835}
1836
1837/**
1838 * A helper method for fetching socket file descriptors that were opened by init from the
1839 * environment.
1840 *
1841 * @param env Managed runtime environment
1842 * @param is_primary If this process is the primary or secondary Zygote; used to compute the name
1843 * of the environment variable storing the file descriptors.
1844 */
1845static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclass,
1846 jboolean is_primary) {
1847 std::string android_socket_prefix(ANDROID_SOCKET_PREFIX);
1848 std::string env_var_name = android_socket_prefix + (is_primary ? "zygote" : "zygote_secondary");
1849 char* env_var_val = getenv(env_var_name.c_str());
1850
1851 if (env_var_val != nullptr) {
1852 gZygoteSocketFD = atoi(env_var_val);
1853 ALOGV("Zygote:zygoteSocketFD = %d", gZygoteSocketFD);
1854 } else {
1855 ALOGE("Unable to fetch Zygote socket file descriptor");
1856 }
1857
1858 env_var_name = android_socket_prefix + (is_primary ? "blastula_pool" : "blastula_pool_secondary");
1859 env_var_val = getenv(env_var_name.c_str());
1860
1861 if (env_var_val != nullptr) {
1862 gBlastulaPoolSocketFD = atoi(env_var_val);
1863 ALOGV("Zygote:blastulaPoolSocketFD = %d", gBlastulaPoolSocketFD);
1864 } else {
1865 ALOGE("Unable to fetch Blastula pool socket file descriptor");
1866 }
1867}
1868
1869/**
1870 * @param env Managed runtime environment
1871 * @return A managed array of raw file descriptors for the read ends of the blastula reporting
1872 * pipes.
1873 */
1874static jintArray com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs(JNIEnv* env, jclass) {
1875 std::vector<int> blastula_fds = MakeBlastulaPipeReadFDVector();
1876
1877 jintArray managed_blastula_fds = env->NewIntArray(blastula_fds.size());
1878 env->SetIntArrayRegion(managed_blastula_fds, 0, blastula_fds.size(), blastula_fds.data());
1879
1880 return managed_blastula_fds;
1881}
1882
1883/**
1884 * A JNI wrapper around RemoveBlastulaTableEntry.
1885 *
1886 * @param env Managed runtime environment
1887 * @param blastula_pid Process ID of the blastula entry to invalidate
1888 * @return True if an entry was invalidated; false otherwise.
1889 */
1890static jboolean com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry(JNIEnv* env, jclass,
1891 jint blastula_pid) {
1892 return RemoveBlastulaTableEntry(blastula_pid);
1893}
1894
1895/**
1896 * Creates the blastula pool event FD if it doesn't exist and returns it. This is used by the
1897 * ZygoteServer poll loop to know when to re-fill the blastula pool.
1898 *
1899 * @param env Managed runtime environment
1900 * @return A raw event file descriptor used to communicate (from the signal handler) when the
1901 * Zygote receives a SIGCHLD for a blastula
1902 */
1903static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD(JNIEnv* env, jclass) {
1904 if (gBlastulaPoolEventFD == -1) {
1905 if ((gBlastulaPoolEventFD = eventfd(0, 0)) == -1) {
1906 ZygoteFailure(env, "zygote", nullptr, StringPrintf("Unable to create eventfd: %s", strerror(errno)));
1907 }
1908 }
1909
1910 return gBlastulaPoolEventFD;
1911}
1912
1913/**
1914 * @param env Managed runtime environment
1915 * @return The number of blastulas currently in the blastula pool
1916 */
1917static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolCount(JNIEnv* env, jclass) {
1918 return gBlastulaPoolCount;
1919}
1920
Chris Wailesae937142019-01-24 12:57:33 -08001921/**
1922 * Kills all processes currently in the blastula pool.
1923 *
1924 * @param env Managed runtime environment
1925 * @return The number of blastulas currently in the blastula pool
1926 */
1927static void com_android_internal_os_Zygote_nativeEmptyBlastulaPool(JNIEnv* env, jclass) {
1928 for (auto& entry : gBlastulaTable) {
1929 auto entry_storage = entry.GetValues();
1930
1931 if (entry_storage.has_value()) {
1932 kill(entry_storage.value().pid, SIGKILL);
Chris Wailesdb132a32019-02-20 10:49:27 -08001933 close(entry_storage.value().read_pipe_fd);
1934
1935 // Avoid a second atomic load by invalidating instead of clearing.
1936 entry.Invalidate();
Chris Wailesae937142019-01-24 12:57:33 -08001937 --gBlastulaPoolCount;
1938 }
1939 }
1940}
1941
Daniel Micay76f6a862015-09-19 17:31:01 -04001942static const JNINativeMethod gMethods[] = {
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001943 { "nativeSecurityInit", "()V",
1944 (void *) com_android_internal_os_Zygote_nativeSecurityInit },
Andreas Gampeaec67dc2014-09-02 21:23:06 -07001945 { "nativeForkAndSpecialize",
Sudheer Shankae51005d2019-02-24 10:24:09 -08001946 "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I",
Narayan Kamath973b4662014-03-31 13:41:26 +01001947 (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
1948 { "nativeForkSystemServer", "(II[II[[IJJ)I",
doheon1.lee885b7422016-01-20 13:07:27 +09001949 (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
Robert Sesek54e387d2016-12-02 17:27:50 -05001950 { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
1951 (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
doheon1.lee885b7422016-01-20 13:07:27 +09001952 { "nativeUnmountStorageOnInit", "()V",
Christopher Ferris76de39e2017-06-20 16:13:40 -07001953 (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit },
1954 { "nativePreApplicationInit", "()V",
Martijn Coenen86f08a52019-01-03 16:23:01 +01001955 (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
1956 { "nativeInstallSeccompUidGidFilter", "(II)V",
Chris Wailesaa1c9622019-01-10 16:55:32 -08001957 (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
1958 { "nativeForkBlastula", "(II[I)I",
1959 (void *) com_android_internal_os_Zygote_nativeForkBlastula },
1960 { "nativeSpecializeBlastula",
Sudheer Shankae51005d2019-02-24 10:24:09 -08001961 "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V",
Chris Wailesaa1c9622019-01-10 16:55:32 -08001962 (void *) com_android_internal_os_Zygote_nativeSpecializeBlastula },
1963 { "nativeGetSocketFDs", "(Z)V",
1964 (void *) com_android_internal_os_Zygote_nativeGetSocketFDs },
1965 { "nativeGetBlastulaPipeFDs", "()[I",
1966 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs },
1967 { "nativeRemoveBlastulaTableEntry", "(I)Z",
1968 (void *) com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry },
1969 { "nativeGetBlastulaPoolEventFD", "()I",
1970 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD },
1971 { "nativeGetBlastulaPoolCount", "()I",
Chris Wailesae937142019-01-24 12:57:33 -08001972 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolCount },
1973 { "nativeEmptyBlastulaPool", "()V",
1974 (void *) com_android_internal_os_Zygote_nativeEmptyBlastulaPool }
Narayan Kamath973b4662014-03-31 13:41:26 +01001975};
1976
1977int register_com_android_internal_os_Zygote(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001978 gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
Orion Hodson46724e72018-10-19 13:05:33 +01001979 gCallPostForkSystemServerHooks = GetStaticMethodIDOrDie(env, gZygoteClass,
1980 "callPostForkSystemServerHooks",
1981 "()V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001982 gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
Robert Sesekd0a190df2018-02-12 18:46:01 -05001983 "(IZZLjava/lang/String;)V");
Narayan Kamath973b4662014-03-31 13:41:26 +01001984
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001985 return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
Narayan Kamath973b4662014-03-31 13:41:26 +01001986}
1987} // namespace android