diff options
author | Srinavasa Nagaraju <srinavasa.x.nagaraju@sonyericsson.com> | 2012-02-28 12:08:22 +0900 |
---|---|---|
committer | Johan Redestig <johan.redestig@sonymobile.com> | 2012-07-31 12:30:28 +0200 |
commit | 2270dfa0c418ab06e89412ea7b4ffe650490bcc9 (patch) | |
tree | 533d23fa27577c4b6b34acb9b851e4ec1caea0b6 /libc/stdlib | |
parent | 643e5722338d303c0b5aac41107432d8fde4081c (diff) | |
download | bionic-2270dfa0c418ab06e89412ea7b4ffe650490bcc9.zip bionic-2270dfa0c418ab06e89412ea7b4ffe650490bcc9.tar.gz bionic-2270dfa0c418ab06e89412ea7b4ffe650490bcc9.tar.bz2 |
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
Diffstat (limited to 'libc/stdlib')
-rw-r--r-- | libc/stdlib/atexit.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index f4bcab9..55b7132 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -131,6 +131,7 @@ __cxa_finalize(void *dso) if (__atexit_invalid) return; + _ATEXIT_LOCK(); call_depth++; for (p = __atexit; p != NULL; p = p->next) { @@ -149,6 +150,7 @@ __cxa_finalize(void *dso) p->fns[n].fn_ptr.cxa_func = NULL; mprotect(p, pgsize, PROT_READ); } + _ATEXIT_UNLOCK(); #if ANDROID /* it looks like we should always call the function * with an argument, even if dso is not NULL. Otherwise @@ -162,6 +164,7 @@ __cxa_finalize(void *dso) else (*fn.fn_ptr.std_func)(); #endif /* !ANDROID */ + _ATEXIT_LOCK(); } } @@ -178,6 +181,7 @@ __cxa_finalize(void *dso) } __atexit = NULL; } + _ATEXIT_UNLOCK(); } /* |