blob: 5a65028469a8d66fdaf8d4ab88215e3bf947c4a8 [file] [log] [blame]
Narayan Kamath973b4662014-03-31 13:41:26 +01001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Chris Waileseac7f4e2019-01-17 14:57:10 -080017/*
18 * Disable optimization of this file if we are compiling with the address
19 * sanitizer. This is a mitigation for b/122921367 and can be removed once the
20 * bug is fixed.
21 */
22#if __has_feature(address_sanitizer)
23#pragma clang optimize off
24#endif
25
Colin Cross18cd9f52014-06-13 12:58:55 -070026#define LOG_TAG "Zygote"
Narayan Kamath973b4662014-03-31 13:41:26 +010027
28// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
29#include <sys/mount.h>
30#include <linux/fs.h>
31
Chris Wailesaa1c9622019-01-10 16:55:32 -080032#include <array>
33#include <atomic>
Chris Wailesaf594fc2018-11-02 11:00:07 -070034#include <functional>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070035#include <list>
Chris Wailesaf594fc2018-11-02 11:00:07 -070036#include <optional>
Andreas Gampeb053cce2015-11-17 16:38:59 -080037#include <sstream>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070038#include <string>
Chris Wailesaa1c9622019-01-10 16:55:32 -080039#include <string_view>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070040
Josh Gaod7951102018-06-26 16:05:12 -070041#include <android/fdsan.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080042#include <arpa/inet.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070043#include <fcntl.h>
Dan Albert46d84442014-11-18 16:07:51 -080044#include <grp.h>
45#include <inttypes.h>
Christopher Ferrisab16dd12017-05-15 16:50:29 -070046#include <malloc.h>
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -070047#include <mntent.h>
Narayan Kamath973b4662014-03-31 13:41:26 +010048#include <paths.h>
49#include <signal.h>
50#include <stdlib.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070051#include <sys/capability.h>
Robert Seseke4f8d692016-09-13 19:13:01 -040052#include <sys/cdefs.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080053#include <sys/eventfd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070054#include <sys/personality.h>
55#include <sys/prctl.h>
56#include <sys/resource.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080057#include <sys/socket.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070058#include <sys/stat.h>
Vitalii Tomkiv5cbce852016-05-18 17:43:02 -070059#include <sys/time.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070060#include <sys/types.h>
61#include <sys/utsname.h>
62#include <sys/wait.h>
Dan Albert46d84442014-11-18 16:07:51 -080063#include <unistd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070064
Chris Wailesaa1c9622019-01-10 16:55:32 -080065#include <android-base/logging.h>
Minchan Kim5fa8af22018-06-27 11:32:40 +090066#include <android-base/properties.h>
Carmen Jacksondd401252017-02-23 15:21:10 -080067#include <android-base/file.h>
68#include <android-base/stringprintf.h>
Chris Wailesaa1c9622019-01-10 16:55:32 -080069#include <android-base/unique_fd.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070070#include <cutils/fs.h>
71#include <cutils/multiuser.h>
Sharvil Nanavati4990e4f2014-06-29 17:06:52 -070072#include <private/android_filesystem_config.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070073#include <utils/String8.h>
74#include <selinux/android.h>
Victor Hsiehc8176ef2018-01-08 12:43:00 -080075#include <seccomp_policy.h>
Howard Ro27330412018-10-02 12:08:28 -070076#include <stats_event_list.h>
Colin Cross0161bbc2014-06-03 13:26:58 -070077#include <processgroup/processgroup.h>
Suren Baghdasaryane4433262019-01-04 12:16:57 -080078#include <processgroup/sched_policy.h>
Colin Cross18cd9f52014-06-13 12:58:55 -070079
Andreas Gampeed6b9df2014-11-20 22:02:20 -080080#include "core_jni_helpers.h"
Steven Moreland2279b252017-07-19 09:50:45 -070081#include <nativehelper/JNIHelp.h>
82#include <nativehelper/ScopedLocalRef.h>
83#include <nativehelper/ScopedPrimitiveArray.h>
84#include <nativehelper/ScopedUtfChars.h>
Robert Sesek8225b7c2016-12-16 14:02:31 -050085#include "fd_utils.h"
Narayan Kamath973b4662014-03-31 13:41:26 +010086
jgu212eacd062014-09-10 06:55:07 -040087#include "nativebridge/native_bridge.h"
88
Narayan Kamath973b4662014-03-31 13:41:26 +010089namespace {
90
Chris Wailesaa1c9622019-01-10 16:55:32 -080091// TODO (chriswailes): Add a function to initialize native Zygote data.
92// TODO (chriswailes): Fix mixed indentation style (2 and 4 spaces).
93
Chris Wailesaf594fc2018-11-02 11:00:07 -070094using namespace std::placeholders;
95
Narayan Kamath973b4662014-03-31 13:41:26 +010096using android::String8;
Sudheer Shanka663b1042018-07-30 17:34:21 -070097using android::base::StringAppendF;
Carmen Jacksondd401252017-02-23 15:21:10 -080098using android::base::StringPrintf;
99using android::base::WriteStringToFile;
Minchan Kim5fa8af22018-06-27 11:32:40 +0900100using android::base::GetBoolProperty;
Narayan Kamath973b4662014-03-31 13:41:26 +0100101
Andreas Gamped5758f62018-03-12 12:08:55 -0700102#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
103 append(StringPrintf(__VA_ARGS__))
104
Chris Wailesaa1c9622019-01-10 16:55:32 -0800105// This type is duplicated in fd_utils.h
106typedef const std::function<void(std::string)>& fail_fn_t;
107
Narayan Kamath973b4662014-03-31 13:41:26 +0100108static pid_t gSystemServerPid = 0;
109
Sudheer Shanka663b1042018-07-30 17:34:21 -0700110static const char kIsolatedStorage[] = "persist.sys.isolated_storage";
Sudheer Shankaa3801582019-01-17 17:19:11 -0800111static const char kIsolatedStorageSnapshot[] = "sys.isolated_storage_snapshot";
Narayan Kamath973b4662014-03-31 13:41:26 +0100112static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
113static jclass gZygoteClass;
Orion Hodson46724e72018-10-19 13:05:33 +0100114static jmethodID gCallPostForkSystemServerHooks;
Narayan Kamath973b4662014-03-31 13:41:26 +0100115static jmethodID gCallPostForkChildHooks;
116
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800117static bool g_is_security_enforced = true;
118
Chris Wailesaa1c9622019-01-10 16:55:32 -0800119/**
120 * The maximum number of characters (not including a null terminator) that a
121 * process name may contain.
122 */
123static constexpr size_t MAX_NAME_LENGTH = 15;
124
125/**
126 * The prefix string for environmental variables storing socket FDs created by
127 * init.
128 */
129
130static constexpr std::string_view ANDROID_SOCKET_PREFIX("ANDROID_SOCKET_");
131
132/**
133 * The file descriptor for the Zygote socket opened by init.
134 */
135
136static int gZygoteSocketFD = -1;
137
138/**
139 * The file descriptor for the Blastula pool socket opened by init.
140 */
141
142static int gBlastulaPoolSocketFD = -1;
143
144/**
145 * The number of Blastulas currently in this Zygote's pool.
146 */
147static std::atomic_uint32_t gBlastulaPoolCount = 0;
148
149/**
150 * Event file descriptor used to communicate reaped blastulas to the
151 * ZygoteServer.
152 */
153static int gBlastulaPoolEventFD = -1;
154
155/**
156 * The maximum value that the gBlastulaPoolMax variable may take. This value
157 * is a mirror of Zygote.BLASTULA_POOL_MAX_LIMIT
158 */
159static constexpr int BLASTULA_POOL_MAX_LIMIT = 10;
160
161/**
162 * A helper class containing accounting information for Blastulas.
163 */
164class BlastulaTableEntry {
165 public:
166 struct EntryStorage {
167 int32_t pid;
168 int32_t read_pipe_fd;
169
170 bool operator!=(const EntryStorage& other) {
171 return pid != other.pid || read_pipe_fd != other.read_pipe_fd;
172 }
173 };
174
175 private:
176 static constexpr EntryStorage INVALID_ENTRY_VALUE = {-1, -1};
177
178 std::atomic<EntryStorage> mStorage;
179 static_assert(decltype(mStorage)::is_always_lock_free);
180
181 public:
182 constexpr BlastulaTableEntry() : mStorage(INVALID_ENTRY_VALUE) {}
183
184 /**
185 * If the provided PID matches the one stored in this entry, the entry will
186 * be invalidated and the associated file descriptor will be closed. If the
187 * PIDs don't match nothing will happen.
188 *
189 * @param pid The ID of the process who's entry we want to clear.
190 * @return True if the entry was cleared; false otherwise
191 */
192 bool ClearForPID(int32_t pid) {
193 EntryStorage storage = mStorage.load();
194
195 if (storage.pid == pid) {
196 /*
197 * There are three possible outcomes from this compare-and-exchange:
198 * 1) It succeeds, in which case we close the FD
199 * 2) It fails and the new value is INVALID_ENTRY_VALUE, in which case
200 * the entry has already been cleared.
201 * 3) It fails and the new value isn't INVALID_ENTRY_VALUE, in which
202 * case the entry has already been cleared and re-used.
203 *
204 * In all three cases the goal of the caller has been met and we can
205 * return true.
206 */
207 if (mStorage.compare_exchange_strong(storage, INVALID_ENTRY_VALUE)) {
208 close(storage.read_pipe_fd);
209 }
210
211 return true;
212 } else {
213 return false;
214 }
215 }
216
217 /**
218 * @return A copy of the data stored in this entry.
219 */
220 std::optional<EntryStorage> GetValues() {
221 EntryStorage storage = mStorage.load();
222
223 if (storage != INVALID_ENTRY_VALUE) {
224 return storage;
225 } else {
226 return std::nullopt;
227 }
228 }
229
230 /**
231 * Sets the entry to the given values if it is currently invalid.
232 *
233 * @param pid The process ID for the new entry.
234 * @param read_pipe_fd The read end of the blastula control pipe for this
235 * process.
236 * @return True if the entry was set; false otherwise.
237 */
238 bool SetIfInvalid(int32_t pid, int32_t read_pipe_fd) {
239 EntryStorage new_value_storage;
240
241 new_value_storage.pid = pid;
242 new_value_storage.read_pipe_fd = read_pipe_fd;
243
244 EntryStorage expected = INVALID_ENTRY_VALUE;
245
246 return mStorage.compare_exchange_strong(expected, new_value_storage);
247 }
248};
249
250/**
251 * A table containing information about the Blastulas currently in the pool.
252 *
253 * Multiple threads may be attempting to modify the table, either from the
254 * signal handler or from the ZygoteServer poll loop. Atomic loads/stores in
255 * the BlastulaTableEntry class prevent data races during these concurrent
256 * operations.
257 */
258static std::array<BlastulaTableEntry, BLASTULA_POOL_MAX_LIMIT> gBlastulaTable;
259
260/**
261 * The list of open zygote file descriptors.
262 */
263static FileDescriptorTable* gOpenFdTable = nullptr;
264
Narayan Kamath973b4662014-03-31 13:41:26 +0100265// Must match values in com.android.internal.os.Zygote.
266enum MountExternalKind {
267 MOUNT_EXTERNAL_NONE = 0,
Jeff Sharkey48877892015-03-18 11:27:19 -0700268 MOUNT_EXTERNAL_DEFAULT = 1,
Jeff Sharkey9527b222015-06-24 15:24:48 -0700269 MOUNT_EXTERNAL_READ = 2,
270 MOUNT_EXTERNAL_WRITE = 3,
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800271 MOUNT_EXTERNAL_LEGACY = 4,
272 MOUNT_EXTERNAL_INSTALLER = 5,
273 MOUNT_EXTERNAL_FULL = 6,
Narayan Kamath973b4662014-03-31 13:41:26 +0100274};
275
Orion Hodson8d005a62018-12-05 12:28:53 +0000276// Must match values in com.android.internal.os.Zygote.
277enum RuntimeFlags : uint32_t {
278 DEBUG_ENABLE_JDWP = 1,
Yabin Cui4d8546d2019-01-29 16:29:20 -0800279 PROFILE_FROM_SHELL = 1 << 15,
Orion Hodson8d005a62018-12-05 12:28:53 +0000280};
281
Chris Wailesaa1c9622019-01-10 16:55:32 -0800282// Forward declaration so we don't have to move the signal handler.
283static bool RemoveBlastulaTableEntry(pid_t blastula_pid);
284
Andreas Gampeb053cce2015-11-17 16:38:59 -0800285static void RuntimeAbort(JNIEnv* env, int line, const char* msg) {
286 std::ostringstream oss;
287 oss << __FILE__ << ":" << line << ": " << msg;
288 env->FatalError(oss.str().c_str());
Narayan Kamath973b4662014-03-31 13:41:26 +0100289}
290
291// This signal handler is for zygote mode, since the zygote must reap its children
292static void SigChldHandler(int /*signal_number*/) {
293 pid_t pid;
294 int status;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800295 int64_t blastulas_removed = 0;
Narayan Kamath973b4662014-03-31 13:41:26 +0100296
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700297 // It's necessary to save and restore the errno during this function.
298 // Since errno is stored per thread, changing it here modifies the errno
299 // on the thread on which this signal handler executes. If a signal occurs
300 // between a call and an errno check, it's possible to get the errno set
301 // here.
302 // See b/23572286 for extra information.
303 int saved_errno = errno;
304
Narayan Kamath973b4662014-03-31 13:41:26 +0100305 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
306 // Log process-death status that we care about. In general it is
307 // not safe to call LOG(...) from a signal handler because of
308 // possible reentrancy. However, we know a priori that the
309 // current implementation of LOG() is safe to call from a SIGCHLD
310 // handler in the zygote process. If the LOG() implementation
311 // changes its locking strategy or its use of syscalls within the
312 // lazy-init critical section, its use here may become unsafe.
313 if (WIFEXITED(status)) {
Josh Gao6d747ca2017-08-02 12:54:05 -0700314 ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
Narayan Kamath973b4662014-03-31 13:41:26 +0100315 } else if (WIFSIGNALED(status)) {
Josh Gao6d747ca2017-08-02 12:54:05 -0700316 ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
Narayan Kamath973b4662014-03-31 13:41:26 +0100317 if (WCOREDUMP(status)) {
318 ALOGI("Process %d dumped core.", pid);
319 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100320 }
321
322 // If the just-crashed process is the system_server, bring down zygote
323 // so that it is restarted by init and system server will be restarted
324 // from there.
325 if (pid == gSystemServerPid) {
Dan Albert46d84442014-11-18 16:07:51 -0800326 ALOGE("Exit zygote because system server (%d) has terminated", pid);
Narayan Kamath973b4662014-03-31 13:41:26 +0100327 kill(getpid(), SIGKILL);
328 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800329
330 // Check to see if the PID is in the blastula pool and remove it if it is.
331 if (RemoveBlastulaTableEntry(pid)) {
332 ++blastulas_removed;
333 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100334 }
335
Narayan Kamath160992d2014-04-14 14:46:07 +0100336 // Note that we shouldn't consider ECHILD an error because
337 // the secondary zygote might have no children left to wait for.
338 if (pid < 0 && errno != ECHILD) {
339 ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100340 }
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700341
Chris Wailesaa1c9622019-01-10 16:55:32 -0800342 if (blastulas_removed > 0) {
343 if (write(gBlastulaPoolEventFD, &blastulas_removed, sizeof(blastulas_removed)) == -1) {
344 // If this write fails something went terribly wrong. We will now kill
345 // the zygote and let the system bring it back up.
346 ALOGE("Zygote failed to write to blastula pool event FD: %s", strerror(errno));
347 kill(getpid(), SIGKILL);
348 }
349 }
350
Christopher Ferrisa8a79542015-08-31 15:40:01 -0700351 errno = saved_errno;
Narayan Kamath973b4662014-03-31 13:41:26 +0100352}
353
yuanhao435e84b2018-01-15 15:37:02 +0800354// Configures the SIGCHLD/SIGHUP handlers for the zygote process. This is
355// configured very late, because earlier in the runtime we may fork() and
356// exec() other processes, and we want to waitpid() for those rather than
Narayan Kamath973b4662014-03-31 13:41:26 +0100357// have them be harvested immediately.
358//
yuanhao435e84b2018-01-15 15:37:02 +0800359// Ignore SIGHUP because all processes forked by the zygote are in the same
360// process group as the zygote and we don't want to be notified if we become
361// an orphaned group and have one or more stopped processes. This is not a
362// theoretical concern :
363// - we can become an orphaned group if one of our direct descendants forks
364// and is subsequently killed before its children.
365// - crash_dump routinely STOPs the process it's tracing.
366//
367// See issues b/71965619 and b/25567761 for further details.
368//
Narayan Kamath973b4662014-03-31 13:41:26 +0100369// This ends up being called repeatedly before each fork(), but there's
370// no real harm in that.
yuanhao435e84b2018-01-15 15:37:02 +0800371static void SetSignalHandlers() {
372 struct sigaction sig_chld = {};
373 sig_chld.sa_handler = SigChldHandler;
Narayan Kamath973b4662014-03-31 13:41:26 +0100374
Chris Wailesaa1c9622019-01-10 16:55:32 -0800375 if (sigaction(SIGCHLD, &sig_chld, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700376 ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100377 }
yuanhao435e84b2018-01-15 15:37:02 +0800378
379 struct sigaction sig_hup = {};
380 sig_hup.sa_handler = SIG_IGN;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800381 if (sigaction(SIGHUP, &sig_hup, nullptr) < 0) {
yuanhao435e84b2018-01-15 15:37:02 +0800382 ALOGW("Error setting SIGHUP handler: %s", strerror(errno));
383 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100384}
385
386// Sets the SIGCHLD handler back to default behavior in zygote children.
yuanhao435e84b2018-01-15 15:37:02 +0800387static void UnsetChldSignalHandler() {
Narayan Kamath973b4662014-03-31 13:41:26 +0100388 struct sigaction sa;
389 memset(&sa, 0, sizeof(sa));
390 sa.sa_handler = SIG_DFL;
391
Chris Wailesaa1c9622019-01-10 16:55:32 -0800392 if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700393 ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100394 }
395}
396
397// Calls POSIX setgroups() using the int[] object as an argument.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800398// A nullptr argument is tolerated.
399static void SetGids(JNIEnv* env, jintArray managed_gids, fail_fn_t fail_fn) {
400 if (managed_gids == nullptr) {
401 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100402 }
403
Chris Wailesaa1c9622019-01-10 16:55:32 -0800404 ScopedIntArrayRO gids(env, managed_gids);
405 if (gids.get() == nullptr) {
406 fail_fn(CREATE_ERROR("Getting gids int array failed"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100407 }
Andreas Gamped5758f62018-03-12 12:08:55 -0700408
Chris Wailesaa1c9622019-01-10 16:55:32 -0800409 if (setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0])) == -1) {
410 fail_fn(CREATE_ERROR("setgroups failed: %s, gids.size=%zu", strerror(errno), gids.size()));
411 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100412}
413
414// Sets the resource limits via setrlimit(2) for the values in the
415// two-dimensional array of integers that's passed in. The second dimension
Chris Wailesaa1c9622019-01-10 16:55:32 -0800416// contains a tuple of length 3: (resource, rlim_cur, rlim_max). nullptr is
Narayan Kamath973b4662014-03-31 13:41:26 +0100417// treated as an empty array.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800418static void SetRLimits(JNIEnv* env, jobjectArray managed_rlimits, fail_fn_t fail_fn) {
419 if (managed_rlimits == nullptr) {
420 return;
Narayan Kamath973b4662014-03-31 13:41:26 +0100421 }
422
423 rlimit rlim;
424 memset(&rlim, 0, sizeof(rlim));
425
Chris Wailesaa1c9622019-01-10 16:55:32 -0800426 for (int i = 0; i < env->GetArrayLength(managed_rlimits); ++i) {
427 ScopedLocalRef<jobject>
428 managed_rlimit_object(env, env->GetObjectArrayElement(managed_rlimits, i));
429 ScopedIntArrayRO rlimit_handle(env, reinterpret_cast<jintArray>(managed_rlimit_object.get()));
430
431 if (rlimit_handle.size() != 3) {
432 fail_fn(CREATE_ERROR("rlimits array must have a second dimension of size 3"));
Narayan Kamath973b4662014-03-31 13:41:26 +0100433 }
434
Chris Wailesaa1c9622019-01-10 16:55:32 -0800435 rlim.rlim_cur = rlimit_handle[1];
436 rlim.rlim_max = rlimit_handle[2];
Narayan Kamath973b4662014-03-31 13:41:26 +0100437
Chris Wailesaa1c9622019-01-10 16:55:32 -0800438 if (setrlimit(rlimit_handle[0], &rlim) == -1) {
439 fail_fn(CREATE_ERROR("setrlimit(%d, {%ld, %ld}) failed",
440 rlimit_handle[0], rlim.rlim_cur, rlim.rlim_max));
Narayan Kamath973b4662014-03-31 13:41:26 +0100441 }
442 }
443}
444
Orion Hodson8d005a62018-12-05 12:28:53 +0000445static void EnableDebugger() {
446 // To let a non-privileged gdbserver attach to this
447 // process, we must set our dumpable flag.
448 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
449 ALOGE("prctl(PR_SET_DUMPABLE) failed");
450 }
451
452 // A non-privileged native debugger should be able to attach to the debuggable app, even if Yama
453 // is enabled (see kernel/Documentation/security/Yama.txt).
454 if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) {
455 // if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this
456 // case since it's expected behaviour.
457 if (errno != EINVAL) {
458 ALOGE("prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed");
459 }
460 }
461
Orion Hodson2b71ad02018-12-07 16:44:33 +0000462 // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
463 if (!GetBoolProperty("persist.zygote.core_dump", false)) {
464 // Set the soft limit on core dump size to 0 without changing the hard limit.
465 rlimit rl;
466 if (getrlimit(RLIMIT_CORE, &rl) == -1) {
467 ALOGE("getrlimit(RLIMIT_CORE) failed");
468 } else {
469 rl.rlim_cur = 0;
470 if (setrlimit(RLIMIT_CORE, &rl) == -1) {
471 ALOGE("setrlimit(RLIMIT_CORE) failed");
472 }
Orion Hodson8d005a62018-12-05 12:28:53 +0000473 }
474 }
475}
476
Narayan Kamath973b4662014-03-31 13:41:26 +0100477// The debug malloc library needs to know whether it's the zygote or a child.
478extern "C" int gMallocLeakZygoteChild;
479
Christopher Ferris76de39e2017-06-20 16:13:40 -0700480static void PreApplicationInit() {
481 // The child process sets this to indicate it's not the zygote.
482 gMallocLeakZygoteChild = 1;
483
484 // Set the jemalloc decay time to 1.
485 mallopt(M_DECAY_TIME, 1);
486}
487
Martijn Coenen86f08a52019-01-03 16:23:01 +0100488static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800489 if (!g_is_security_enforced) {
490 ALOGI("seccomp disabled by setenforce 0");
491 return;
492 }
493
494 // Apply system or app filter based on uid.
Victor Hsiehfa046a12018-03-28 16:26:28 -0700495 if (uid >= AID_APP_START) {
Martijn Coenen86f08a52019-01-03 16:23:01 +0100496 if (is_child_zygote) {
Martijn Coenen6ef16802019-01-18 16:40:01 +0100497 set_app_zygote_seccomp_filter();
Martijn Coenen86f08a52019-01-03 16:23:01 +0100498 } else {
499 set_app_seccomp_filter();
500 }
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800501 } else {
502 set_system_seccomp_filter();
503 }
504}
505
Chris Wailesaa1c9622019-01-10 16:55:32 -0800506static void EnableKeepCapabilities(fail_fn_t fail_fn) {
507 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
508 fail_fn(CREATE_ERROR("prctl(PR_SET_KEEPCAPS) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100509 }
510}
511
Chris Wailesaa1c9622019-01-10 16:55:32 -0800512static void DropCapabilitiesBoundingSet(fail_fn_t fail_fn) {
513 for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {;
514 if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0) == -1) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100515 if (errno == EINVAL) {
516 ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
517 "your kernel is compiled with file capabilities support");
518 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800519 fail_fn(CREATE_ERROR("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100520 }
521 }
522 }
523}
524
Chris Wailesaa1c9622019-01-10 16:55:32 -0800525static void SetInheritable(uint64_t inheritable, fail_fn_t fail_fn) {
Josh Gao45dab782017-02-01 14:56:09 -0800526 __user_cap_header_struct capheader;
527 memset(&capheader, 0, sizeof(capheader));
528 capheader.version = _LINUX_CAPABILITY_VERSION_3;
529 capheader.pid = 0;
530
531 __user_cap_data_struct capdata[2];
532 if (capget(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800533 fail_fn(CREATE_ERROR("capget failed: %s", strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800534 }
535
536 capdata[0].inheritable = inheritable;
537 capdata[1].inheritable = inheritable >> 32;
538
539 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800540 fail_fn(CREATE_ERROR("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno)));
Josh Gao45dab782017-02-01 14:56:09 -0800541 }
542}
543
Chris Wailesaa1c9622019-01-10 16:55:32 -0800544static void SetCapabilities(uint64_t permitted, uint64_t effective, uint64_t inheritable,
545 fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100546 __user_cap_header_struct capheader;
547 memset(&capheader, 0, sizeof(capheader));
548 capheader.version = _LINUX_CAPABILITY_VERSION_3;
549 capheader.pid = 0;
550
551 __user_cap_data_struct capdata[2];
552 memset(&capdata, 0, sizeof(capdata));
553 capdata[0].effective = effective;
554 capdata[1].effective = effective >> 32;
555 capdata[0].permitted = permitted;
556 capdata[1].permitted = permitted >> 32;
Josh Gao45dab782017-02-01 14:56:09 -0800557 capdata[0].inheritable = inheritable;
558 capdata[1].inheritable = inheritable >> 32;
Narayan Kamath973b4662014-03-31 13:41:26 +0100559
560 if (capset(&capheader, &capdata[0]) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800561 fail_fn(CREATE_ERROR("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") "
562 "failed: %s", permitted, effective, inheritable, strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100563 }
564}
565
Chris Wailesaa1c9622019-01-10 16:55:32 -0800566static void SetSchedulerPolicy(fail_fn_t fail_fn) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100567 errno = -set_sched_policy(0, SP_DEFAULT);
568 if (errno != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800569 fail_fn(CREATE_ERROR("set_sched_policy(0, SP_DEFAULT) failed: %s", strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100570 }
571}
572
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700573static int UnmountTree(const char* path) {
574 size_t path_len = strlen(path);
575
576 FILE* fp = setmntent("/proc/mounts", "r");
Chris Wailesaa1c9622019-01-10 16:55:32 -0800577 if (fp == nullptr) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700578 ALOGE("Error opening /proc/mounts: %s", strerror(errno));
579 return -errno;
580 }
581
582 // Some volumes can be stacked on each other, so force unmount in
583 // reverse order to give us the best chance of success.
584 std::list<std::string> toUnmount;
585 mntent* mentry;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800586 while ((mentry = getmntent(fp)) != nullptr) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700587 if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
588 toUnmount.push_front(std::string(mentry->mnt_dir));
589 }
590 }
591 endmntent(fp);
592
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800593 for (const auto& path : toUnmount) {
Jeff Sharkeyfaf3f692015-06-30 15:56:33 -0700594 if (umount2(path.c_str(), MNT_DETACH)) {
595 ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
596 }
597 }
598 return 0;
599}
600
Chris Wailesaa1c9622019-01-10 16:55:32 -0800601static void CreatePkgSandbox(uid_t uid, const std::string& package_name, fail_fn_t fail_fn) {
Sudheer Shanka663b1042018-07-30 17:34:21 -0700602 // Create /mnt/user/0/package/<package-name>
603 userid_t user_id = multiuser_get_user_id(uid);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700604 std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
Sudheer Shanka8d8223e2018-08-03 18:18:21 -0700605 if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800606 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700607 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800608
Sudheer Shanka663b1042018-07-30 17:34:21 -0700609 StringAppendF(&pkg_sandbox_dir, "/package");
610 if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800611 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700612 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800613
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700614 StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str());
Sudheer Shanka663b1042018-07-30 17:34:21 -0700615 if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800616 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700617 }
Sudheer Shanka663b1042018-07-30 17:34:21 -0700618}
619
Chris Wailesaa1c9622019-01-10 16:55:32 -0800620static void BindMount(const std::string& sourceDir, const std::string& targetDir,
621 fail_fn_t fail_fn) {
622 if (TEMP_FAILURE_RETRY(mount(sourceDir.c_str(), targetDir.c_str(), nullptr,
623 MS_BIND | MS_REC, nullptr)) == -1) {
624 fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
625 sourceDir.c_str(), targetDir.c_str(), strerror(errno)));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800626 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800627
628 if (TEMP_FAILURE_RETRY(mount(nullptr, targetDir.c_str(), nullptr,
629 MS_SLAVE | MS_REC, nullptr)) == -1) {
630 fail_fn(CREATE_ERROR("Failed to set MS_SLAVE for %s", targetDir.c_str()));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800631 }
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800632}
633
Chris Wailesaa1c9622019-01-10 16:55:32 -0800634static void MountPkgSpecificDir(const std::string& mntSourceRoot,
635 const std::string& mntTargetRoot,
636 const std::string& packageName,
637 const char* dirName,
638 fail_fn_t fail_fn) {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700639 std::string mntSourceDir = StringPrintf("%s/Android/%s/%s",
640 mntSourceRoot.c_str(), dirName, packageName.c_str());
641 std::string mntTargetDir = StringPrintf("%s/Android/%s/%s",
642 mntTargetRoot.c_str(), dirName, packageName.c_str());
Chris Wailesaa1c9622019-01-10 16:55:32 -0800643
644 BindMount(mntSourceDir, mntTargetDir, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700645}
646
Chris Wailesaa1c9622019-01-10 16:55:32 -0800647static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
648 const std::vector<std::string>& volumeLabels,
649 bool mountAllObbs, userid_t userId, fail_fn_t fail_fn) {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700650 for (auto& label : volumeLabels) {
651 std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
652 std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
653 if (label == "emulated") {
654 StringAppendF(&mntSource, "/%d", userId);
655 StringAppendF(&mntTarget, "/%d", userId);
656 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800657
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700658 for (auto& package : packageNames) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800659 MountPkgSpecificDir(mntSource, mntTarget, package, "data", fail_fn);
660 MountPkgSpecificDir(mntSource, mntTarget, package, "media", fail_fn);
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800661 if (!mountAllObbs) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800662 MountPkgSpecificDir(mntSource, mntTarget, package, "obb", fail_fn);
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800663 }
664 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800665
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800666 if (mountAllObbs) {
667 StringAppendF(&mntSource, "/Android/obb");
668 StringAppendF(&mntTarget, "/Android/obb");
Chris Wailesaa1c9622019-01-10 16:55:32 -0800669 BindMount(mntSource, mntTarget, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700670 }
671 }
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700672}
673
Narayan Kamath973b4662014-03-31 13:41:26 +0100674// Create a private mount namespace and bind mount appropriate emulated
675// storage for the given user.
Chris Wailesaa1c9622019-01-10 16:55:32 -0800676static void MountEmulatedStorage(uid_t uid, jint mount_mode,
677 bool force_mount_namespace, const std::string& package_name,
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700678 const std::vector<std::string>& packages_for_uid,
Chris Wailesaa1c9622019-01-10 16:55:32 -0800679 const std::vector<std::string>& visible_vol_ids, fail_fn_t fail_fn) {
Jeff Sharkey9527b222015-06-24 15:24:48 -0700680 // See storage config details at http://source.android.com/tech/storage/
681
Jeff Sharkey9527b222015-06-24 15:24:48 -0700682 String8 storageSource;
683 if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700684 storageSource = "/mnt/runtime/default";
Jeff Sharkey9527b222015-06-24 15:24:48 -0700685 } else if (mount_mode == MOUNT_EXTERNAL_READ) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700686 storageSource = "/mnt/runtime/read";
Jeff Sharkey9527b222015-06-24 15:24:48 -0700687 } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
Jeff Sharkey928e1ec2015-08-06 11:40:21 -0700688 storageSource = "/mnt/runtime/write";
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800689 } else if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
Jeff Sharkey9527b222015-06-24 15:24:48 -0700690 // Sane default of no storage visible
Chris Wailesaa1c9622019-01-10 16:55:32 -0800691 return;
Jeff Sharkey9527b222015-06-24 15:24:48 -0700692 }
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400693
694 // Create a second private mount namespace for our process
695 if (unshare(CLONE_NEWNS) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800696 fail_fn(CREATE_ERROR("Failed to unshare(): %s", strerror(errno)));
Robert Sesek8a3a6ff2016-10-31 11:25:10 -0400697 }
698
Robert Sesek06f39302017-03-20 17:30:05 -0400699 // Handle force_mount_namespace with MOUNT_EXTERNAL_NONE.
700 if (mount_mode == MOUNT_EXTERNAL_NONE) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800701 return;
Robert Sesek06f39302017-03-20 17:30:05 -0400702 }
703
Sudheer Shankaa3801582019-01-17 17:19:11 -0800704 if (GetBoolProperty(kIsolatedStorageSnapshot, GetBoolProperty(kIsolatedStorage, false))) {
Sudheer Shanka0b6da532019-01-09 12:06:51 -0800705 if (mount_mode == MOUNT_EXTERNAL_FULL || mount_mode == MOUNT_EXTERNAL_LEGACY) {
706 storageSource = (mount_mode == MOUNT_EXTERNAL_FULL)
707 ? "/mnt/runtime/full" : "/mnt/runtime/write";
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700708 if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800709 NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
710 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
711 storageSource.string(),
712 strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700713 }
Jeff Sharkey9527b222015-06-24 15:24:48 -0700714
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700715 // Mount user-specific symlink helper into place
716 userid_t user_id = multiuser_get_user_id(uid);
717 const String8 userSource(String8::format("/mnt/user/%d", user_id));
718 if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800719 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s (%s)",
720 userSource.string(), strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700721 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800722
723 if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self", nullptr, MS_BIND,
724 nullptr)) == -1) {
725 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
726 userSource.string(),
727 strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700728 }
729 } else {
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700730 if (package_name.empty()) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800731 return;
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700732 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800733
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700734 userid_t user_id = multiuser_get_user_id(uid);
Chris Wailesaa1c9622019-01-10 16:55:32 -0800735 std::string pkgSandboxDir =
736 StringPrintf("/mnt/user/%d/package/%s", user_id, package_name.c_str());
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700737 struct stat sb;
738 bool sandboxAlreadyCreated = true;
739 if (TEMP_FAILURE_RETRY(lstat(pkgSandboxDir.c_str(), &sb)) == -1) {
740 if (errno == ENOENT) {
741 ALOGD("Sandbox not yet created for %s", pkgSandboxDir.c_str());
742 sandboxAlreadyCreated = false;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800743 CreatePkgSandbox(uid, package_name, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700744 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800745 fail_fn(CREATE_ERROR("Failed to lstat %s: %s",
746 pkgSandboxDir.c_str(), strerror(errno)));
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700747 }
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700748 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800749
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700750 if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800751 nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
752 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
753 pkgSandboxDir.c_str(), strerror(errno)));
Sudheer Shanka98cb3f02018-08-17 16:10:29 -0700754 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800755
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800756 if (access("/storage/obb_mount", F_OK) == 0) {
757 if (mount_mode != MOUNT_EXTERNAL_INSTALLER) {
758 remove("/storage/obb_mount");
759 }
760 } else {
761 if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800762 int fd =
763 TEMP_FAILURE_RETRY(open("/storage/obb_mount", O_RDWR | O_CREAT, 0660));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800764 if (fd == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800765 fail_fn(CREATE_ERROR("Couldn't create /storage/obb_mount: %s",
766 strerror(errno)));
Sudheer Shanka3a0df3b2018-12-12 12:43:43 -0800767 }
768 close(fd);
769 }
770 }
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700771 // If the sandbox was already created by vold, only then set up the bind mounts for
772 // pkg specific directories. Otherwise, leave as is and bind mounts will be taken
773 // care of by vold later.
774 if (sandboxAlreadyCreated) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800775 PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
776 mount_mode == MOUNT_EXTERNAL_INSTALLER, user_id, fail_fn);
Sudheer Shanka3f0645b2018-09-18 13:07:59 -0700777 }
Sudheer Shanka663b1042018-07-30 17:34:21 -0700778 }
779 } else {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800780 if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage", nullptr,
781 MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
782 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
783 storageSource.string(),
784 strerror(errno)));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700785 }
786
787 // Mount user-specific symlink helper into place
788 userid_t user_id = multiuser_get_user_id(uid);
789 const String8 userSource(String8::format("/mnt/user/%d", user_id));
790 if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800791 fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s",
792 userSource.string()));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700793 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800794
Sudheer Shanka663b1042018-07-30 17:34:21 -0700795 if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
Chris Wailesaa1c9622019-01-10 16:55:32 -0800796 nullptr, MS_BIND, nullptr)) == -1) {
797 fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
798 userSource.string(), strerror(errno)));
Sudheer Shanka663b1042018-07-30 17:34:21 -0700799 }
Jeff Sharkey9527b222015-06-24 15:24:48 -0700800 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100801}
802
Narayan Kamath973b4662014-03-31 13:41:26 +0100803static bool NeedsNoRandomizeWorkaround() {
804#if !defined(__arm__)
805 return false;
806#else
807 int major;
808 int minor;
809 struct utsname uts;
810 if (uname(&uts) == -1) {
811 return false;
812 }
813
814 if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
815 return false;
816 }
817
818 // Kernels before 3.4.* need the workaround.
819 return (major < 3) || ((major == 3) && (minor < 4));
820#endif
821}
Narayan Kamath973b4662014-03-31 13:41:26 +0100822
823// Utility to close down the Zygote socket file descriptors while
824// the child is still running as root with Zygote's privileges. Each
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800825// descriptor (if any) is closed via dup3(), replacing it with a valid
Narayan Kamath973b4662014-03-31 13:41:26 +0100826// (open) descriptor to /dev/null.
827
Chris Wailesaa1c9622019-01-10 16:55:32 -0800828static void DetachDescriptors(JNIEnv* env,
829 const std::vector<int>& fds_to_close,
830 fail_fn_t fail_fn) {
831
832 if (fds_to_close.size() > 0) {
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800833 android::base::unique_fd devnull_fd(open("/dev/null", O_RDWR | O_CLOEXEC));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800834 if (devnull_fd == -1) {
835 fail_fn(std::string("Failed to open /dev/null: ").append(strerror(errno)));
Narayan Kamath973b4662014-03-31 13:41:26 +0100836 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800837
838 for (int fd : fds_to_close) {
839 ALOGV("Switching descriptor %d to /dev/null", fd);
Nick Kralevich5d5bf1f2019-01-25 10:24:42 -0800840 if (dup3(devnull_fd, fd, O_CLOEXEC) == -1) {
841 fail_fn(StringPrintf("Failed dup3() on descriptor %d: %s", fd, strerror(errno)));
Chris Wailesaa1c9622019-01-10 16:55:32 -0800842 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100843 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100844 }
845}
846
Chris Wailesaa1c9622019-01-10 16:55:32 -0800847void SetThreadName(const std::string& thread_name) {
Narayan Kamath973b4662014-03-31 13:41:26 +0100848 bool hasAt = false;
849 bool hasDot = false;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800850
851 for (const char str_el : thread_name) {
852 if (str_el == '.') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100853 hasDot = true;
Chris Wailesaa1c9622019-01-10 16:55:32 -0800854 } else if (str_el == '@') {
Narayan Kamath973b4662014-03-31 13:41:26 +0100855 hasAt = true;
856 }
Narayan Kamath973b4662014-03-31 13:41:26 +0100857 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800858
859 const char* name_start_ptr = thread_name.c_str();
860 if (thread_name.length() >= MAX_NAME_LENGTH && !hasAt && hasDot) {
861 name_start_ptr += thread_name.length() - MAX_NAME_LENGTH;
Narayan Kamath973b4662014-03-31 13:41:26 +0100862 }
Chris Wailesaa1c9622019-01-10 16:55:32 -0800863
Narayan Kamath973b4662014-03-31 13:41:26 +0100864 // pthread_setname_np fails rather than truncating long strings.
865 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
Chris Wailesaa1c9622019-01-10 16:55:32 -0800866 strlcpy(buf, name_start_ptr, sizeof(buf) - 1);
Narayan Kamath973b4662014-03-31 13:41:26 +0100867 errno = pthread_setname_np(pthread_self(), buf);
868 if (errno != 0) {
Elliott Hughes960e8312014-09-30 08:49:01 -0700869 ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
Narayan Kamath973b4662014-03-31 13:41:26 +0100870 }
Andreas Gampe041483a2018-03-05 13:00:42 -0800871 // Update base::logging default tag.
872 android::base::SetDefaultTag(buf);
Narayan Kamath973b4662014-03-31 13:41:26 +0100873}
874
Chris Wailesaa1c9622019-01-10 16:55:32 -0800875/**
876 * A failure function used to report fatal errors to the managed runtime. This
877 * function is often curried with the process name information and then passed
878 * to called functions.
879 *
880 * @param env Managed runtime environment
881 * @param process_name A native representation of the process name
882 * @param managed_process_name A managed representation of the process name
883 * @param msg The error message to be reported
884 */
Chris Wailesaf594fc2018-11-02 11:00:07 -0700885[[noreturn]]
886static void ZygoteFailure(JNIEnv* env,
887 const char* process_name,
888 jstring managed_process_name,
889 const std::string& msg) {
890 std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr;
891 if (managed_process_name != nullptr) {
892 scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name));
893 if (scoped_managed_process_name_ptr->c_str() != nullptr) {
894 process_name = scoped_managed_process_name_ptr->c_str();
David Sehrde8d0bd2018-06-22 10:45:36 -0700895 }
896 }
897
Chris Wailesaf594fc2018-11-02 11:00:07 -0700898 const std::string& error_msg =
899 (process_name == nullptr) ? msg : StringPrintf("(%s) %s", process_name, msg.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -0700900
Chris Wailesaf594fc2018-11-02 11:00:07 -0700901 env->FatalError(error_msg.c_str());
902 __builtin_unreachable();
903}
David Sehrde8d0bd2018-06-22 10:45:36 -0700904
Chris Wailesaa1c9622019-01-10 16:55:32 -0800905/**
906 * A helper method for converting managed strings to native strings. A fatal
907 * error is generated if a problem is encountered in extracting a non-null
908 * string.
909 *
910 * @param env Managed runtime environment
911 * @param process_name A native representation of the process name
912 * @param managed_process_name A managed representation of the process name
913 * @param managed_string The managed string to extract
914 *
915 * @return An empty option if the managed string is null. A optional-wrapped
916 * string otherwise.
917 */
Chris Wailesaf594fc2018-11-02 11:00:07 -0700918static std::optional<std::string> ExtractJString(JNIEnv* env,
919 const char* process_name,
920 jstring managed_process_name,
921 jstring managed_string) {
922 if (managed_string == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -0800923 return std::nullopt;
Chris Wailesaf594fc2018-11-02 11:00:07 -0700924 } else {
925 ScopedUtfChars scoped_string_chars(env, managed_string);
926
927 if (scoped_string_chars.c_str() != nullptr) {
928 return std::optional<std::string>(scoped_string_chars.c_str());
David Sehrde8d0bd2018-06-22 10:45:36 -0700929 } else {
Chris Wailesaf594fc2018-11-02 11:00:07 -0700930 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JString.");
David Sehrde8d0bd2018-06-22 10:45:36 -0700931 }
932 }
David Sehrde8d0bd2018-06-22 10:45:36 -0700933}
934
Chris Wailesaa1c9622019-01-10 16:55:32 -0800935/**
936 * A helper method for converting managed string arrays to native vectors. A
937 * fatal error is generated if a problem is encountered in extracting a non-null array.
938 *
939 * @param env Managed runtime environment
940 * @param process_name A native representation of the process name
941 * @param managed_process_name A managed representation of the process name
942 * @param managed_array The managed integer array to extract
943 *
944 * @return An empty option if the managed array is null. A optional-wrapped
945 * vector otherwise.
946 */
947static std::optional<std::vector<int>> ExtractJIntArray(JNIEnv* env,
948 const char* process_name,
949 jstring managed_process_name,
950 jintArray managed_array) {
951 if (managed_array == nullptr) {
952 return std::nullopt;
953 } else {
954 ScopedIntArrayRO managed_array_handle(env, managed_array);
Narayan Kamath973b4662014-03-31 13:41:26 +0100955
Chris Wailesaa1c9622019-01-10 16:55:32 -0800956 if (managed_array_handle.get() != nullptr) {
957 std::vector<int> native_array;
958 native_array.reserve(managed_array_handle.size());
959
960 for (size_t array_index = 0; array_index < managed_array_handle.size(); ++array_index) {
961 native_array.push_back(managed_array_handle[array_index]);
962 }
963
964 return std::move(native_array);
965
966 } else {
967 ZygoteFailure(env, process_name, managed_process_name, "Failed to extract JIntArray.");
968 }
969 }
970}
971
972/**
973 * A helper method for converting managed string arrays to native vectors. A
974 * fatal error is generated if a problem is encountered in extracting a non-null array.
975 *
976 * @param env Managed runtime environment
977 * @param process_name A native representation of the process name
978 * @param managed_process_name A managed representation of the process name
979 * @param managed_array The managed string array to extract
980 *
981 * @return An empty option if the managed array is null. A optional-wrapped
982 * vector otherwise.
983 */
984static std::optional<std::vector<std::string>> ExtractJStringArray(JNIEnv* env,
985 const char* process_name,
986 jstring managed_process_name,
987 jobjectArray managed_array) {
988 if (managed_array == nullptr) {
989 return std::nullopt;
990 } else {
991 jsize element_count = env->GetArrayLength(managed_array);
992 std::vector<std::string> native_string_vector;
993 native_string_vector.reserve(element_count);
994
995 for (jsize array_index = 0; array_index < element_count; ++array_index) {
996 jstring managed_string = (jstring) env->GetObjectArrayElement(managed_array, array_index);
997 auto native_string = ExtractJString(env, process_name, managed_process_name, managed_string);
998
999 if (LIKELY(native_string.has_value())) {
1000 native_string_vector.emplace_back(std::move(native_string.value()));
1001 } else {
1002 ZygoteFailure(env, process_name, managed_process_name,
1003 "Null string found in managed string array.");
1004 }
1005 }
1006
1007 return std::move(native_string_vector);
1008 }
1009}
1010
1011/**
1012 * A utility function for blocking signals.
1013 *
1014 * @param signum Signal number to block
1015 * @param fail_fn Fatal error reporting function
1016 *
1017 * @see ZygoteFailure
1018 */
1019static void BlockSignal(int signum, fail_fn_t fail_fn) {
1020 sigset_t sigs;
1021 sigemptyset(&sigs);
1022 sigaddset(&sigs, signum);
1023
1024 if (sigprocmask(SIG_BLOCK, &sigs, nullptr) == -1) {
1025 fail_fn(CREATE_ERROR("Failed to block signal %s: %s", strsignal(signum), strerror(errno)));
1026 }
1027}
1028
1029
1030/**
1031 * A utility function for unblocking signals.
1032 *
1033 * @param signum Signal number to unblock
1034 * @param fail_fn Fatal error reporting function
1035 *
1036 * @see ZygoteFailure
1037 */
1038static void UnblockSignal(int signum, fail_fn_t fail_fn) {
1039 sigset_t sigs;
1040 sigemptyset(&sigs);
1041 sigaddset(&sigs, signum);
1042
1043 if (sigprocmask(SIG_UNBLOCK, &sigs, nullptr) == -1) {
1044 fail_fn(CREATE_ERROR("Failed to un-block signal %s: %s", strsignal(signum), strerror(errno)));
1045 }
1046}
1047
1048// Utility routine to fork a process from the zygote.
1049static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
1050 const std::vector<int>& fds_to_close,
1051 const std::vector<int>& fds_to_ignore) {
1052 SetSignalHandlers();
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001053
Chris Wailesaf594fc2018-11-02 11:00:07 -07001054 // Curry a failure function.
1055 auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
1056 nullptr, _1);
Andreas Gamped5758f62018-03-12 12:08:55 -07001057
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001058 // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
1059 // log, which would result in the logging FDs we close being reopened.
1060 // This would cause failures because the FDs are not whitelisted.
1061 //
1062 // Note that the zygote process is single threaded at this point.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001063 BlockSignal(SIGCHLD, fail_fn);
Narayan Kamathdfcc79e2016-11-07 16:22:48 +00001064
Narayan Kamath3764a262016-08-30 15:36:19 +01001065 // Close any logging related FDs before we start evaluating the list of
1066 // file descriptors.
1067 __android_log_close();
Howard Ro27330412018-10-02 12:08:28 -07001068 stats_log_close();
Narayan Kamath3764a262016-08-30 15:36:19 +01001069
Chris Wailesaf594fc2018-11-02 11:00:07 -07001070 // If this is the first fork for this zygote, create the open FD table. If
1071 // it isn't, we just need to check whether the list of open files has changed
1072 // (and it shouldn't in the normal case).
Chris Wailesaf594fc2018-11-02 11:00:07 -07001073 if (gOpenFdTable == nullptr) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001074 gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
1075 } else {
1076 gOpenFdTable->Restat(fds_to_ignore, fail_fn);
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001077 }
1078
Josh Gaod7951102018-06-26 16:05:12 -07001079 android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
1080
Narayan Kamath973b4662014-03-31 13:41:26 +01001081 pid_t pid = fork();
1082
1083 if (pid == 0) {
David Sehrde8d0bd2018-06-22 10:45:36 -07001084 // The child process.
Christopher Ferris76de39e2017-06-20 16:13:40 -07001085 PreApplicationInit();
Christopher Ferrisab16dd12017-05-15 16:50:29 -07001086
Narayan Kamath973b4662014-03-31 13:41:26 +01001087 // Clean up any descriptors which must be closed immediately
Chris Wailesaa1c9622019-01-10 16:55:32 -08001088 DetachDescriptors(env, fds_to_close, fail_fn);
Narayan Kamath973b4662014-03-31 13:41:26 +01001089
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001090 // Re-open all remaining open file descriptors so that they aren't shared
1091 // with the zygote across a fork.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001092 gOpenFdTable->ReopenOrDetach(fail_fn);
Josh Gaod7951102018-06-26 16:05:12 -07001093
1094 // Turn fdsan back on.
1095 android_fdsan_set_error_level(fdsan_error_level);
David Sehrde8d0bd2018-06-22 10:45:36 -07001096 }
Narayan Kamathc5f27a72016-08-19 13:45:24 +01001097
David Sehrde8d0bd2018-06-22 10:45:36 -07001098 // We blocked SIGCHLD prior to a fork, we unblock it here.
Chris Wailesaa1c9622019-01-10 16:55:32 -08001099 UnblockSignal(SIGCHLD, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001100
Narayan Kamath973b4662014-03-31 13:41:26 +01001101 return pid;
1102}
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001103
Chris Wailesaf594fc2018-11-02 11:00:07 -07001104// Utility routine to specialize a zygote child process.
1105static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
1106 jint runtime_flags, jobjectArray rlimits,
1107 jlong permitted_capabilities, jlong effective_capabilities,
1108 jint mount_external, jstring managed_se_info,
1109 jstring managed_nice_name, bool is_system_server,
1110 bool is_child_zygote, jstring managed_instruction_set,
1111 jstring managed_app_data_dir, jstring managed_package_name,
1112 jobjectArray managed_pacakges_for_uid,
1113 jobjectArray managed_visible_vol_ids) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001114 const char* process_name = is_system_server ? "system_server" : "zygote";
1115 auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
1116 auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001117
1118 auto se_info = extract_fn(managed_se_info);
1119 auto nice_name = extract_fn(managed_nice_name);
1120 auto instruction_set = extract_fn(managed_instruction_set);
1121 auto app_data_dir = extract_fn(managed_app_data_dir);
1122 auto package_name = extract_fn(managed_package_name);
1123
Chris Wailesaf594fc2018-11-02 11:00:07 -07001124 // Keep capabilities across UID change, unless we're staying root.
1125 if (uid != 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001126 EnableKeepCapabilities(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001127 }
1128
Chris Wailesaa1c9622019-01-10 16:55:32 -08001129 SetInheritable(permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001130
Chris Wailesaa1c9622019-01-10 16:55:32 -08001131 DropCapabilitiesBoundingSet(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001132
1133 bool use_native_bridge = !is_system_server &&
1134 instruction_set.has_value() &&
1135 android::NativeBridgeAvailable() &&
1136 android::NeedsNativeBridge(instruction_set.value().c_str());
1137
1138 if (use_native_bridge && !app_data_dir.has_value()) {
1139 // The app_data_dir variable should never be empty if we need to use a
1140 // native bridge. In general, app_data_dir will never be empty for normal
1141 // applications. It can only happen in special cases (for isolated
1142 // processes which are not associated with any app). These are launched by
1143 // the framework and should not be emulated anyway.
1144 use_native_bridge = false;
1145 ALOGW("Native bridge will not be used because managed_app_data_dir == nullptr.");
1146 }
1147
1148 if (!package_name.has_value()) {
1149 if (is_system_server) {
1150 package_name.emplace("android");
1151 } else {
1152 package_name.emplace("");
1153 }
1154 }
1155
Chris Wailesaa1c9622019-01-10 16:55:32 -08001156 std::vector<std::string> packages_for_uid =
1157 ExtractJStringArray(env, process_name, managed_nice_name, managed_pacakges_for_uid).
1158 value_or(std::vector<std::string>());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001159
Chris Wailesaa1c9622019-01-10 16:55:32 -08001160 std::vector<std::string> visible_vol_ids =
1161 ExtractJStringArray(env, process_name, managed_nice_name, managed_visible_vol_ids).
1162 value_or(std::vector<std::string>());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001163
Chris Wailesaa1c9622019-01-10 16:55:32 -08001164 MountEmulatedStorage(uid, mount_external, use_native_bridge, package_name.value(),
1165 packages_for_uid, visible_vol_ids, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001166
1167 // If this zygote isn't root, it won't be able to create a process group,
1168 // since the directory is owned by root.
1169 if (!is_system_server && getuid() == 0) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001170 const int rc = createProcessGroup(uid, getpid());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001171 if (rc == -EROFS) {
1172 ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
1173 } else if (rc != 0) {
1174 ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
1175 }
1176 }
1177
Chris Wailesaa1c9622019-01-10 16:55:32 -08001178 SetGids(env, gids, fail_fn);
1179 SetRLimits(env, rlimits, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001180
1181 if (use_native_bridge) {
1182 // Due to the logic behind use_native_bridge we know that both app_data_dir
1183 // and instruction_set contain values.
1184 android::PreInitializeNativeBridge(app_data_dir.value().c_str(),
1185 instruction_set.value().c_str());
1186 }
1187
1188 if (setresgid(gid, gid, gid) == -1) {
1189 fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
1190 }
1191
1192 // Must be called when the new process still has CAP_SYS_ADMIN, in this case,
1193 // before changing uid from 0, which clears capabilities. The other
1194 // alternative is to call prctl(PR_SET_NO_NEW_PRIVS, 1) afterward, but that
1195 // breaks SELinux domain transition (see b/71859146). As the result,
1196 // privileged syscalls used below still need to be accessible in app process.
Martijn Coenen86f08a52019-01-03 16:23:01 +01001197 SetUpSeccompFilter(uid, is_child_zygote);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001198
1199 if (setresuid(uid, uid, uid) == -1) {
1200 fail_fn(CREATE_ERROR("setresuid(%d) failed: %s", uid, strerror(errno)));
1201 }
1202
1203 // The "dumpable" flag of a process, which controls core dump generation, is
1204 // overwritten by the value in /proc/sys/fs/suid_dumpable when the effective
1205 // user or group ID changes. See proc(5) for possible values. In most cases,
1206 // the value is 0, so core dumps are disabled for zygote children. However,
1207 // when running in a Chrome OS container, the value is already set to 2,
1208 // which allows the external crash reporter to collect all core dumps. Since
1209 // only system crashes are interested, core dump is disabled for app
1210 // processes. This also ensures compliance with CTS.
1211 int dumpable = prctl(PR_GET_DUMPABLE);
1212 if (dumpable == -1) {
1213 ALOGE("prctl(PR_GET_DUMPABLE) failed: %s", strerror(errno));
1214 RuntimeAbort(env, __LINE__, "prctl(PR_GET_DUMPABLE) failed");
1215 }
1216
1217 if (dumpable == 2 && uid >= AID_APP) {
1218 if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1) {
1219 ALOGE("prctl(PR_SET_DUMPABLE, 0) failed: %s", strerror(errno));
1220 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 0) failed");
1221 }
1222 }
1223
Orion Hodson8d005a62018-12-05 12:28:53 +00001224 // Set process properties to enable debugging if required.
1225 if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_JDWP) != 0) {
1226 EnableDebugger();
1227 }
Yabin Cui4d8546d2019-01-29 16:29:20 -08001228 if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) {
1229 // simpleperf needs the process to be dumpable to profile it.
1230 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
1231 ALOGE("prctl(PR_SET_DUMPABLE) failed: %s", strerror(errno));
1232 RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 1) failed");
1233 }
1234 }
Orion Hodson8d005a62018-12-05 12:28:53 +00001235
Chris Wailesaf594fc2018-11-02 11:00:07 -07001236 if (NeedsNoRandomizeWorkaround()) {
1237 // Work around ARM kernel ASLR lossage (http://b/5817320).
1238 int old_personality = personality(0xffffffff);
1239 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
1240 if (new_personality == -1) {
1241 ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
1242 }
1243 }
1244
Chris Wailesaa1c9622019-01-10 16:55:32 -08001245 SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001246
Chris Wailesaa1c9622019-01-10 16:55:32 -08001247 SetSchedulerPolicy(fail_fn);
Chris Wailesaf594fc2018-11-02 11:00:07 -07001248
1249 const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;
1250 const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;
1251
1252 if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
1253 fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
1254 uid, is_system_server, se_info_ptr, nice_name_ptr));
1255 }
1256
1257 // Make it easier to debug audit logs by setting the main thread's name to the
1258 // nice name rather than "app_process".
1259 if (nice_name.has_value()) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001260 SetThreadName(nice_name.value());
Chris Wailesaf594fc2018-11-02 11:00:07 -07001261 } else if (is_system_server) {
1262 SetThreadName("system_server");
1263 }
1264
1265 // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
1266 UnsetChldSignalHandler();
1267
1268 if (is_system_server) {
1269 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
1270 if (env->ExceptionCheck()) {
1271 fail_fn("Error calling post fork system server hooks.");
1272 }
Chris Wailesaa1c9622019-01-10 16:55:32 -08001273
Chris Wailesaf594fc2018-11-02 11:00:07 -07001274 // TODO(oth): Remove hardcoded label here (b/117874058).
1275 static const char* kSystemServerLabel = "u:r:system_server:s0";
1276 if (selinux_android_setcon(kSystemServerLabel) != 0) {
1277 fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));
1278 }
1279 }
1280
1281 env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
1282 is_system_server, is_child_zygote, managed_instruction_set);
1283
1284 if (env->ExceptionCheck()) {
1285 fail_fn("Error calling post fork hooks.");
1286 }
1287}
1288
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001289static uint64_t GetEffectiveCapabilityMask(JNIEnv* env) {
1290 __user_cap_header_struct capheader;
1291 memset(&capheader, 0, sizeof(capheader));
1292 capheader.version = _LINUX_CAPABILITY_VERSION_3;
1293 capheader.pid = 0;
1294
1295 __user_cap_data_struct capdata[2];
1296 if (capget(&capheader, &capdata[0]) == -1) {
1297 ALOGE("capget failed: %s", strerror(errno));
1298 RuntimeAbort(env, __LINE__, "capget failed");
1299 }
1300
Chris Wailesaf594fc2018-11-02 11:00:07 -07001301 return capdata[0].effective | (static_cast<uint64_t>(capdata[1].effective) << 32);
1302}
1303
1304static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gids,
1305 bool is_child_zygote) {
1306 jlong capabilities = 0;
1307
1308 /*
1309 * Grant the following capabilities to the Bluetooth user:
1310 * - CAP_WAKE_ALARM
1311 * - CAP_NET_RAW
1312 * - CAP_NET_BIND_SERVICE (for DHCP client functionality)
1313 * - CAP_SYS_NICE (for setting RT priority for audio-related threads)
1314 */
1315
1316 if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
1317 capabilities |= (1LL << CAP_WAKE_ALARM);
1318 capabilities |= (1LL << CAP_NET_RAW);
1319 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1320 capabilities |= (1LL << CAP_SYS_NICE);
1321 }
1322
Remi NGUYEN VANc094a542018-12-07 16:52:24 +09001323 if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
1324 capabilities |= (1LL << CAP_NET_ADMIN);
1325 capabilities |= (1LL << CAP_NET_BROADCAST);
1326 capabilities |= (1LL << CAP_NET_BIND_SERVICE);
1327 capabilities |= (1LL << CAP_NET_RAW);
1328 }
1329
Chris Wailesaf594fc2018-11-02 11:00:07 -07001330 /*
1331 * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
1332 */
1333
1334 bool gid_wakelock_found = false;
1335 if (gid == AID_WAKELOCK) {
1336 gid_wakelock_found = true;
1337 } else if (gids != nullptr) {
1338 jsize gids_num = env->GetArrayLength(gids);
1339 ScopedIntArrayRO native_gid_proxy(env, gids);
1340
1341 if (native_gid_proxy.get() == nullptr) {
1342 RuntimeAbort(env, __LINE__, "Bad gids array");
1343 }
1344
1345 for (int gid_index = gids_num; --gids_num >= 0;) {
1346 if (native_gid_proxy[gid_index] == AID_WAKELOCK) {
1347 gid_wakelock_found = true;
1348 break;
1349 }
1350 }
1351 }
1352
1353 if (gid_wakelock_found) {
1354 capabilities |= (1LL << CAP_BLOCK_SUSPEND);
1355 }
1356
1357 /*
1358 * Grant child Zygote processes the following capabilities:
1359 * - CAP_SETUID (change UID of child processes)
1360 * - CAP_SETGID (change GID of child processes)
1361 * - CAP_SETPCAP (change capabilities of child processes)
1362 */
1363
1364 if (is_child_zygote) {
1365 capabilities |= (1LL << CAP_SETUID);
1366 capabilities |= (1LL << CAP_SETGID);
1367 capabilities |= (1LL << CAP_SETPCAP);
1368 }
1369
1370 /*
1371 * Containers run without some capabilities, so drop any caps that are not
1372 * available.
1373 */
1374
1375 return capabilities & GetEffectiveCapabilityMask(env);
Luis Hector Chavez72042c92017-07-12 10:03:30 -07001376}
Chris Wailesaa1c9622019-01-10 16:55:32 -08001377
1378/**
1379 * Adds the given information about a newly created blastula to the Zygote's
1380 * blastula table.
1381 *
1382 * @param blastula_pid Process ID of the newly created blastula
1383 * @param read_pipe_fd File descriptor for the read end of the blastula
1384 * reporting pipe. Used in the ZygoteServer poll loop to track blastula
1385 * specialization.
1386 */
1387static void AddBlastulaTableEntry(pid_t blastula_pid, int read_pipe_fd) {
1388 static int sBlastulaTableInsertIndex = 0;
1389
1390 int search_index = sBlastulaTableInsertIndex;
1391
1392 do {
1393 if (gBlastulaTable[search_index].SetIfInvalid(blastula_pid, read_pipe_fd)) {
1394 // Start our next search right after where we finished this one.
1395 sBlastulaTableInsertIndex = (search_index + 1) % gBlastulaTable.size();
1396
1397 return;
1398 }
1399
1400 search_index = (search_index + 1) % gBlastulaTable.size();
1401 } while (search_index != sBlastulaTableInsertIndex);
1402
1403 // Much like money in the banana stand, there should always be an entry
1404 // in the blastula table.
1405 __builtin_unreachable();
1406}
1407
1408/**
1409 * Invalidates the entry in the BlastulaTable corresponding to the provided
1410 * process ID if it is present. If an entry was removed the blastula pool
1411 * count is decremented.
1412 *
1413 * @param blastula_pid Process ID of the blastula entry to invalidate
1414 * @return True if an entry was invalidated; false otherwise
1415 */
1416static bool RemoveBlastulaTableEntry(pid_t blastula_pid) {
1417 for (BlastulaTableEntry& entry : gBlastulaTable) {
1418 if (entry.ClearForPID(blastula_pid)) {
1419 --gBlastulaPoolCount;
1420 return true;
1421 }
1422 }
1423
1424 return false;
1425}
1426
1427/**
1428 * @return A vector of the read pipe FDs for each of the active blastulas.
1429 */
1430std::vector<int> MakeBlastulaPipeReadFDVector() {
1431 std::vector<int> fd_vec;
1432 fd_vec.reserve(gBlastulaTable.size());
1433
1434 for (BlastulaTableEntry& entry : gBlastulaTable) {
1435 auto entry_values = entry.GetValues();
1436
1437 if (entry_values.has_value()) {
1438 fd_vec.push_back(entry_values.value().read_pipe_fd);
1439 }
1440 }
1441
1442 return fd_vec;
1443}
1444
Narayan Kamath973b4662014-03-31 13:41:26 +01001445} // anonymous namespace
1446
1447namespace android {
1448
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001449static void com_android_internal_os_Zygote_nativeSecurityInit(JNIEnv*, jclass) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001450 // security_getenforce is not allowed on app process. Initialize and cache
1451 // the value before zygote forks.
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001452 g_is_security_enforced = security_getenforce();
1453}
1454
Christopher Ferris76de39e2017-06-20 16:13:40 -07001455static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
1456 PreApplicationInit();
1457}
1458
Narayan Kamath973b4662014-03-31 13:41:26 +01001459static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
1460 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +01001461 jint runtime_flags, jobjectArray rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001462 jint mount_external, jstring se_info, jstring nice_name,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001463 jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001464 jstring instruction_set, jstring app_data_dir, jstring package_name,
1465 jobjectArray packages_for_uid, jobjectArray visible_vol_ids) {
1466 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
Pavlin Radoslavovfbd59042015-11-23 17:13:25 -08001467
Chris Wailesaa1c9622019-01-10 16:55:32 -08001468 if (UNLIKELY(managed_fds_to_close == nullptr)) {
1469 ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
1470 }
1471
1472 std::vector<int> fds_to_close =
1473 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
1474 std::vector<int> fds_to_ignore =
1475 ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
1476 .value_or(std::vector<int>());
1477
1478 std::vector<int> blastula_pipes = MakeBlastulaPipeReadFDVector();
1479
1480 fds_to_close.insert(fds_to_close.end(), blastula_pipes.begin(), blastula_pipes.end());
1481 fds_to_ignore.insert(fds_to_ignore.end(), blastula_pipes.begin(), blastula_pipes.end());
1482
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001483 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001484
1485 if (gBlastulaPoolEventFD != -1) {
1486 fds_to_close.push_back(gBlastulaPoolEventFD);
1487 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1488 }
1489
Chris Wailesaf594fc2018-11-02 11:00:07 -07001490 pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001491
David Sehrde8d0bd2018-06-22 10:45:36 -07001492 if (pid == 0) {
1493 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1494 capabilities, capabilities,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001495 mount_external, se_info, nice_name, false,
1496 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
1497 package_name, packages_for_uid, visible_vol_ids);
David Sehrde8d0bd2018-06-22 10:45:36 -07001498 }
1499 return pid;
Narayan Kamath973b4662014-03-31 13:41:26 +01001500}
1501
1502static jint com_android_internal_os_Zygote_nativeForkSystemServer(
1503 JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001504 jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
1505 jlong effective_capabilities) {
Chris Wailesaa1c9622019-01-10 16:55:32 -08001506 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1507 fds_to_ignore(fds_to_close);
1508
Chris Wailesba4c2eb2019-01-11 17:13:00 -08001509 fds_to_close.push_back(gBlastulaPoolSocketFD);
Chris Wailesaa1c9622019-01-10 16:55:32 -08001510
1511 if (gBlastulaPoolEventFD != -1) {
1512 fds_to_close.push_back(gBlastulaPoolEventFD);
1513 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1514 }
1515
Chris Wailesaf594fc2018-11-02 11:00:07 -07001516 pid_t pid = ForkCommon(env, true,
Chris Wailesaa1c9622019-01-10 16:55:32 -08001517 fds_to_close,
1518 fds_to_ignore);
David Sehrde8d0bd2018-06-22 10:45:36 -07001519 if (pid == 0) {
1520 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
Chris Wailesaf594fc2018-11-02 11:00:07 -07001521 permitted_capabilities, effective_capabilities,
1522 MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
1523 false, nullptr, nullptr, nullptr, nullptr, nullptr);
David Sehrde8d0bd2018-06-22 10:45:36 -07001524 } else if (pid > 0) {
Narayan Kamath973b4662014-03-31 13:41:26 +01001525 // The zygote process checks whether the child process has died or not.
1526 ALOGI("System server process %d has been created", pid);
1527 gSystemServerPid = pid;
1528 // There is a slight window that the system server process has crashed
1529 // but it went unnoticed because we haven't published its pid yet. So
1530 // we recheck here just to make sure that all is well.
1531 int status;
1532 if (waitpid(pid, &status, WNOHANG) == pid) {
1533 ALOGE("System server process %d has died. Restarting Zygote!", pid);
Andreas Gampeb053cce2015-11-17 16:38:59 -08001534 RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
Narayan Kamath973b4662014-03-31 13:41:26 +01001535 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001536
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001537 if (UsePerAppMemcg()) {
Minchan Kim5fa8af22018-06-27 11:32:40 +09001538 // Assign system_server to the correct memory cgroup.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001539 // Not all devices mount memcg so check if it is mounted first
Minchan Kim5fa8af22018-06-27 11:32:40 +09001540 // to avoid unnecessarily printing errors and denials in the logs.
Suren Baghdasaryan3fc4af62018-12-14 10:32:22 -08001541 if (!SetTaskProfiles(pid, std::vector<std::string>{"SystemMemoryProcess"})) {
1542 ALOGE("couldn't add process %d into system memcg group", pid);
Minchan Kim5fa8af22018-06-27 11:32:40 +09001543 }
Carmen Jacksondd401252017-02-23 15:21:10 -08001544 }
Narayan Kamath973b4662014-03-31 13:41:26 +01001545 }
1546 return pid;
1547}
1548
Chris Wailesaa1c9622019-01-10 16:55:32 -08001549/**
1550 * A JNI function that forks a blastula from the Zygote while ensuring proper
1551 * file descriptor hygiene.
1552 *
1553 * @param env Managed runtime environment
1554 * @param read_pipe_fd The read FD for the blastula reporting pipe. Manually closed by blastlas
1555 * in managed code.
1556 * @param write_pipe_fd The write FD for the blastula reporting pipe. Manually closed by the
1557 * zygote in managed code.
1558 * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by
1559 * the FD hygiene code and automatically "closed" in the new blastula.
1560 * @return
1561 */
1562static jint com_android_internal_os_Zygote_nativeForkBlastula(JNIEnv* env, jclass,
1563 jint read_pipe_fd, jint write_pipe_fd, jintArray managed_session_socket_fds) {
1564 std::vector<int> fds_to_close(MakeBlastulaPipeReadFDVector()),
1565 fds_to_ignore(fds_to_close);
1566
1567 std::vector<int> session_socket_fds =
1568 ExtractJIntArray(env, "blastula", nullptr, managed_session_socket_fds)
1569 .value_or(std::vector<int>());
1570
1571 // The Blastula Pool Event FD is created during the initialization of the
1572 // blastula pool and should always be valid here.
1573
1574 fds_to_close.push_back(gZygoteSocketFD);
1575 fds_to_close.push_back(gBlastulaPoolEventFD);
1576 fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
1577
1578 fds_to_ignore.push_back(gZygoteSocketFD);
1579 fds_to_ignore.push_back(gBlastulaPoolSocketFD);
1580 fds_to_ignore.push_back(gBlastulaPoolEventFD);
1581 fds_to_ignore.push_back(read_pipe_fd);
1582 fds_to_ignore.push_back(write_pipe_fd);
1583 fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
1584
1585 pid_t blastula_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
1586
1587 if (blastula_pid != 0) {
1588 ++gBlastulaPoolCount;
1589 AddBlastulaTableEntry(blastula_pid, read_pipe_fd);
1590 }
1591
1592 return blastula_pid;
1593}
1594
Robert Sesek54e387d2016-12-02 17:27:50 -05001595static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
1596 JNIEnv* env, jclass, jstring path) {
1597 ScopedUtfChars path_native(env, path);
1598 const char* path_cstr = path_native.c_str();
1599 if (!path_cstr) {
Chris Wailesaf594fc2018-11-02 11:00:07 -07001600 RuntimeAbort(env, __LINE__, "path_cstr == nullptr");
Robert Sesek54e387d2016-12-02 17:27:50 -05001601 }
1602 FileDescriptorWhitelist::Get()->Allow(path_cstr);
1603}
1604
doheon1.lee885b7422016-01-20 13:07:27 +09001605static void com_android_internal_os_Zygote_nativeUnmountStorageOnInit(JNIEnv* env, jclass) {
1606 // Zygote process unmount root storage space initially before every child processes are forked.
1607 // Every forked child processes (include SystemServer) only mount their own root storage space
Robert Seseke4f8d692016-09-13 19:13:01 -04001608 // and no need unmount storage operation in MountEmulatedStorage method.
1609 // Zygote process does not utilize root storage spaces and unshares its mount namespace below.
1610
1611 // See storage config details at http://source.android.com/tech/storage/
1612 // Create private mount namespace shared by all children
1613 if (unshare(CLONE_NEWNS) == -1) {
1614 RuntimeAbort(env, __LINE__, "Failed to unshare()");
1615 return;
1616 }
1617
1618 // Mark rootfs as being a slave so that changes from default
1619 // namespace only flow into our children.
1620 if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
1621 RuntimeAbort(env, __LINE__, "Failed to mount() rootfs as MS_SLAVE");
1622 return;
1623 }
1624
1625 // Create a staging tmpfs that is shared by our children; they will
1626 // bind mount storage into their respective private namespaces, which
1627 // are isolated from each other.
1628 const char* target_base = getenv("EMULATED_STORAGE_TARGET");
1629 if (target_base != nullptr) {
1630#define STRINGIFY_UID(x) __STRING(x)
1631 if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV,
1632 "uid=0,gid=" STRINGIFY_UID(AID_SDCARD_R) ",mode=0751") == -1) {
1633 ALOGE("Failed to mount tmpfs to %s", target_base);
1634 RuntimeAbort(env, __LINE__, "Failed to mount tmpfs");
1635 return;
1636 }
1637#undef STRINGIFY_UID
1638 }
doheon1.lee885b7422016-01-20 13:07:27 +09001639
1640 UnmountTree("/storage");
doheon1.lee885b7422016-01-20 13:07:27 +09001641}
1642
Martijn Coenen86f08a52019-01-03 16:23:01 +01001643static void com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter(
1644 JNIEnv* env, jclass, jint uidGidMin, jint uidGidMax) {
1645 if (!g_is_security_enforced) {
1646 ALOGI("seccomp disabled by setenforce 0");
1647 return;
1648 }
1649
Martijn Coenen86f08a52019-01-03 16:23:01 +01001650 bool installed = install_setuidgid_seccomp_filter(uidGidMin, uidGidMax);
1651 if (!installed) {
1652 RuntimeAbort(env, __LINE__, "Could not install setuid/setgid seccomp filter.");
1653 }
Martijn Coenen86f08a52019-01-03 16:23:01 +01001654}
1655
Chris Wailesaa1c9622019-01-10 16:55:32 -08001656/**
1657 * Called from a blastula to specialize the process for a specific application.
1658 *
1659 * @param env Managed runtime environment
1660 * @param uid User ID of the new application
1661 * @param gid Group ID of the new application
1662 * @param gids Extra groups that the process belongs to
1663 * @param runtime_flags Flags for changing the behavior of the managed runtime
1664 * @param rlimits Resource limits
1665 * @param mount_external The mode (read/write/normal) that external storage will be mounted with
1666 * @param se_info SELinux policy information
1667 * @param nice_name New name for this process
1668 * @param is_child_zygote If the process is to become a WebViewZygote
1669 * @param instruction_set The instruction set expected/requested by the new application
1670 * @param app_data_dir Path to the application's data directory
1671 */
1672static void com_android_internal_os_Zygote_nativeSpecializeBlastula(
1673 JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
1674 jint runtime_flags, jobjectArray rlimits,
1675 jint mount_external, jstring se_info, jstring nice_name,
1676 jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir,
1677 jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids) {
1678 jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
1679
1680 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
1681 capabilities, capabilities,
1682 mount_external, se_info, nice_name, false,
1683 is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
1684 package_name, packages_for_uid, visible_vol_ids);
1685}
1686
1687/**
1688 * A helper method for fetching socket file descriptors that were opened by init from the
1689 * environment.
1690 *
1691 * @param env Managed runtime environment
1692 * @param is_primary If this process is the primary or secondary Zygote; used to compute the name
1693 * of the environment variable storing the file descriptors.
1694 */
1695static void com_android_internal_os_Zygote_nativeGetSocketFDs(JNIEnv* env, jclass,
1696 jboolean is_primary) {
1697 std::string android_socket_prefix(ANDROID_SOCKET_PREFIX);
1698 std::string env_var_name = android_socket_prefix + (is_primary ? "zygote" : "zygote_secondary");
1699 char* env_var_val = getenv(env_var_name.c_str());
1700
1701 if (env_var_val != nullptr) {
1702 gZygoteSocketFD = atoi(env_var_val);
1703 ALOGV("Zygote:zygoteSocketFD = %d", gZygoteSocketFD);
1704 } else {
1705 ALOGE("Unable to fetch Zygote socket file descriptor");
1706 }
1707
1708 env_var_name = android_socket_prefix + (is_primary ? "blastula_pool" : "blastula_pool_secondary");
1709 env_var_val = getenv(env_var_name.c_str());
1710
1711 if (env_var_val != nullptr) {
1712 gBlastulaPoolSocketFD = atoi(env_var_val);
1713 ALOGV("Zygote:blastulaPoolSocketFD = %d", gBlastulaPoolSocketFD);
1714 } else {
1715 ALOGE("Unable to fetch Blastula pool socket file descriptor");
1716 }
1717}
1718
1719/**
1720 * @param env Managed runtime environment
1721 * @return A managed array of raw file descriptors for the read ends of the blastula reporting
1722 * pipes.
1723 */
1724static jintArray com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs(JNIEnv* env, jclass) {
1725 std::vector<int> blastula_fds = MakeBlastulaPipeReadFDVector();
1726
1727 jintArray managed_blastula_fds = env->NewIntArray(blastula_fds.size());
1728 env->SetIntArrayRegion(managed_blastula_fds, 0, blastula_fds.size(), blastula_fds.data());
1729
1730 return managed_blastula_fds;
1731}
1732
1733/**
1734 * A JNI wrapper around RemoveBlastulaTableEntry.
1735 *
1736 * @param env Managed runtime environment
1737 * @param blastula_pid Process ID of the blastula entry to invalidate
1738 * @return True if an entry was invalidated; false otherwise.
1739 */
1740static jboolean com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry(JNIEnv* env, jclass,
1741 jint blastula_pid) {
1742 return RemoveBlastulaTableEntry(blastula_pid);
1743}
1744
1745/**
1746 * Creates the blastula pool event FD if it doesn't exist and returns it. This is used by the
1747 * ZygoteServer poll loop to know when to re-fill the blastula pool.
1748 *
1749 * @param env Managed runtime environment
1750 * @return A raw event file descriptor used to communicate (from the signal handler) when the
1751 * Zygote receives a SIGCHLD for a blastula
1752 */
1753static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD(JNIEnv* env, jclass) {
1754 if (gBlastulaPoolEventFD == -1) {
1755 if ((gBlastulaPoolEventFD = eventfd(0, 0)) == -1) {
1756 ZygoteFailure(env, "zygote", nullptr, StringPrintf("Unable to create eventfd: %s", strerror(errno)));
1757 }
1758 }
1759
1760 return gBlastulaPoolEventFD;
1761}
1762
1763/**
1764 * @param env Managed runtime environment
1765 * @return The number of blastulas currently in the blastula pool
1766 */
1767static jint com_android_internal_os_Zygote_nativeGetBlastulaPoolCount(JNIEnv* env, jclass) {
1768 return gBlastulaPoolCount;
1769}
1770
Daniel Micay76f6a862015-09-19 17:31:01 -04001771static const JNINativeMethod gMethods[] = {
Victor Hsiehc8176ef2018-01-08 12:43:00 -08001772 { "nativeSecurityInit", "()V",
1773 (void *) com_android_internal_os_Zygote_nativeSecurityInit },
Andreas Gampeaec67dc2014-09-02 21:23:06 -07001774 { "nativeForkAndSpecialize",
Sudheer Shanka3f0645b2018-09-18 13:07:59 -07001775 "(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 +01001776 (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
1777 { "nativeForkSystemServer", "(II[II[[IJJ)I",
doheon1.lee885b7422016-01-20 13:07:27 +09001778 (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
Robert Sesek54e387d2016-12-02 17:27:50 -05001779 { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",
1780 (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },
doheon1.lee885b7422016-01-20 13:07:27 +09001781 { "nativeUnmountStorageOnInit", "()V",
Christopher Ferris76de39e2017-06-20 16:13:40 -07001782 (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit },
1783 { "nativePreApplicationInit", "()V",
Martijn Coenen86f08a52019-01-03 16:23:01 +01001784 (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
1785 { "nativeInstallSeccompUidGidFilter", "(II)V",
Chris Wailesaa1c9622019-01-10 16:55:32 -08001786 (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
1787 { "nativeForkBlastula", "(II[I)I",
1788 (void *) com_android_internal_os_Zygote_nativeForkBlastula },
1789 { "nativeSpecializeBlastula",
1790 "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
1791 (void *) com_android_internal_os_Zygote_nativeSpecializeBlastula },
1792 { "nativeGetSocketFDs", "(Z)V",
1793 (void *) com_android_internal_os_Zygote_nativeGetSocketFDs },
1794 { "nativeGetBlastulaPipeFDs", "()[I",
1795 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPipeFDs },
1796 { "nativeRemoveBlastulaTableEntry", "(I)Z",
1797 (void *) com_android_internal_os_Zygote_nativeRemoveBlastulaTableEntry },
1798 { "nativeGetBlastulaPoolEventFD", "()I",
1799 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolEventFD },
1800 { "nativeGetBlastulaPoolCount", "()I",
1801 (void *) com_android_internal_os_Zygote_nativeGetBlastulaPoolCount }
Narayan Kamath973b4662014-03-31 13:41:26 +01001802};
1803
1804int register_com_android_internal_os_Zygote(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001805 gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
Orion Hodson46724e72018-10-19 13:05:33 +01001806 gCallPostForkSystemServerHooks = GetStaticMethodIDOrDie(env, gZygoteClass,
1807 "callPostForkSystemServerHooks",
1808 "()V");
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001809 gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
Robert Sesekd0a190df2018-02-12 18:46:01 -05001810 "(IZZLjava/lang/String;)V");
Narayan Kamath973b4662014-03-31 13:41:26 +01001811
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001812 return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
Narayan Kamath973b4662014-03-31 13:41:26 +01001813}
1814} // namespace android