fix __cxa_finalize() implementation to be thread safe.

__cxa_finalize() modifies the access permissions of __atexit
global variable without acquiring  _ATEXIT_LOCK(). Fix it prevent
any possible races.

Change-Id: I11939d0ebcbf6f360c14163222d40a449d96948e
This commit is contained in:
Srinavasa Nagaraju 2012-02-28 12:08:22 +09:00 committed by Johan Redestig
parent 643e572233
commit 2270dfa0c4

View File

@ -131,6 +131,7 @@ __cxa_finalize(void *dso)
if (__atexit_invalid) if (__atexit_invalid)
return; return;
_ATEXIT_LOCK();
call_depth++; call_depth++;
for (p = __atexit; p != NULL; p = p->next) { for (p = __atexit; p != NULL; p = p->next) {
@ -149,6 +150,7 @@ __cxa_finalize(void *dso)
p->fns[n].fn_ptr.cxa_func = NULL; p->fns[n].fn_ptr.cxa_func = NULL;
mprotect(p, pgsize, PROT_READ); mprotect(p, pgsize, PROT_READ);
} }
_ATEXIT_UNLOCK();
#if ANDROID #if ANDROID
/* it looks like we should always call the function /* it looks like we should always call the function
* with an argument, even if dso is not NULL. Otherwise * with an argument, even if dso is not NULL. Otherwise
@ -162,6 +164,7 @@ __cxa_finalize(void *dso)
else else
(*fn.fn_ptr.std_func)(); (*fn.fn_ptr.std_func)();
#endif /* !ANDROID */ #endif /* !ANDROID */
_ATEXIT_LOCK();
} }
} }
@ -178,6 +181,7 @@ __cxa_finalize(void *dso)
} }
__atexit = NULL; __atexit = NULL;
} }
_ATEXIT_UNLOCK();
} }
/* /*