diff options
author | Rich Felker <dalias@aerifal.cx> | 2013-06-29 02:24:02 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2013-06-29 02:24:02 -0400 |
commit | 509b50eda8ea7d4a28f738e4cf8ea98d25959f00 (patch) | |
tree | 1f042d8cb5c8cc228dc55e54f36d26a94fcac442 | |
parent | 17aef0b41e3d7cb37c476cbe2df26fc444518a64 (diff) | |
download | musl-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.c | 4 |
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); } |