From: Alan Cox Date: Thu, 5 Oct 2017 23:06:06 +0000 (+0100) Subject: kernel: fix signal race X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5294216520f10041a55bfdb7f5e97f866e2ca359;p=FUZIX.git kernel: fix signal race Without this we can have the following occur kill(pid, foo) queues signal processing for foo signal(SIGFOO, SIG_IGN) executes pending signal and jumps to lala land --- diff --git a/Kernel/TODO.md b/Kernel/TODO.md index d5958715..ce1014fc 100644 --- a/Kernel/TODO.md +++ b/Kernel/TODO.md @@ -86,8 +86,10 @@ Other ----- - [IP] Check safety of changes to allow interrupts during swapper -- [ ] Check we don't have any races of the form +- [x] Check we don't have any races of the form kill() checks signal has handler signal(x, SIG_DFL) signal serviced + + (We now clear the cached signal in this and the mask case) diff --git a/Kernel/syscall_proc.c b/Kernel/syscall_proc.c index eb37a1b1..47fd9792 100644 --- a/Kernel/syscall_proc.c +++ b/Kernel/syscall_proc.c @@ -476,8 +476,10 @@ arg_t _signal(void) retval = (arg_t) udata.u_sigvec[sig]; if (sig != SIGKILL && sig != SIGSTOP) udata.u_sigvec[sig] = func; + /* Force recalculation of signal pending in the syscall return path */ + udata.u_cursig = 0; irqrestore(irq); - + return (retval); nogood: @@ -506,6 +508,8 @@ arg_t _sigdisp(void) udata.u_ptab->p_held |= sigmask(sig); else udata.u_ptab->p_held &= ~sigmask(sig); + /* Force recalculation of signal pending in the syscall return path */ + udata.u_cursig = 0; return 0; }