summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-02-07 20:31:27 -0500
committerRich Felker <dalias@aerifal.cx>2012-02-07 20:31:27 -0500
commitf2baf4d7b8be043b231ecf7fc611247196acd9f5 (patch)
treedde4a9752f44bfb4616be6eb270dc5e7133c5883 /src
parent700a8156adc5bfb3ddf9c92dab4ffd516df31958 (diff)
downloadmusl-f2baf4d7b8be043b231ecf7fc611247196acd9f5.tar.gz
protect against cancellation in dlopen
i'm not sure that it's "correct" for dlopen to block cancellation when calling constructors for libraries it loads, but it sure seems like the right thing. in any case, dlopen itself needs cancellation blocked.
Diffstat (limited to 'src')
-rw-r--r--src/ldso/dynlink.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index eda0046e..6ff8850c 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -610,9 +610,11 @@ void *dlopen(const char *file, int mode)
{
struct dso *volatile p, *orig_tail = tail, *next;
size_t i;
+ int cs;
if (!file) return head;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
pthread_rwlock_wrlock(&lock);
if (setjmp(rtld_fail)) {
@@ -628,8 +630,8 @@ void *dlopen(const char *file, int mode)
}
tail = orig_tail;
tail->next = 0;
- pthread_rwlock_unlock(&lock);
- return 0;
+ p = 0;
+ goto end;
}
p = load_library(file);
@@ -658,6 +660,7 @@ void *dlopen(const char *file, int mode)
do_init_fini(tail);
end:
pthread_rwlock_unlock(&lock);
+ pthread_setcancelstate(cs, 0);
return p;
}