PCTS tests for sigprocmask() have uncovered a defect in the way signal masks are managed. The test-case below specifically provides an "invalid" *how* argument and expects the resulting signal mask to NOT change. But upon execution of the code below, the signal mask *is* modified. Cristian Gafton has analyzed this and concurs about it being a kernel bug. [snip] #include <stdio.h> #include <signal.h> #include <errno.h> #define INVALID_HOW (SIG_SETMASK + SIG_BLOCK + SIG_UNBLOCK) main() { int pid, x; sigset_t set, oset; void dumpset(); printf("**** Start *****\n"); sigemptyset(&set); sigemptyset(&oset); dumpset(set, " set"); dumpset(oset, "oset"); printf("\nCalling sigprocmask(SIG_SETMASK, &set, &oset)\n"); x = sigprocmask(SIG_SETMASK, &set, &oset); printf("sigprocmask(SIG_SETMASK) returns %d, errno %d\n", x, errno); if (errno) perror("sigprocmask"); dumpset(set, " set"); dumpset(oset, "oset"); printf("\t... adding SIGHUP to signal set\n"); sigaddset(&set, SIGHUP); dumpset(set, " set"); printf("\nCalling sigprocmask(INVALID_HOW, &set, &oset)\n"); x = sigprocmask(INVALID_HOW, &set, &oset); printf("sigprocmask returns %d, errno %d\n", x, errno); if (errno) perror("sigprocmask"); dumpset(set, " set"); dumpset(oset, "oset"); sigprocmask(SIG_SETMASK, (sigset_t *)0, &oset); if (sigismember(&oset, SIGHUP)) printf("\n\t\tOOPS: signal mask altered!\n\n"); exit(0); } char *n; { int i = 0, *ip = (int *) &s; printf("%s = ", n); while (i < sizeof(s) / sizeof(int)) { /*printf("[0x%08x]", *ip++);*/ printf("%1d", *ip++); if (++i % 105 == 0) printf("\n"); } printf("\n"); return; } void dumpset(s, n) sigset_t s; dumpset(set, " set");
Created attachment 42 [details] Proposed patch for sigprocmask(2) defect
Assigned to dledford
This should be ok since 2.2.14 kernels (6.2)