mirror of git://sourceware.org/git/glibc.git
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.h | ||
| atomic_wide_counter.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.h | ||
| getopt_int.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.h | ||
| list_t.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.h | ||
| nss_dns.h | ||
| nss_files.h | ||
| nsswitch.h | ||
| obstack.h | ||
| plural-exp.h | ||
| poll.h | ||
| printf.h | ||
| printf_buffer.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.h | ||
| stdio_ext.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.h | ||
| unistd_ext.h | ||
| utime.h | ||
| utmp.h | ||
| values.h | ||
| verify.h | ||
| wait.h | ||
| wchar.h | ||
| wctype.h | ||
| wordexp.h | ||