[newlib-cygwin/cygwin-3_6-branch] newlib: copy args for atexit()'ed function before unlock the mutex
Takashi Yano
tyan0@sourceware.org
Thu Dec 4 10:00:52 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=23378fb147e85f572a493f13fe15fe47c764350b
commit 23378fb147e85f572a493f13fe15fe47c764350b
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Sat Nov 29 21:05:02 2025 +0900
newlib: copy args for atexit()'ed function before unlock the mutex
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 <sebastian.huber@embedded-brains.de>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>, Sebastian Huber <sebastian.huber@embedded-brains.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
(cherry picked from commit 7c7d9cf585d0d7c905f600eff14bf4f4e07fb178)
Diff:
---
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
More information about the Newlib-cvs
mailing list