From d41cec56d5c04d88aa2d06986b692cd1fa279748 Mon Sep 17 00:00:00 2001
From: Waldemar Brodkorb <wbx@uclibc-ng.org>
Date: Sun, 3 Jan 2016 19:44:54 +0100
Subject: 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.:
 http://bugs.busybox.net/show_bug.cgi?id=8211
 http://sourceware.org/bugzilla/show_bug.cgi?id=13502

Add test-case, enable cleanup for NPTL only.

Signed-off-by: John Ata <john.ata@baesystems.com>
Signed-off-by: Leonid Lisovskiy <lly.dev@gmail.com>
---
 libc/stdlib/_atexit.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'libc')

diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c
index 3faa9f05f..8a3196781 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>
+#endif
 
 #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.
      */
 #ifdef UNREGISTER_ATFORK
-    if (d != NULL) {
-        UNREGISTER_ATFORK(d);
+    if (dso_handle != NULL) {
+        UNREGISTER_ATFORK(dso_handle);
     }
 #endif
-#endif
 }
 #endif
 
-- 
cgit v1.2.3