Kees Cook <keescook@xxxxxxxxxxxx> writes: > On Mon, Nov 15, 2021 at 11:32:50PM -0600, Eric W. Biederman wrote: >> >> Recently while investigating a problem with rr and signals I noticed >> that siglock is dropped in ptrace_signal and get_signal does not jump >> to relock. >> >> Looking farther to see if the problem is anywhere else I see that >> do_signal_stop also returns if signal_group_exit is true. I believe >> that test can now never be true, but it is a bit hard to trace >> through and be certain. >> >> Testing signal_group_exit is not expensive, so move the test for >> signal_group_exit into the for loop inside of get_signal to ensure >> the test is never skipped improperly. > > Seems reasonable. > >> >> This has been a potential since I added the test for signal_group_exit > > nit: missing word after "potential"? "bug", "problem"? Yes. Potential problem. I will update the comment. >> was added. >> >> Fixes: 35634ffa1751 ("signal: Always notice exiting tasks") >> Signed-off-by: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> > > Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> > >> --- >> kernel/signal.c | 20 ++++++++++---------- >> 1 file changed, 10 insertions(+), 10 deletions(-) >> >> diff --git a/kernel/signal.c b/kernel/signal.c >> index 7c4b7ae714d4..986fa69c15c5 100644 >> --- a/kernel/signal.c >> +++ b/kernel/signal.c >> @@ -2662,19 +2662,19 @@ bool get_signal(struct ksignal *ksig) >> goto relock; >> } >> >> - /* Has this task already been marked for death? */ >> - if (signal_group_exit(signal)) { >> - ksig->info.si_signo = signr = SIGKILL; >> - sigdelset(¤t->pending.signal, SIGKILL); >> - trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, >> - &sighand->action[SIGKILL - 1]); >> - recalc_sigpending(); >> - goto fatal; >> - } >> - >> for (;;) { >> struct k_sigaction *ka; >> >> + /* Has this task already been marked for death? */ >> + if (signal_group_exit(signal)) { >> + ksig->info.si_signo = signr = SIGKILL; >> + sigdelset(¤t->pending.signal, SIGKILL); >> + trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, >> + &sighand->action[SIGKILL - 1]); >> + recalc_sigpending(); >> + goto fatal; >> + } >> + >> if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) && >> do_signal_stop(0)) >> goto relock; >> -- >> 2.20.1 >>