diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2017-10-31 23:10:37 -0200 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2018-04-03 13:30:49 -0300 |
commit | d2dc5467c67bc8625a4fc8f285b6a5443bf43df4 (patch) | |
tree | 27ddabfd779bfcbcc92f095288be5778ec4370ca /nptl | |
parent | 511ed56f2e792bea5e7145e1d5d5c93b9f47c41f (diff) | |
download | glibc-d2dc5467c67bc8625a4fc8f285b6a5443bf43df4.zip glibc-d2dc5467c67bc8625a4fc8f285b6a5443bf43df4.tar.gz glibc-d2dc5467c67bc8625a4fc8f285b6a5443bf43df4.tar.bz2 |
Filter out NPTL internal signals (BZ #22391)
This patch filters out the internal NPTL signals (SIGCANCEL/SIGTIMER and
SIGSETXID) from signal functions. GLIBC on Linux requires both signals to
proper implement pthread cancellation, posix timers, and set*id posix
thread synchronization.
And not filtering out the internal signal is troublesome:
- A conformant program on a architecture that does not filter out the
signals might inadvertently disable pthread asynchronous cancellation,
set*id synchronization or posix timers.
- It might also to security issues if SIGSETXID is masked and set*id
functions are called (some threads might have effective user or group
id different from the rest).
The changes are basically:
- Change __is_internal_signal to bool and used on all signal function
that has a signal number as input. Also for signal function which accepts
signals sets (sigset_t) it assumes that canonical function were used to
add/remove signals which lead to some input simplification.
- Fix tst-sigset.c to avoid check for SIGCANCEL/SIGTIMER and SIGSETXID.
It is rewritten to check each signal indidually and to check realtime
signals using canonical macros.
- Add generic __clear_internal_signals and __is_internal_signal
version since both symbols are used on generic implementations.
- Remove superflous sysdeps/nptl/sigfillset.c.
- Remove superflous SIGTIMER handling on Linux __is_internal_signal
since it is the same of SIGCANCEL.
- Remove dangling define and obvious comment on nptl/sigaction.c.
Checked on x86_64-linux-gnu.
[BZ #22391]
* nptl/sigaction.c (__sigaction): Use __is_internal_signal to
check for internal nptl signals.
* nptl/sigaction.c (__sigaction): Likewise.
* signal/sigaddset.c (sigaddset): Likewise.
* signal/sigdelset.c (sigdelset): Likewise.
* sysdeps/posix/signal.c (__bsd_signal): Likewise.
* sysdeps/posix/sigset.c (sigset): Call and check sigaddset return
value.
* signal/sigfillset.c (sigfillset): User __clear_internal_signals
to filter out internal nptl signals.
* signal/tst-sigset.c (do_test): Check ech signal indidually and
also check realtime signals using standard macros.
* sysdeps/generic/internal-signals.h (__clear_internal_signals,
__is_internal_signal, __libc_signal_block_all,
__libc_signal_block_app, __libc_signal_restore_set): New functions.
* sysdeps/nptl/sigfillset.c: Remove file.
* sysdeps/unix/sysv/linux/internal-signals.h (__is_internal_signal):
Change return to bool.
(__clear_internal_signals): Remove SIGTIMER clean since it is
equal to SIGCANEL on Linux.
* sysdeps/unix/sysv/linux/sigtimedwait.c (__sigtimedwait): Assume
signal set was constructed using standard functions.
Reported-by: Yury Norov <ynorov@caviumnetworks.com>
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/sigaction.c | 14 |
1 files changed, 2 insertions, 12 deletions
diff --git a/nptl/sigaction.c b/nptl/sigaction.c index ddf6f5e..79b6fdc 100644 --- a/nptl/sigaction.c +++ b/nptl/sigaction.c @@ -16,22 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ - -/* This is no complete implementation. The file is meant to be - included in the real implementation to provide the wrapper around - __libc_sigaction. */ - -#include <nptl/pthreadP.h> - -/* We use the libc implementation but we tell it to not allow - SIGCANCEL or SIGTIMER to be handled. */ -#define LIBC_SIGACTION 1 - +#include <internal-signals.h> int __sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { - if (__glibc_unlikely (sig == SIGCANCEL || sig == SIGSETXID)) + if (sig <= 0 || sig >= NSIG || __is_internal_signal (sig)) { __set_errno (EINVAL); return -1; |