about summary refs log tree commit diff
path: root/src/ldso
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-10-05 01:15:25 -0400
committerRich Felker <dalias@aerifal.cx>2012-10-05 01:15:25 -0400
commit642b7593c3b3488d229488a436bab294dcc27ee9 (patch)
tree485eb850b836f921c3a4582e2aff8ddf0b01881f /src/ldso
parent99a2af6f45b356324e99acf0da809ca416eed0de (diff)
downloadmusl-642b7593c3b3488d229488a436bab294dcc27ee9.tar.gz
musl-642b7593c3b3488d229488a436bab294dcc27ee9.tar.xz
musl-642b7593c3b3488d229488a436bab294dcc27ee9.zip
fix race condition in dlopen
orig_tail was being saved before the lock was obtained, allowing
dlopen failure to roll-back other dlopens that had succeeded.
Diffstat (limited to 'src/ldso')
-rw-r--r--src/ldso/dynlink.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index e09f0715..2bbd492a 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -886,7 +886,7 @@ void *__dynlink(int argc, char **argv)
 
 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;
 
@@ -895,6 +895,8 @@ void *dlopen(const char *file, int mode)
 	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++)