[PATCH/RFC future] nptl: reinstate SIGCANCEL/SIGSETXID safeguards
Peter Mazinger
ps.m at gmx.net
Tue May 10 21:06:40 UTC 2011
Hi,
> Couple more data points to muddy the waters:
>
> x86 glibc 2.11.1 (same result for -pthread and non -pthread):
>
> sigfillset refused to set: 32 (Unknown signal 32)
> sigfillset refused to set: 33 (Unknown signal 33)
> sigprocmask refused to mask: 9 (Killed)
> sigprocmask refused to mask: 19 (Stopped (signal))
> sending SIGINT
> sending SIGQUIT
> caught sig 3 (Quit)
>
> MIPS uClibc 0.9.32-rc3 unpatched, built with -pthread:
>
> sigfillset refused to set: 32 (Unknown signal 32)
> sigfillset refused to set: 33 (Unknown signal 33)
> sigprocmask refused to mask: 9 (Killed)
> sigprocmask refused to mask: 23 (Stopped (signal))
> sigprocmask refused to mask: 32 (Unknown signal 32)
> sigprocmask refused to mask: 33 (Unknown signal 33)
> sending SIGINT
> sending SIGQUIT
> caught sig 3 (Quit)
>
> MIPS uClibc 0.9.32-rc3 unpatched, built without -pthread:
>
> sigprocmask refused to mask: 9 (Killed)
> sigprocmask refused to mask: 23 (Stopped (signal))
> sending SIGINT
> sending SIGQUIT
> caught sig 3 (Quit)
>
> MIPS uClibc 0.9.32-rc3 with Austin's patch + my patch (same result for
> -pthread and non -pthread):
>
> sigfillset refused to set: 32 (Unknown signal 32)
> sigfillset refused to set: 33 (Unknown signal 33)
> sigprocmask refused to mask: 9 (Killed)
> sigprocmask refused to mask: 23 (Stopped (signal))
> sigprocmask refused to mask: 32 (Unknown signal 32)
> sigprocmask refused to mask: 33 (Unknown signal 33)
> sending SIGINT
> sending SIGQUIT
> caught sig 3 (Quit)
>
>
> glibc has two sigprocmask implementations:
>
> ./sysdeps/unix/sysv/linux/sigprocmask.c - this has the same SIGCANCEL
> and SIGSETXID code as uClibc but does not include pthreadP.h, so the
> extra checks remain inactive.
>
> ./nptl/sysdeps/pthread/sigprocmask.c is just:
>
> #include <nptl/pthreadP.h>
> #include <sysdeps/unix/sysv/linux/sigprocmask.c>
>
> So the latter implementation will refuse to mask SIGCANCEL +
> SIGSETXID. But the former implementation gets built into libc, and
> the latter implementation never gets built. Therefore glibc
> sigprocmask() does NOT block tampering with SIGCANCEL/SIGSETXID.
>
>
> glibc also has two sigfillset implementations:
>
> ./signal/sigfillset.c - this has the same SIGCANCEL and SIGSETXID code
> as uClibc but does not include pthreadP.h, so the extra checks remain
> inactive.
>
> ./nptl/sysdeps/pthread/sigfillset.c is just:
>
> #include <nptl/pthreadP.h>
> #include <signal/sigfillset.c>
>
> So the latter implementation will refuse to mask SIGCANCEL +
> SIGSETXID. The latter implementation gets built into libc, and the
> former implementation never gets built by itself. Therefore glibc
> sigfillset() DOES avoid setting bits for SIGCANCEL/SIGSETXID.
>
>
> I am left wondering:
>
> 1) How much of the observed glibc behavior is the result of an
> explicit design decision? Or did it wind up working this way by
> accident?
no comment ;-)
> 2) How much of the observed glibc behavior should we try to emulate in
> uClibc?
I am for only one implementation (that should go only into libc), else you have unpredictable/different results depending on which linking order you choose libc/libpthread
Peter
>
>
> Updated test program:
>
> -- 8< --
>
> #include <signal.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <string.h>
>
> void fn(int sig, siginfo_t *si, void *vctx)
> {
> printf("caught sig %d (%s)\n", sig, strsignal(sig));
> exit(0);
> }
>
> int main(int argc, char **argv)
> {
> sigset_t s, old;
> struct sigaction sa, sa_old;
> int i;
>
> /* see if sigfillset/sigaddset/sigprocmask skip certain signals */
>
> sigfillset(&s);
> for (i = 1; i <= SIGRTMAX; i++)
> if (!sigismember(&s, i))
> printf("sigfillset refused to set: %d (%s)\n",
> i, strsignal(i));
>
> /* try to fill in the holes left by sigfillset() */
> for (i = 1; i <= SIGRTMAX; i++) {
> sigaddset(&s, i);
> if (!sigismember(&s, i))
> printf("sigaddset refused to set: %d (%s)\n",
> i, strsignal(i));
> }
> sigprocmask(SIG_BLOCK, &s, &old);
> sigprocmask(SIG_BLOCK, NULL, &s);
> for (i = 1; i <= SIGRTMAX; i++) {
> if (!sigismember(&s, i))
> printf("sigprocmask refused to mask: %d (%s)\n",
> i, strsignal(i));
> }
>
> /* send ourselves a signal to see if sigaction works properly */
>
> sigfillset(&s);
> sigdelset(&s, SIGQUIT);
> sigprocmask(SIG_SETMASK, &s, &old);
>
> memset(&sa, 0, sizeof(sa));
> sa.sa_sigaction = fn;
> sa.sa_flags = SA_SIGINFO;
> sigaction(SIGQUIT, &sa, &sa_old);
>
> printf("sending SIGINT\n");
> usleep(100000);
> kill(0, SIGINT);
> usleep(100000);
>
> printf("sending SIGQUIT\n");
> usleep(100000);
> kill(0, SIGQUIT);
> usleep(100000);
>
> printf("failed to catch SIGQUIT\n");
> exit(1);
> }
--
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de
More information about the uClibc
mailing list