summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Wailes <chriswailes@google.com> 2021-02-12 14:46:28 -0800
committer Chris Wailes <chriswailes@google.com> 2021-05-17 11:41:52 -0700
commitecdd0b3b42666b24d9f4adc2746e8b7d17895417 (patch)
tree5f75877f0996f582d204a8412e65d06a5e02c4ed
parent6c914b4bc61235d6a4ff3cc468de6eac286aadf8 (diff)
Reset stack guard after fork from Zygote
Bug: 168258494 Test: Check log for change in stack guard Change-Id: Iaf565a374924ad664b005d348d5c270b3fc2fa16
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp15
-rw-r--r--core/jni/com_android_internal_os_Zygote.h8
-rw-r--r--core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp1
3 files changed, 24 insertions, 0 deletions
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 6ac43bd30973..96fc0866a345 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -93,6 +93,10 @@
#include "nativebridge/native_bridge.h"
+#if defined(__BIONIC__)
+extern "C" void android_reset_stack_guards();
+#endif
+
namespace {
// TODO (chriswailes): Add a function to initialize native Zygote data.
@@ -389,6 +393,7 @@ static void sendSigChildStatus(const pid_t pid, const uid_t uid, const int statu
}
// This signal handler is for zygote mode, since the zygote must reap its children
+NO_STACK_PROTECTOR
static void SigChldHandler(int /*signal_number*/, siginfo_t* info, void* /*ucontext*/) {
pid_t pid;
int status;
@@ -1965,6 +1970,7 @@ void zygote::ZygoteFailure(JNIEnv* env,
}
// Utility routine to fork a process from the zygote.
+NO_STACK_PROTECTOR
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore,
@@ -2018,6 +2024,11 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
}
+#if defined(__BIONIC__)
+ // Reset the stack guard for the new process.
+ android_reset_stack_guards();
+#endif
+
// The child process.
PreApplicationInit();
@@ -2050,6 +2061,7 @@ static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jcl
PreApplicationInit();
}
+NO_STACK_PROTECTOR
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint runtime_flags,
jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name,
@@ -2099,6 +2111,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
return pid;
}
+NO_STACK_PROTECTOR
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
@@ -2170,6 +2183,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
* @param is_priority_fork Controls the nice level assigned to the newly created process
* @return child pid in the parent, 0 in the child
*/
+NO_STACK_PROTECTOR
static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env,
jclass,
jint read_pipe_fd,
@@ -2184,6 +2198,7 @@ static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env,
args_known == JNI_TRUE, is_priority_fork == JNI_TRUE, true);
}
+NO_STACK_PROTECTOR
int zygote::forkApp(JNIEnv* env,
int read_pipe_fd,
int write_pipe_fd,
diff --git a/core/jni/com_android_internal_os_Zygote.h b/core/jni/com_android_internal_os_Zygote.h
index b87396cbd5f5..15f53e0814e3 100644
--- a/core/jni/com_android_internal_os_Zygote.h
+++ b/core/jni/com_android_internal_os_Zygote.h
@@ -20,6 +20,14 @@
#define LOG_TAG "Zygote"
#define ATRACE_TAG ATRACE_TAG_DALVIK
+/*
+ * All functions that lead to ForkCommon must be marked with the
+ * no_stack_protector attributed. Because ForkCommon changes the stack
+ * protector cookie, all of the guard checks on the frames above ForkCommon
+ * would fail when they are popped.
+ */
+#define NO_STACK_PROTECTOR __attribute__((no_stack_protector))
+
#include <jni.h>
#include <vector>
#include <android-base/stringprintf.h>
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 5fe96ede202e..1b4b9bd0bdad 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -365,6 +365,7 @@ void com_android_internal_os_ZygoteCommandBuffer_nativeReadFullyAndReset(JNIEnv*
// We only process fork commands if the peer uid matches expected_uid.
// For every fork command after the first, we check that the requested uid is at
// least minUid.
+NO_STACK_PROTECTOR
jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
JNIEnv* env,
jclass,