From 7024c3cc7928707a42ba3ef1bed2726cf15f0909 Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 10 Mar 2020 20:25:03 +0000 Subject: [PATCH] Fix signal delivery might be on sigfastblock clearing. When clearing sigfastblock, either by sigfastblock(UNSETPTR) call or implicitly on execve(2), kernel must check for pending signals and reschedule them if needed. E.g. on execve, all other threads are terminated, and current thread fast block pointer is cleaned. If any signal was left pending, it can now be delivered to the current thread, and we should prepare for ast() on return to userspace to notice the signals. Reported and tested by: pho Sponsored by: The FreeBSD Foundation --- sys/kern/kern_sig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 17126f2da624..0d597e559c8d 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -4107,7 +4107,8 @@ sigfastblock_clear(struct thread *td) if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) return; td->td_sigblock_val = 0; - resched = (td->td_pflags & TDP_SIGFASTPENDING) != 0; + resched = (td->td_pflags & TDP_SIGFASTPENDING) != 0 || + SIGPENDING(td); td->td_pflags &= ~(TDP_SIGFASTBLOCK | TDP_SIGFASTPENDING); if (resched) { p = td->td_proc;