summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortedu <>2014-07-10 21:14:22 +0000
committertedu <>2014-07-10 21:14:22 +0000
commit7f6a95d90665644779afb040180fa14a6bd15a15 (patch)
tree363d9818bba92cf877e4b7765f26becc6d0ed8e7 /src
parentbbf0836e37dbf8c0b3a354c7df445b5f0fcf6f1a (diff)
downloadopenbsd-7f6a95d90665644779afb040180fa14a6bd15a15.tar.gz
openbsd-7f6a95d90665644779afb040180fa14a6bd15a15.tar.bz2
openbsd-7f6a95d90665644779afb040180fa14a6bd15a15.zip
as noted by google/android via kettenis, atexit handlers can install new
handlers. if this happens, restart the loop. ok kettenis matthew millert miod
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/atexit.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/lib/libc/stdlib/atexit.c b/src/lib/libc/stdlib/atexit.c
index 9b08ebd7e6..34f76bb7d3 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.18 2014/06/18 19:01:10 kettenis Exp $ */ 1/* $OpenBSD: atexit.c,v 1.19 2014/07/10 21:14:22 tedu Exp $ */
2/* 2/*
3 * Copyright (c) 2002 Daniel Hartmeier 3 * Copyright (c) 2002 Daniel Hartmeier
4 * All rights reserved. 4 * All rights reserved.
@@ -38,6 +38,7 @@
38#include "thread_private.h" 38#include "thread_private.h"
39 39
40struct atexit *__atexit; 40struct atexit *__atexit;
41static int restartloop;
41 42
42/* 43/*
43 * Function pointers are stored in a linked list of pages. The list 44 * Function pointers are stored in a linked list of pages. The list
@@ -95,6 +96,7 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso)
95 fnp->fn_dso = dso; 96 fnp->fn_dso = dso;
96 if (mprotect(p, pgsize, PROT_READ)) 97 if (mprotect(p, pgsize, PROT_READ))
97 goto unlock; 98 goto unlock;
99 restartloop = 1;
98 ret = 0; 100 ret = 0;
99unlock: 101unlock:
100 _ATEXIT_UNLOCK(); 102 _ATEXIT_UNLOCK();
@@ -116,6 +118,8 @@ __cxa_finalize(void *dso)
116 118
117 call_depth++; 119 call_depth++;
118 120
121restart:
122 restartloop = 0;
119 for (p = __atexit; p != NULL; p = p->next) { 123 for (p = __atexit; p != NULL; p = p->next) {
120 for (n = p->ind; --n >= 0;) { 124 for (n = p->ind; --n >= 0;) {
121 if (p->fns[n].fn_ptr == NULL) 125 if (p->fns[n].fn_ptr == NULL)
@@ -133,6 +137,8 @@ __cxa_finalize(void *dso)
133 mprotect(p, pgsize, PROT_READ); 137 mprotect(p, pgsize, PROT_READ);
134 } 138 }
135 (*fn.fn_ptr)(fn.fn_arg); 139 (*fn.fn_ptr)(fn.fn_arg);
140 if (restartloop)
141 goto restart;
136 } 142 }
137 } 143 }
138 144
@@ -186,6 +192,7 @@ __atexit_register_cleanup(void (*func)(void))
186 p->fns[0].fn_arg = NULL; 192 p->fns[0].fn_arg = NULL;
187 p->fns[0].fn_dso = NULL; 193 p->fns[0].fn_dso = NULL;
188 mprotect(p, pgsize, PROT_READ); 194 mprotect(p, pgsize, PROT_READ);
195 restartloop = 1;
189unlock: 196unlock:
190 _ATEXIT_UNLOCK(); 197 _ATEXIT_UNLOCK();
191} 198}