block all signals during rsyscall

otherwise a signal handler could see an inconsistent and nonconformant
program state where different threads have different uids/gids.
This commit is contained in:
Rich Felker 2011-04-03 13:15:42 -04:00
commit 66def4e776

View file

@ -85,7 +85,7 @@ static void rsyscall_handler(int sig, siginfo_t *si, void *ctx)
/* Threads which have already decremented themselves from the /* Threads which have already decremented themselves from the
* thread count must not increment rs.cnt or otherwise act. */ * thread count must not increment rs.cnt or otherwise act. */
if (self->dead) { if (self->dead) {
sigaddset(&((ucontext_t *)ctx)->uc_sigmask, SIGSYSCALL); sigfillset(&((ucontext_t *)ctx)->uc_sigmask);
return; return;
} }
@ -151,13 +151,18 @@ static void init_threads()
libc.lockfile = __lockfile; libc.lockfile = __lockfile;
libc.cancelpt = cancelpt; libc.cancelpt = cancelpt;
libc.rsyscall = rsyscall; libc.rsyscall = rsyscall;
sa.sa_sigaction = cancel_handler;
__libc_sigaction(SIGCANCEL, &sa, 0); sigfillset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGSYSCALL);
sigaddset(&sa.sa_mask, SIGCANCEL);
sa.sa_sigaction = rsyscall_handler; sa.sa_sigaction = rsyscall_handler;
__libc_sigaction(SIGSYSCALL, &sa, 0); __libc_sigaction(SIGSYSCALL, &sa, 0);
sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = cancel_handler;
__libc_sigaction(SIGCANCEL, &sa, 0);
sigaddset(&sa.sa_mask, SIGSYSCALL);
sigaddset(&sa.sa_mask, SIGCANCEL);
__libc_sigprocmask(SIG_UNBLOCK, &sa.sa_mask, 0);
} }
static int start(void *p) static int start(void *p)