From 5294216520f10041a55bfdb7f5e97f866e2ca359 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 6 Oct 2017 00:06:06 +0100 Subject: [PATCH] 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 --- Kernel/TODO.md | 4 +++- Kernel/syscall_proc.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) 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; } -- 2.34.1