mirror of https://gitee.com/Nocallback/glibc.git
Browse Source
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>
hjl/pr23240/fw
13 changed files with 150 additions and 96 deletions
@ -1,43 +1,85 @@ |
|||
/* Test sig*set functions. */ |
|||
|
|||
#include <signal.h> |
|||
#include <stdio.h> |
|||
|
|||
#define TEST_FUNCTION do_test () |
|||
#include <support/check.h> |
|||
|
|||
static int |
|||
do_test (void) |
|||
{ |
|||
int result = 0; |
|||
int sig = -1; |
|||
sigset_t set; |
|||
TEST_VERIFY (sigemptyset (&set) == 0); |
|||
|
|||
#define TRY(call) \ |
|||
if (call) \ |
|||
{ \ |
|||
printf ("%s (sig = %d): %m\n", #call, sig); \ |
|||
result = 1; \ |
|||
} \ |
|||
else |
|||
#define VERIFY(set, sig) \ |
|||
TEST_VERIFY (sigismember (&set, sig) == 0); \ |
|||
TEST_VERIFY (sigaddset (&set, sig) == 0); \ |
|||
TEST_VERIFY (sigismember (&set, sig) != 0); \ |
|||
TEST_VERIFY (sigdelset (&set, sig) == 0); \ |
|||
TEST_VERIFY (sigismember (&set, sig) == 0) |
|||
|
|||
/* ISO C99 signals. */ |
|||
VERIFY (set, SIGINT); |
|||
VERIFY (set, SIGILL); |
|||
VERIFY (set, SIGABRT); |
|||
VERIFY (set, SIGFPE); |
|||
VERIFY (set, SIGSEGV); |
|||
VERIFY (set, SIGTERM); |
|||
|
|||
sigset_t set; |
|||
TRY (sigemptyset (&set) != 0); |
|||
/* Historical signals specified by POSIX. */ |
|||
VERIFY (set, SIGHUP); |
|||
VERIFY (set, SIGQUIT); |
|||
VERIFY (set, SIGTRAP); |
|||
VERIFY (set, SIGKILL); |
|||
VERIFY (set, SIGBUS); |
|||
VERIFY (set, SIGSYS); |
|||
VERIFY (set, SIGPIPE); |
|||
VERIFY (set, SIGALRM); |
|||
|
|||
/* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */ |
|||
VERIFY (set, SIGURG); |
|||
VERIFY (set, SIGSTOP); |
|||
VERIFY (set, SIGTSTP); |
|||
VERIFY (set, SIGCONT); |
|||
VERIFY (set, SIGCHLD); |
|||
VERIFY (set, SIGTTIN); |
|||
VERIFY (set, SIGTTOU); |
|||
VERIFY (set, SIGPOLL); |
|||
VERIFY (set, SIGXCPU); |
|||
VERIFY (set, SIGXFSZ); |
|||
VERIFY (set, SIGVTALRM); |
|||
VERIFY (set, SIGPROF); |
|||
VERIFY (set, SIGUSR1); |
|||
VERIFY (set, SIGUSR2); |
|||
|
|||
/* Nonstandard signals found in all modern POSIX systems
|
|||
(including both BSD and Linux). */ |
|||
VERIFY (set, SIGWINCH); |
|||
|
|||
#ifdef SIGRTMAX |
|||
int max_sig = SIGRTMAX; |
|||
#else |
|||
int max_sig = NSIG - 1; |
|||
/* Arch-specific signals. */ |
|||
#ifdef SIGEMT |
|||
VERIFY (set, SIGEMT); |
|||
#endif |
|||
#ifdef SIGLOST |
|||
VERIFY (set, SIGLOST); |
|||
#endif |
|||
#ifdef SIGINFO |
|||
VERIFY (set, SIGINFO); |
|||
#endif |
|||
#ifdef SIGSTKFLT |
|||
VERIFY (set, SIGSTKFLT); |
|||
#endif |
|||
#ifdef SIGPWR |
|||
VERIFY (set, SIGPWR); |
|||
#endif |
|||
|
|||
for (sig = 1; sig <= max_sig; ++sig) |
|||
/* Read-time signals (POSIX.1b real-time extensions). If they are
|
|||
supported SIGRTMAX value is greater than SIGRTMIN. */ |
|||
for (int rtsig = SIGRTMIN; rtsig <= SIGRTMAX; rtsig++) |
|||
{ |
|||
TRY (sigismember (&set, sig) != 0); |
|||
TRY (sigaddset (&set, sig) != 0); |
|||
TRY (sigismember (&set, sig) == 0); |
|||
TRY (sigdelset (&set, sig) != 0); |
|||
TRY (sigismember (&set, sig) != 0); |
|||
VERIFY (set, rtsig); |
|||
} |
|||
|
|||
return result; |
|||
return 0; |
|||
} |
|||
|
|||
#include "../test-skeleton.c" |
|||
#include <support/test-driver.c> |
|||
|
|||
@ -1,20 +0,0 @@ |
|||
/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
|||
This file is part of the GNU C Library. |
|||
|
|||
The GNU C Library is free software; you can redistribute it and/or |
|||
modify it under the terms of the GNU Lesser General Public |
|||
License as published by the Free Software Foundation; either |
|||
version 2.1 of the License, or (at your option) any later version. |
|||
|
|||
The GNU C Library is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|||
Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public |
|||
License along with the GNU C Library; if not, see |
|||
<http://www.gnu.org/licenses/>. */
|
|||
|
|||
#include <nptl/pthreadP.h> |
|||
|
|||
#include <signal/sigfillset.c> |
|||
Loading…
Reference in new issue