nptl: Use SA_RESTART for SIGCANCEL handler

The usage of signals to implementation pthread cancellation is an
implementation detail and should not be visible through cancellation
entrypoints.

However now that pthread_cancel always send the SIGCANCEL, some
entrypoint might be interruptable and return EINTR to the caller
(for instance on sem_wait).

Using SA_RESTART hides this, since the cancellation handler should
either act uppon cancellation (if asynchronous cancellation is enable)
or ignore the cancellation internal signal.

Checked on x86_64-linux-gnu and i686-linux-gnu.
This commit is contained in:
Adhemerval Zanella 2021-06-17 09:45:03 -03:00
parent 03caacbc7f
commit bf6749a7f8
2 changed files with 13 additions and 1 deletions

8
NEWS
View File

@ -64,6 +64,14 @@ Deprecated and removed features, and other changes affecting compatibility:
* The function pthread_yield has been deprecated; programs should use
the equivalent standard function sched_yield instead.
* The pthread cancellation handler is now installed with SA_RESTART and
pthread_cancel will always send the internal SIGCANCEL on a cancellation
request. It should not be visible to application since the cancellation
handler should either act upon cancellation (if asynchronous cancellation
is enabled) or ignore the cancellation internal signal. However there are
buggy kernel interfaces (for instance some CIFS version) that could still
see spurious EINTR error when cancellation interrupts a blocking syscall.
Changes to build and runtime requirements:
* On Linux, the shm_open, sem_open, and related functions now expect the

View File

@ -72,7 +72,11 @@ __pthread_cancel (pthread_t th)
{
struct sigaction sa;
sa.sa_sigaction = sigcancel_handler;
sa.sa_flags = SA_SIGINFO;
/* The signal handle should be non-interruptible to avoid the risk of
spurious EINTR caused by SIGCANCEL sent to process or if
pthread_cancel() is called while cancellation is disabled in the
target thread. */
sa.sa_flags = SA_SIGINFO | SA_RESTART;
__sigemptyset (&sa.sa_mask);
__libc_sigaction (SIGCANCEL, &sa, NULL);
atomic_store_relaxed (&init_sigcancel, 1);