Merge changes I98c9329f,I40936f7b,I09d20ff1
* changes:
Defer registration of the arc4random fork-detect handler.
Make getpid work before the main thread is initialized.
Take the arc4random lock before forking.
diff --git a/libc/bionic/getpid.cpp b/libc/bionic/getpid.cpp
index a3d5b35..779b147 100644
--- a/libc/bionic/getpid.cpp
+++ b/libc/bionic/getpid.cpp
@@ -35,10 +35,12 @@
pid_t getpid() {
pthread_internal_t* self = __get_thread();
- // Do we have a valid cached pid?
- pid_t cached_pid;
- if (__predict_true(self->get_cached_pid(&cached_pid))) {
- return cached_pid;
+ if (__predict_true(self)) {
+ // Do we have a valid cached pid?
+ pid_t cached_pid;
+ if (__predict_true(self->get_cached_pid(&cached_pid))) {
+ return cached_pid;
+ }
}
// We're still in the dynamic linker or we're in the middle of forking, so ask the kernel.
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 0c9e87b..2070c9c 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -41,13 +41,14 @@
#include <sys/time.h>
#include <unistd.h>
+#include "private/KernelArgumentBlock.h"
+#include "private/WriteProtected.h"
#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_ssp.h"
#include "private/bionic_tls.h"
-#include "private/KernelArgumentBlock.h"
#include "private/libc_logging.h"
-#include "private/WriteProtected.h"
+#include "private/thread_private.h"
#include "pthread_internal.h"
extern "C" abort_msg_t** __abort_message_ptr;
@@ -108,6 +109,11 @@
}
#endif
+static void arc4random_fork_handler() {
+ _rs_forked = 1;
+ _thread_arc4_lock();
+}
+
void __libc_init_common(KernelArgumentBlock& args) {
// Initialize various globals.
environ = args.envp;
@@ -123,6 +129,9 @@
pthread_internal_t* main_thread = __get_thread();
__pthread_internal_add(main_thread);
+ // Register atfork handlers to take and release the arc4random lock.
+ pthread_atfork(arc4random_fork_handler, _thread_arc4_unlock, _thread_arc4_unlock);
+
__system_properties_init(); // Requires 'environ'.
}
diff --git a/libc/private/thread_private.h b/libc/private/thread_private.h
index 2e3ac3d..0081ad0 100644
--- a/libc/private/thread_private.h
+++ b/libc/private/thread_private.h
@@ -50,6 +50,8 @@
#define _ARC4_UNLOCK() _thread_arc4_unlock()
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
+extern volatile sig_atomic_t _rs_forked;
+
__END_DECLS
#endif /* _THREAD_PRIVATE_H_ */
diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h
index 96d9c9a..8d965e0 100644
--- a/libc/upstream-openbsd/android/include/arc4random.h
+++ b/libc/upstream-openbsd/android/include/arc4random.h
@@ -49,13 +49,7 @@
raise(SIGKILL);
}
-static volatile sig_atomic_t _rs_forked;
-
-static inline void
-_rs_forkhandler(void)
-{
- _rs_forked = 1;
-}
+volatile sig_atomic_t _rs_forked;
static inline void
_rs_forkdetect(void)
@@ -90,6 +84,5 @@
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *rsxp, sizeof(**rsxp),
"arc4random _rsx structure");
- _ARC4_ATFORK(_rs_forkhandler);
return (0);
}