summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-06-29 02:24:02 -0400
committerRich Felker <dalias@aerifal.cx>2013-06-29 02:24:02 -0400
commit509b50eda8ea7d4a28f738e4cf8ea98d25959f00 (patch)
tree1f042d8cb5c8cc228dc55e54f36d26a94fcac442
parent17aef0b41e3d7cb37c476cbe2df26fc444518a64 (diff)
downloadmusl-509b50eda8ea7d4a28f738e4cf8ea98d25959f00.tar.gz
musl-509b50eda8ea7d4a28f738e4cf8ea98d25959f00.tar.bz2
musl-509b50eda8ea7d4a28f738e4cf8ea98d25959f00.tar.xz
musl-509b50eda8ea7d4a28f738e4cf8ea98d25959f00.zip
fix missing synchronization in calls from dynamic linker to global ctors
this change is needed to correctly handle the case where a constructor creates a new thread which calls dlopen. previously, the lock was not held in this case. the reason for the complex logic to avoid locking whenever possible is that, since the mutex is recursive, it will need to inspect the thread pointer to get the current thread's tid, and this requires initializing the thread pointer. we do not want non-multi-threaded programs to attempt to access the thread pointer unnecessarily; doing so could make them crash on ancient kernels that don't support threads but which may otherwise be capable of running the program.
-rw-r--r--src/ldso/dynlink.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index d1974736..ac4b669f 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -692,6 +692,10 @@ static void do_init_fini(struct dso *p)
}
if (dyn[0] & (1<<DT_INIT))
((void (*)(void))(p->base + dyn[DT_INIT]))();
+ if (!need_locking && libc.threads_minus_1) {
+ need_locking = 1;
+ pthread_mutex_lock(&init_fini_lock);
+ }
}
if (need_locking) pthread_mutex_unlock(&init_fini_lock);
}