path: root/libc
diff options
authorWaldemar Brodkorb <>2016-01-03 18:44:54 (GMT)
committerWaldemar Brodkorb <>2016-01-06 22:54:38 (GMT)
commitd41cec56d5c04d88aa2d06986b692cd1fa279748 (patch)
tree0ae2816dabaff91329d1e51f1f234fc8ead55174 /libc
parent7b495396fbf7bf604939d8150955ce891f7e8ccd (diff)
pthread_atfork handlers not removed during dlclose
Invoke pthread_atfork handler cleanup when removing the associated DSO... If a program loads a DSO (dlopen) that sets up a pthread_atfork handler(s), and then subsequently closes the DSO, the handler(s) are left in place. If fork() is subsequently called, the handlers are invoked even though the DSO has been removed causing crashes or unpredictable code execution. This is because the code in __cxa_finalize(atexit.c)to invoke the unregister_atfork() routine is ifdef'd out with the comment that it hasn't been "looked into this yet...". Refs.: Add test-case, enable cleanup for NPTL only. Signed-off-by: John Ata <> Signed-off-by: Leonid Lisovskiy <>
Diffstat (limited to 'libc')
1 files changed, 5 insertions, 4 deletions
diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c
index 3faa9f0..8a31967 100644
--- a/libc/stdlib/_atexit.c
+++ b/libc/stdlib/_atexit.c
@@ -43,6 +43,9 @@
#include <stdio.h>
#include <errno.h>
#include <atomic.h>
+#if defined __UCLIBC_HAS_THREADS__ && defined __UCLIBC_HAS_THREADS_NATIVE__
+# include <fork.h>
#include <bits/uClibc_mutex.h>
__UCLIBC_MUTEX_EXTERN(__atexit_lock) attribute_hidden;
@@ -208,17 +211,15 @@ void __cxa_finalize(void *dso_handle)
-#if 0 /* haven't looked into this yet... */
* Remove the registered fork handlers. We do not have to
* unregister anything if the program is going to terminate anyway.
- if (d != NULL) {
+ if (dso_handle != NULL) {
+ UNREGISTER_ATFORK(dso_handle);