b88a8d3d1d
Obtaining compat rtld lock in write mode sets process signal mask to block all signals. Previous mask is stored in the global variable oldsigmask. If a lock is write-locked while another lock is already write-locked, oldsigmask is overwritten by the total mask and on the last unlock, all signals except traps appear to be blocked. Fix this by counting the write-lock nested level, and only storing to oldsigmask/restoring from it at the outermost level. Masking signals disables involuntary preemption for libc_r, and there could be no voluntary context switches in the locked code (dl_iterate_phdr(3) keeps a lock around user callback, but it was added long after libc_r was renounced). Due to this, remembering the level in the global variable after the lock is obtained should be safe, because no two libc_r threads can acquire different write locks in parallel. PR: 215826 Reported by: kami Tested by: yamagi@yamagi.org (previous version) To be reviewed by: kan Sponsored by: The FreeBSD Foundation MFC after: 2 weeks |
||
---|---|---|
.. | ||
aarch64 | ||
amd64 | ||
arm | ||
i386 | ||
mips | ||
powerpc | ||
powerpc64 | ||
riscv | ||
sparc64 | ||
tests | ||
debug.c | ||
debug.h | ||
libmap.c | ||
libmap.h | ||
Makefile | ||
Makefile.depend | ||
malloc.c | ||
map_object.c | ||
paths.h | ||
rtld_lock.c | ||
rtld_lock.h | ||
rtld_printf.c | ||
rtld_printf.h | ||
rtld_tls.h | ||
rtld_utrace.h | ||
rtld.1 | ||
rtld.c | ||
rtld.h | ||
Symbol.map | ||
xmalloc.c |