summaryrefslogtreecommitdiffstats
path: root/libc/stdlib
diff options
context:
space:
mode:
authorSrinavasa Nagaraju <srinavasa.x.nagaraju@sonyericsson.com>2012-02-28 12:08:22 +0900
committerJohan Redestig <johan.redestig@sonymobile.com>2012-07-31 12:30:28 +0200
commit2270dfa0c418ab06e89412ea7b4ffe650490bcc9 (patch)
tree533d23fa27577c4b6b34acb9b851e4ec1caea0b6 /libc/stdlib
parent643e5722338d303c0b5aac41107432d8fde4081c (diff)
downloadbionic-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.c4
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();
}
/*