mirror of
git://sourceware.org/git/glibc.git
synced 2024-12-09 04:11:27 +08:00
d2dc5467c6
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>
86 lines
1.9 KiB
C
86 lines
1.9 KiB
C
/* Test sig*set functions. */
|
|
|
|
#include <signal.h>
|
|
|
|
#include <support/check.h>
|
|
|
|
static int
|
|
do_test (void)
|
|
{
|
|
sigset_t set;
|
|
TEST_VERIFY (sigemptyset (&set) == 0);
|
|
|
|
#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);
|
|
|
|
/* 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);
|
|
|
|
/* 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
|
|
|
|
/* 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++)
|
|
{
|
|
VERIFY (set, rtsig);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#include <support/test-driver.c>
|