mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
d40ac01cbb
The recursive lock used on abort does not synchronize with a new process creation (either by fork-like interfaces or posix_spawn ones), nor it is reinitialized after fork(). Also, the SIGABRT unblock before raise() shows another race condition, where a fork or posix_spawn() call by another thread, just after the recursive lock release and before the SIGABRT signal, might create programs with a non-expected signal mask. With the default option (without POSIX_SPAWN_SETSIGDEF), the process can see SIG_DFL for SIGABRT, where it should be SIG_IGN. To fix the AS-safe, raise() does not change the process signal mask, and an AS-safe lock is used if a SIGABRT is installed or the process is blocked or ignored. With the signal mask change removal, there is no need to use a recursive loc. The lock is also taken on both _Fork() and posix_spawn(), to avoid the spawn process to see the abort handler as SIG_DFL. A read-write lock is used to avoid serialize _Fork and posix_spawn execution. Both sigaction (SIGABRT) and abort() requires to lock as writer (since both change the disposition). The fallback is also simplified: there is no need to use a loop of ABORT_INSTRUCTION after _exit() (if the syscall does not terminate the process, the system is broken). The proposed fix changes how setjmp works on a SIGABRT handler, where glibc does not save the signal mask. So usage like the below will now always abort. static volatile int chk_fail_ok; static jmp_buf chk_fail_buf; static void handler (int sig) { if (chk_fail_ok) { chk_fail_ok = 0; longjmp (chk_fail_buf, 1); } else _exit (127); } [...] signal (SIGABRT, handler); [....] chk_fail_ok = 1; if (! setjmp (chk_fail_buf)) { // Something that can calls abort, like a failed fortify function. chk_fail_ok = 0; printf ("FAIL\n"); } Such cases will need to use sigsetjmp instead. The _dl_start_profile calls sigaction through _profil, and to avoid pulling abort() on loader the call is replaced with __libc_sigaction. Checked on x86_64-linux-gnu and aarch64-linux-gnu. Reviewed-by: DJ Delorie <dj@redhat.com> |
||
---|---|---|
.. | ||
arpa | ||
bits | ||
gnu | ||
net | ||
netinet | ||
programs | ||
protocols | ||
rpc | ||
rpcsvc | ||
sys | ||
aio.h | ||
aliases.h | ||
alloc_buffer.h | ||
alloca.h | ||
allocate_once.h | ||
ar.h | ||
argp-fmtstream.h | ||
argp.h | ||
argz.h | ||
array_length.h | ||
assert.h | ||
atomic_wide_counter.h | ||
atomic.h | ||
byteswap.h | ||
clone_internal.h | ||
complex.h | ||
cpio.h | ||
ctype.h | ||
des.h | ||
dirent.h | ||
dlfcn.h | ||
dso_handle.h | ||
elf.h | ||
endian.h | ||
envz.h | ||
err.h | ||
errno.h | ||
error.h | ||
execinfo.h | ||
fcntl.h | ||
features-time64.h | ||
features.h | ||
fenv.h | ||
file_change_detection.h | ||
filename.h | ||
float.h | ||
fmtmsg.h | ||
fnmatch.h | ||
fpu_control.h | ||
fstab.h | ||
fts.h | ||
ftw.h | ||
gconv.h | ||
getopt_int.h | ||
getopt.h | ||
glob.h | ||
gmp.h | ||
gnu-versions.h | ||
grp-merge.h | ||
grp.h | ||
gshadow.h | ||
iconv.h | ||
idx.h | ||
ifaddrs.h | ||
ifreq.h | ||
ifunc-impl-list.h | ||
inline-hashtab.h | ||
intprops.h | ||
inttypes.h | ||
langinfo.h | ||
lastlog.h | ||
libc-diag.h | ||
libc-internal.h | ||
libc-pointer-arith.h | ||
libc-symbols.h | ||
libgen.h | ||
libintl.h | ||
limits.h | ||
link.h | ||
list_t.h | ||
list.h | ||
locale.h | ||
loop_unroll.h | ||
malloc.h | ||
math-narrow-eval.h | ||
math.h | ||
mcheck.h | ||
memory.h | ||
mntent.h | ||
monetary.h | ||
mqueue.h | ||
netdb.h | ||
netgroup.h | ||
nl_types.h | ||
nss_dns.h | ||
nss_files.h | ||
nss.h | ||
nsswitch.h | ||
obstack.h | ||
plural-exp.h | ||
poll.h | ||
printf_buffer.h | ||
printf.h | ||
pthread.h | ||
pty.h | ||
pwd.h | ||
random-bits.h | ||
re_comp.h | ||
regex.h | ||
regexp.h | ||
register-atfork.h | ||
resolv.h | ||
rounding-mode.h | ||
rtld-malloc.h | ||
sched.h | ||
scratch_buffer.h | ||
search.h | ||
set-freeres.h | ||
setjmp.h | ||
sgtty.h | ||
shadow.h | ||
shlib-compat.h | ||
shm-directory.h | ||
signal.h | ||
spawn.h | ||
stab.h | ||
stackinfo.h | ||
stap-probe.h | ||
stdbit.h | ||
stdc-predef.h | ||
stdint.h | ||
stdio_ext.h | ||
stdio.h | ||
stdlib.h | ||
string.h | ||
strings.h | ||
struct___timeb64.h | ||
struct___timespec64.h | ||
struct___timeval64.h | ||
stubs-prologue.h | ||
syscall.h | ||
sysexits.h | ||
syslog.h | ||
tar.h | ||
termios.h | ||
tgmath.h | ||
time.h | ||
ttyent.h | ||
uchar.h | ||
ucontext.h | ||
ulimit.h | ||
unistd_ext.h | ||
unistd.h | ||
utime.h | ||
utmp.h | ||
values.h | ||
verify.h | ||
wait.h | ||
wchar.h | ||
wctype.h | ||
wordexp.h |