diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-17 09:45:03 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-23 13:45:13 -0300 |
commit | bf6749a7f87c54e62db26b24c63b27004a110847 (patch) | |
tree | 9f847757df91f3ab89914c10dd00f9cc8e9c9154 | |
parent | 03caacbc7f3004ad21fc00bf883f00421a211130 (diff) | |
download | glibc-bf6749a7f87c54e62db26b24c63b27004a110847.tar.gz glibc-bf6749a7f87c54e62db26b24c63b27004a110847.tar.xz glibc-bf6749a7f87c54e62db26b24c63b27004a110847.zip |
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.
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | nptl/pthread_cancel.c | 6 |
2 files changed, 13 insertions, 1 deletions
diff --git a/NEWS b/NEWS index d64be288da..48d77d706f 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index 0698cd2046..cc25ff21f3 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -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); |