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> |
||
---|---|---|
.. | ||
asprintf_chk.c | ||
backtrace-tst.c | ||
backtrace.c | ||
backtracesyms.c | ||
backtracesymsfd.c | ||
chk_fail.c | ||
confstr_chk.c | ||
Depend | ||
dprintf_chk.c | ||
execinfo.h | ||
explicit_bzero_chk.c | ||
fdelt_chk.c | ||
fgets_chk.c | ||
fgets_u_chk.c | ||
fgetws_chk.c | ||
fgetws_u_chk.c | ||
fortify_fail.c | ||
fprintf_chk.c | ||
fread_chk.c | ||
fread_u_chk.c | ||
fwprintf_chk.c | ||
getcwd_chk.c | ||
getdomainname_chk.c | ||
getgroups_chk.c | ||
gethostname_chk.c | ||
gets_chk.c | ||
getwd_chk.c | ||
longjmp_chk.c | ||
Makefile | ||
mbsnrtowcs_chk.c | ||
mbsrtowcs_chk.c | ||
mbstowcs_chk.c | ||
memcpy_chk.c | ||
memmove_chk.c | ||
mempcpy_chk.c | ||
memset_chk.c | ||
noophooks.c | ||
obprintf_chk.c | ||
pcprofile.c | ||
pcprofiledump.c | ||
poll_chk.c | ||
ppoll_chk.c | ||
pread64_chk.c | ||
pread_chk.c | ||
printf_chk.c | ||
read_chk.c | ||
readlink_chk.c | ||
readlinkat_chk.c | ||
readonly-area.c | ||
realpath_chk.c | ||
recv_chk.c | ||
recvfrom_chk.c | ||
snprintf_chk.c | ||
sprintf_chk.c | ||
stack_chk_fail_local.c | ||
stack_chk_fail.c | ||
stpcpy_chk.c | ||
stpncpy_chk.c | ||
strcat_chk.c | ||
strcpy_chk.c | ||
strlcat_chk.c | ||
strlcpy_chk.c | ||
strncat_chk.c | ||
strncpy_chk.c | ||
swprintf_chk.c | ||
test-stpcpy_chk.c | ||
test-strcpy_chk.c | ||
tst-backtrace2.c | ||
tst-backtrace3.c | ||
tst-backtrace4.c | ||
tst-backtrace5.c | ||
tst-backtrace6.c | ||
tst-backtrace.h | ||
tst-chk-cancel.c | ||
tst-fortify-syslog.c | ||
tst-fortify-wide.c | ||
tst-fortify.c | ||
tst-longjmp_chk2.c | ||
tst-longjmp_chk3.c | ||
tst-longjmp_chk.c | ||
tst-realpath-chk.c | ||
tst-sprintf-fortify-rdonly.c | ||
tst-sprintf-fortify-unchecked.c | ||
tst-ssp-1.c | ||
ttyname_r_chk.c | ||
vasprintf_chk.c | ||
vdprintf_chk.c | ||
Versions | ||
vfprintf_chk.c | ||
vfwprintf_chk.c | ||
vobprintf_chk.c | ||
vprintf_chk.c | ||
vsnprintf_chk.c | ||
vsprintf_chk.c | ||
vswprintf_chk.c | ||
vwprintf_chk.c | ||
wcpcpy_chk.c | ||
wcpncpy_chk.c | ||
wcrtomb_chk.c | ||
wcscat_chk.c | ||
wcscpy_chk.c | ||
wcslcat_chk.c | ||
wcslcpy_chk.c | ||
wcsncat_chk.c | ||
wcsncpy_chk.c | ||
wcsnrtombs_chk.c | ||
wcsrtombs_chk.c | ||
wcstombs_chk.c | ||
wctomb_chk.c | ||
wmemcpy_chk.c | ||
wmemmove_chk.c | ||
wmempcpy_chk.c | ||
wmemset_chk.c | ||
wprintf_chk.c | ||
xtrace.sh |