[0/2] Make abort AS-safe

Message ID 20230731171900.4065501-1-adhemerval.zanella@linaro.org
Headers
Series Make abort AS-safe |

Message

Adhemerval Zanella Netto July 31, 2023, 5:18 p.m. UTC
  Besides POSIX stating abort should be AS-safe, Rust also had an
open PR about it [1] (it was closed with a different fix). 

The main issue is the recursive lock used on abort does not
synchronize with 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 raising SIGABRT might create
a new process with a non-expected signal mask.

To fix the AS-safe, the raise is issued without changing the process
signal mask, and an AS-safe lock is used if a SIGABRT is installed or
the process is blocked or ignored.  The the signal mask change removal,
there is no need to use a recursive lock.  The lock is also used on
both _Fork and posix_spawn, to avoid the spawn process to see the
abort handler as SIG_DFL.

The clone is also subjected to this issue, but since glibc does not
do any internal metadata setup (as for fork-like function), this patch
does not handle it for the symbol.

I have not added a regression tests because, from previous Carlos's
patch [2], hitting the code path to trigger the potential issue
(fork just after abort has acquired the lock and reset SIGABRT handler)
is not deterministic and it would generate a lot of development
overhead.

[1] https://github.com/rust-lang/rust/issues/73894#issuecomment-673478761
[2] https://sourceware.org/pipermail/libc-alpha/2020-September/117934.html

Adhemerval Zanella (2):
  setjmp: Use BSD sematic as default for setjmp
  stdlib: Make abort AS-safe (BZ 26275)

 include/stdlib.h                           |   4 +
 manual/setjmp.texi                         |  14 +--
 manual/startup.texi                        |   3 -
 nptl/pthread_create.c                      |   3 +-
 nptl/pthread_kill.c                        |  11 ++
 posix/fork.c                               |   2 +
 setjmp/setjmp.h                            |   5 -
 signal/sigaction.c                         |  21 +++-
 stdlib/abort.c                             | 128 ++++++++-------------
 sysdeps/generic/internal-signals.h         |  24 ++++
 sysdeps/htl/pthreadP.h                     |   2 +
 sysdeps/nptl/_Fork.c                       |  12 ++
 sysdeps/nptl/libc_start_call_main.h        |   3 +-
 sysdeps/nptl/pthreadP.h                    |   1 +
 sysdeps/unix/sysv/linux/internal-signals.h |   9 ++
 sysdeps/unix/sysv/linux/spawni.c           |   3 +
 16 files changed, 140 insertions(+), 105 deletions(-)