glibc/posix
Adhemerval Zanella d40ac01cbb stdlib: Make abort/_Exit AS-safe (BZ 26275)
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>
2024-10-08 14:40:12 -03:00
..
bits unistd: Improve fortify with clang 2024-02-27 10:52:58 -03:00
bug-ga2.root/etc
rxspencer
sys Always define __USE_TIME_BITS64 when 64 bit time_t is used 2024-04-02 15:28:36 -03:00
_exit.c
_Fork.c
alarm.c
annexc.c
BOOST.tests
bsd-getpgrp.c
bug-ga1.c
bug-ga2.c
bug-getopt1.c
bug-getopt2.c
bug-getopt3.c
bug-getopt4.c
bug-getopt5.c
bug-glob2.c
bug-glob3.c
bug-regex1.c
bug-regex2.c
bug-regex3.c
bug-regex4.c
bug-regex5.c
bug-regex6.c
bug-regex7.c
bug-regex8.c
bug-regex9.c
bug-regex10.c
bug-regex11.c
bug-regex12.c
bug-regex13.c
bug-regex14.c
bug-regex15.c
bug-regex16.c
bug-regex17.c
bug-regex18.c
bug-regex19.c
bug-regex20.c
bug-regex21.c
bug-regex22.c
bug-regex23.c
bug-regex24.c
bug-regex25.c
bug-regex26.c
bug-regex27.c
bug-regex28.c
bug-regex29.c
bug-regex30.c
bug-regex31.c
bug-regex31.input
bug-regex32.c
bug-regex33.c
bug-regex34.c
bug-regex35.c
bug-regex36.c
bug-regex37.c
bug-regex38.c
confstr.c
cpio.h
Depend
environ.c
execl.c
execle.c
execlp.c
execv.c
execve.c
execveat.c
execvp.c
execvpe.c
fexecve.c
flexmember.h
fnmatch_loop.c
fnmatch.c
fnmatch.h
fork.c stdlib: Make abort/_Exit AS-safe (BZ 26275) 2024-10-08 14:40:12 -03:00
fpathconf.c
gai_strerror.c
gai.conf
get_child_max.c
getconf-speclist.c
getconf.c getconf: Add NPROCESSORS_{CONF,ONLN} [BZ #31661] 2024-06-05 14:57:54 +02:00
getegid.c
geteuid.c
getgid.c
getgroups.c
getopt1.c
getopt_int.h
getopt.c
getopt.h
getpgid.c
getpgrp.c
getpid.c
getppid.c
getresgid.c
getresuid.c
getsid.c
getuid.c
glob64-lstat-compat.c
glob64-time64.c
glob64.c
glob_internal.h
glob_pattern_p.c
glob-lstat-compat.c
glob.c
glob.h Always define __USE_TIME_BITS64 when 64 bit time_t is used 2024-04-02 15:28:36 -03:00
globfree64-time64.c
globfree64.c
globfree.c
globtest.c
globtest.sh
group_member.c
init-posix.c
Makefile Fix conditionals on mtrace-based tests (bug 31892) 2024-07-01 17:20:30 +02:00
nanosleep.c
pathconf.c
pause.c
PCRE.tests
posix_madvise.c
posix-conf-vars.h
posix-conf-vars.list
posix-envs.def
pread64.c
pread.c
PTESTS
PTESTS2C.sed
pwrite64.c
pwrite.c
re_comp.h
regcomp.c
regex_internal.c
regex_internal.h
regex.c Omit regex.c pragmas no longer needed 2024-01-01 10:53:40 -08:00
regex.h
regexbug1.c
regexec.c
register-atfork.c
runptests.c
runtests.c
sched_cpualloc.c
sched_cpucount.c
sched_cpufree.c
sched_getaffinity.c
sched_getp.c
sched_gets.c
sched_primax.c
sched_primin.c
sched_rr_gi.c
sched_setaffinity.c
sched_setp.c
sched_sets.c
sched_yield.c
sched.h Always define __USE_TIME_BITS64 when 64 bit time_t is used 2024-04-02 15:28:36 -03:00
setgid.c
setgroups.c
setpgid.c
setpgrp.c
setresgid.c
setresuid.c
setsid.c
setuid.c
shm-directory.c
sleep.c
spawn_faction_addchdir.c
spawn_faction_addclose.c
spawn_faction_addclosefrom.c
spawn_faction_adddup2.c
spawn_faction_addfchdir.c
spawn_faction_addopen.c
spawn_faction_addtcsetpgrp_np.c
spawn_faction_destroy.c
spawn_faction_init.c
spawn_int.h
spawn_valid_fd.c
spawn.c
spawn.h
spawnattr_destroy.c
spawnattr_getdefault.c
spawnattr_getflags.c
spawnattr_getpgroup.c
spawnattr_getschedparam.c
spawnattr_getschedpolicy.c
spawnattr_getsigmask.c
spawnattr_init.c
spawnattr_setdefault.c
spawnattr_setflags.c
spawnattr_setpgroup.c
spawnattr_setschedparam.c
spawnattr_setschedpolicy.c
spawnattr_setsigmask.c
spawni.c
spawnp.c
streams-compat.c
sysconf.c
tar.h
test-errno.c
test-ssize-max.c
test-vfork.c
testfnm.c
TESTS
TESTS2C.sed
times.c
transbug.c
tst-_Fork.c
tst-boost.c
tst-chmod.c
tst-cpucount.c
tst-cpuset.c
tst-dir.c
tst-exec-static.c
tst-exec.c
tst-execl1.c
tst-execl2.c
tst-execle1.c
tst-execle2.c
tst-execlp1.c
tst-execlp2.c
tst-execv1.c
tst-execv2.c
tst-execve1.c
tst-execve2.c
tst-execveat.c support: Use macros for *stat wrappers 2024-08-16 16:05:20 +02:00
tst-execvp1.c
tst-execvp2.c
tst-execvp3.c
tst-execvp4.c
tst-execvpe1.c
tst-execvpe2.c
tst-execvpe3.c
tst-execvpe4.c
tst-execvpe5.c
tst-execvpe6.c
tst-fexecve.c
tst-fnmatch2.c
tst-fnmatch3.c
tst-fnmatch4.c
tst-fnmatch5.c
tst-fnmatch6.c
tst-fnmatch7.c
tst-fnmatch.c
tst-fnmatch.input
tst-fork.c
tst-gai_strerror.c
tst-getconf.sh Extend tst-getconf.sh test with NPROCESSORS_CONF and NPROCESSORS_ONLN 2024-06-17 14:18:16 +02:00
tst-getopt_long1.c
tst-getopt-cancel.c
tst-glob_lstat_compat.c
tst-glob_symlinks.c
tst-glob-tilde.c
tst-gnuglob64-time64.c
tst-gnuglob64.c
tst-gnuglob-skeleton.c
tst-gnuglob.c
tst-mmap-offset.c
tst-mmap.c
tst-nanosleep.c
tst-nice.c
tst-pathconf.c
tst-pcre.c
tst-posix_fadvise64.c
tst-posix_fadvise-common.c
tst-posix_fadvise.c
tst-posix_spawn-fd.c
tst-posix_spawn-setsid.c
tst-preadwrite64.c
tst-preadwrite-common.c
tst-preadwrite.c
tst-regcomp-truncated.c
tst-regex2.c
tst-regex.c
tst-regex.input
tst-regexloc.c
tst-rxspencer-no-utf8.c
tst-rxspencer.c
tst-sched_getaffinity.c
tst-sched_rr_get_interval-time64.c
tst-sched_rr_get_interval.c
tst-spawn2.c posix: Fix pidfd_spawn/pidfd_spawnp leak if execve fails (BZ 31695) 2024-06-25 12:11:48 -03:00
tst-spawn3.c
tst-spawn4-compat.c
tst-spawn4.c
tst-spawn5.c
tst-spawn6.c
tst-spawn7.c
tst-spawn-chdir.c
tst-spawn-static.c
tst-spawn.c
tst-spawn.h
tst-sysconf-empty-chroot.c
tst-sysconf.c
tst-truncate64.c
tst-truncate-common.c posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64 2024-07-26 13:21:34 +01:00
tst-truncate.c
tst-vfork1.c
tst-vfork2.c
tst-vfork3.c
tst-wait3-time64.c
tst-wait3.c
tst-wait4-time64.c
tst-wait4.c
tst-wait-skeleton.c
tst-waitid.c
tst-wordexp-nocmd.c
tstgetopt.c
uname-values.h
uname.c
unistd.h
Versions
vfork.c
wait3.c
wait4.c
wait.c
wait.h
waitid.c
waitpid.c
wordexp-test.c
wordexp-tst.sh
wordexp.c
wordexp.h