libc/stdlib: Avoid calling destructors in a wrong order.
authorzrj <rimvydas.jasinskas@gmail.com>
Mon, 1 Apr 2019 11:20:40 +0000 (14:20 +0300)
committerzrj <zrj@dragonflybsd.org>
Sun, 7 Apr 2019 19:15:01 +0000 (22:15 +0300)
There is a possibility that dso handle in __cxa_finalize() might be owned
by another dso. On exit(3) calling these destructors is pointless.

lib/libc/stdlib/atexit.c
lib/libc/stdlib/atexit.h

index 9d9601d..eae0f5d 100644 (file)
@@ -148,6 +148,8 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 #pragma weak __pthread_cxa_finalize
 void __pthread_cxa_finalize(const struct dl_phdr_info *);
 
+static int global_exit;
+
 /*
  * Call all handlers registered with __cxa_atexit for the shared
  * object owning 'dso'.  Note: if 'dso' is NULL, then all remaining
@@ -161,10 +163,12 @@ __cxa_finalize(void *dso)
        struct atexit_fn fn;
        int n, has_phdr;
 
-       if (dso != NULL)
+       if (dso != NULL) {
                has_phdr = _rtld_addr_phdr(dso, &phdr_info);
-       else
+       } else {
                has_phdr = 0;
+               global_exit = 1;
+       }
 
        _MUTEX_LOCK(&atexit_mutex);
        for (p = __atexit; p; p = p->next) {
@@ -174,8 +178,9 @@ __cxa_finalize(void *dso)
                        fn = p->fns[n];
                        if (dso != NULL && dso != fn.fn_dso) {
                                /* wrong DSO ? */
-                               if (!has_phdr || !__elf_phdr_match_addr(
-                                   &phdr_info, fn.fn_ptr.cxa_func))
+                               if (!has_phdr || global_exit ||
+                                   !__elf_phdr_match_addr(&phdr_info,
+                                   fn.fn_ptr.cxa_func))
                                        continue;
                        }
                        /*
@@ -197,6 +202,6 @@ __cxa_finalize(void *dso)
        if (dso == NULL)
                _MUTEX_DESTROY(&atexit_mutex);
 
-       if (has_phdr && &__pthread_cxa_finalize != NULL)
+       if (has_phdr && !global_exit && &__pthread_cxa_finalize != NULL)
                __pthread_cxa_finalize(&phdr_info);
 }
index f7ce762..6bc5b4e 100644 (file)
@@ -28,7 +28,6 @@
  *
  *     @(#)atexit.h    8.2 (Berkeley) 7/3/94
  * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.4 2007/01/09 00:28:09 imp Exp $
- * $DragonFly: src/lib/libc/stdlib/atexit.h,v 1.3 2004/01/24 22:18:12 joerg Exp $
  */
 
 /* must be at least 32 to guarantee ANSI conformance */