fix race condition in dlopen
authorRich Felker <dalias@aerifal.cx>
Fri, 5 Oct 2012 05:15:25 +0000 (01:15 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 5 Oct 2012 05:15:25 +0000 (01:15 -0400)
orig_tail was being saved before the lock was obtained, allowing
dlopen failure to roll-back other dlopens that had succeeded.

src/ldso/dynlink.c

index e09f071..2bbd492 100644 (file)
@@ -886,7 +886,7 @@ void *__dynlink(int argc, char **argv)
 
 void *dlopen(const char *file, int mode)
 {
 
 void *dlopen(const char *file, int mode)
 {
-       struct dso *volatile p, *orig_tail = tail, *next;
+       struct dso *volatile p, *orig_tail, *next;
        size_t i;
        int cs;
 
        size_t i;
        int cs;
 
@@ -895,6 +895,8 @@ void *dlopen(const char *file, int mode)
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
        pthread_rwlock_wrlock(&lock);
 
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
        pthread_rwlock_wrlock(&lock);
 
+       orig_tail = tail;
+
        if (setjmp(rtld_fail)) {
                /* Clean up anything new that was (partially) loaded */
                if (p->deps) for (i=0; p->deps[i]; i++)
        if (setjmp(rtld_fail)) {
                /* Clean up anything new that was (partially) loaded */
                if (p->deps) for (i=0; p->deps[i]; i++)