[PATCH] newlib: copy args for atexit()'ed function before unlock the mutex
Takashi Yano <[email protected]> Wed, 3 Dec 2025 17:57:35 +0900
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
The commit a2a8bc771f2f has a problem that __atexit which includes
args for atexit()'ed function may be touched by another thread
since the mutex is unlocked while calling the function.
With this path, the args, etc. are copyed to local variable to
prevent this problem.
Fixes: a2a8bc771f2f ("newlib: Unlock the mutex while calling atexit()'ed functions")
Suggested-by: Sebastian Huber <[email protected]>
Reviewed-by: Corinna Vinschen <[email protected]>, Sebastian Huber <[email protected]>
Signed-off-by: Takashi Yano <[email protected]>
---
newlib/libc/stdlib/__call_atexit.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
index 44f1f6acc..15ecda343 100644
--- a/newlib/libc/stdlib/__call_atexit.c
+++ b/newlib/libc/stdlib/__call_atexit.c
@@ -93,6 +93,8 @@ __call_exitprocs (int code, void *d)
for (n = p->_ind - 1; n >= 0; n--)
{
int ind;
+ __ULong fntypes, is_cxa;
+ void *fnarg;
i = 1 << n;
@@ -114,18 +116,22 @@ __call_exitprocs (int code, void *d)
ind = p->_ind;
+ fntypes = args->_fntypes;
+ is_cxa = args->_is_cxa;
+ fnarg = args->_fnargs[n];
+
#ifndef __SINGLE_THREAD__
/* Unlock __atexit_recursive_mutex; otherwise, the function fn() may
deadlock if it waits for another thread which calls atexit(). */
__lock_release_recursive(__atexit_recursive_mutex);
#endif
/* Call the function. */
- if (!args || (args->_fntypes & i) == 0)
+ if (!args || (fntypes & i) == 0)
fn ();
- else if ((args->_is_cxa & i) == 0)
- (*((void (*)(int, void *)) fn))(code, args->_fnargs[n]);
+ else if ((is_cxa & i) == 0)
+ (*((void (*)(int, void *)) fn))(code, fnarg);
else
- (*((void (*)(void *)) fn))(args->_fnargs[n]);
+ (*((void (*)(void *)) fn))(fnarg);
#ifndef __SINGLE_THREAD__
__lock_acquire_recursive(__atexit_recursive_mutex);
#endif
--
2.51.0