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? 2) How much of the observed glibc behavior should we try to emulate in uClibc? 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); } _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc