summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/atexit.c
diff options
context:
space:
mode:
authorkettenis <>2014-06-18 19:01:10 +0000
committerkettenis <>2014-06-18 19:01:10 +0000
commitea52171d7ee0bb85a996dc2021440e122bf0357d (patch)
tree25ba00731ee7e34a8f0bb9da9731d10eba63a790 /src/lib/libc/stdlib/atexit.c
parent067b361c7dbce14db401c57d13ca4e1146dedc3c (diff)
downloadopenbsd-ea52171d7ee0bb85a996dc2021440e122bf0357d.tar.gz
openbsd-ea52171d7ee0bb85a996dc2021440e122bf0357d.tar.bz2
openbsd-ea52171d7ee0bb85a996dc2021440e122bf0357d.zip
Always call atexit handlers as if they were registered with __cxa_atexit.
The extra argument doesn't hurt genuine atexit handlers and this fixes a bug where we didn't provide the argument (effectively passing garbage) for functions registered with __cxa_atexit in the main executable. Pointed out by Dmitriy Ivanov <dimitry@google.com> and Elliott Hughes <enh@google.com>. ok matthew@
Diffstat (limited to 'src/lib/libc/stdlib/atexit.c')
-rw-r--r--src/lib/libc/stdlib/atexit.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 049da3261d..9b08ebd7e6 100644
--- a/src/lib/libc/stdlib/atexit.c
+++ b/src/lib/libc/stdlib/atexit.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: atexit.c,v 1.17 2013/12/28 18:38:42 kettenis Exp $ */ 1/* $OpenBSD: atexit.c,v 1.18 2014/06/18 19:01:10 kettenis Exp $ */
2/* 2/*
3 * Copyright (c) 2002 Daniel Hartmeier 3 * Copyright (c) 2002 Daniel Hartmeier
4 * All rights reserved. 4 * All rights reserved.
@@ -90,7 +90,7 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso)
90 __atexit = p; 90 __atexit = p;
91 } 91 }
92 fnp = &p->fns[p->ind++]; 92 fnp = &p->fns[p->ind++];
93 fnp->fn_ptr.cxa_func = func; 93 fnp->fn_ptr = func;
94 fnp->fn_arg = arg; 94 fnp->fn_arg = arg;
95 fnp->fn_dso = dso; 95 fnp->fn_dso = dso;
96 if (mprotect(p, pgsize, PROT_READ)) 96 if (mprotect(p, pgsize, PROT_READ))
@@ -118,7 +118,7 @@ __cxa_finalize(void *dso)
118 118
119 for (p = __atexit; p != NULL; p = p->next) { 119 for (p = __atexit; p != NULL; p = p->next) {
120 for (n = p->ind; --n >= 0;) { 120 for (n = p->ind; --n >= 0;) {
121 if (p->fns[n].fn_ptr.cxa_func == NULL) 121 if (p->fns[n].fn_ptr == NULL)
122 continue; /* already called */ 122 continue; /* already called */
123 if (dso != NULL && dso != p->fns[n].fn_dso) 123 if (dso != NULL && dso != p->fns[n].fn_dso)
124 continue; /* wrong DSO */ 124 continue; /* wrong DSO */
@@ -129,13 +129,10 @@ __cxa_finalize(void *dso)
129 */ 129 */
130 fn = p->fns[n]; 130 fn = p->fns[n];
131 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) { 131 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE) == 0) {
132 p->fns[n].fn_ptr.cxa_func = NULL; 132 p->fns[n].fn_ptr = NULL;
133 mprotect(p, pgsize, PROT_READ); 133 mprotect(p, pgsize, PROT_READ);
134 } 134 }
135 if (fn.fn_dso != NULL) 135 (*fn.fn_ptr)(fn.fn_arg);
136 (*fn.fn_ptr.cxa_func)(fn.fn_arg);
137 else
138 (*fn.fn_ptr.std_func)();
139 } 136 }
140 } 137 }
141 138
@@ -185,7 +182,7 @@ __atexit_register_cleanup(void (*func)(void))
185 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE)) 182 if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
186 goto unlock; 183 goto unlock;
187 } 184 }
188 p->fns[0].fn_ptr.std_func = func; 185 p->fns[0].fn_ptr = (void (*)(void *))func;
189 p->fns[0].fn_arg = NULL; 186 p->fns[0].fn_arg = NULL;
190 p->fns[0].fn_dso = NULL; 187 p->fns[0].fn_dso = NULL;
191 mprotect(p, pgsize, PROT_READ); 188 mprotect(p, pgsize, PROT_READ);