newlib: copy args for atexit()'ed function before unlock the mutex
Commit Message
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>
---
newlib/libc/stdlib/__call_atexit.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
Comments
On Dec 3 17:57, Takashi Yano wrote:
> 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>
> ---
> newlib/libc/stdlib/__call_atexit.c | 14 ++++++++++----
> 1 file changed, 10 insertions(+), 4 deletions(-)
Thanks, please push.
Corinna
@@ -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