From: Matthew Dillon Date: Fri, 29 Jul 2011 08:19:29 +0000 (-0700) Subject: kernel - Fix signal delivery races X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/025d695a653d667f8d06e460e9e0e625ded69efb kernel - Fix signal delivery races * The send side was using p->p_token but the processing code from trap was still using the mp_lock. Fix the trap processing code to use p->p_token. * This fixes several nasty races that can cause signals to be lost and vkernels to freeze, and possibly other programs which depend on signals between threads. --- diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index d82b1a9a49..e5651b84e6 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1916,6 +1916,8 @@ issignal(struct lwp *lp, int maytrace) /* * Take the action for the specified signal * from the current set of pending signals. + * + * Caller must hold p->p_token */ void postsig(int sig) diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c index 96b8af2bd0..0432e5495b 100644 --- a/sys/platform/pc32/i386/trap.c +++ b/sys/platform/pc32/i386/trap.c @@ -273,10 +273,10 @@ recheck: * to restore the virtual kernel's vmspace before posting the upcall. */ if (p->p_flag & P_UPCALLPEND) { + lwkt_gettoken(&p->p_token); p->p_flag &= ~P_UPCALLPEND; - get_mplock(); postupcall(lp); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } @@ -287,9 +287,9 @@ recheck: * WARNING! postsig() can exit and not return. */ if ((sig = CURSIG_TRACE(lp)) != 0) { - get_mplock(); + lwkt_gettoken(&p->p_token); postsig(sig); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/pc64/x86_64/trap.c b/sys/platform/pc64/x86_64/trap.c index d22e5d40ce..e507758db0 100644 --- a/sys/platform/pc64/x86_64/trap.c +++ b/sys/platform/pc64/x86_64/trap.c @@ -237,10 +237,10 @@ recheck: * to restore the virtual kernel's vmspace before posting the upcall. */ if (p->p_flag & P_UPCALLPEND) { + lwkt_gettoken(&p->p_token); p->p_flag &= ~P_UPCALLPEND; - get_mplock(); postupcall(lp); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } @@ -251,9 +251,9 @@ recheck: * WARNING! postsig() can exit and not return. */ if ((sig = CURSIG_TRACE(lp)) != 0) { - get_mplock(); + lwkt_gettoken(&p->p_token); postsig(sig); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c index ff69ae1d73..fc025de5ed 100644 --- a/sys/platform/vkernel/i386/trap.c +++ b/sys/platform/vkernel/i386/trap.c @@ -247,10 +247,10 @@ recheck: * Post any pending upcalls */ if (p->p_flag & P_UPCALLPEND) { - get_mplock(); + lwkt_gettoken(&p->p_token); p->p_flag &= ~P_UPCALLPEND; postupcall(lp); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } @@ -260,9 +260,9 @@ recheck: * WARNING! postsig() can exit and not return. */ if ((sig = CURSIG_TRACE(lp)) != 0) { - get_mplock(); + lwkt_gettoken(&p->p_token); postsig(sig); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } diff --git a/sys/platform/vkernel64/x86_64/trap.c b/sys/platform/vkernel64/x86_64/trap.c index 874dfc553a..02227ba66c 100644 --- a/sys/platform/vkernel64/x86_64/trap.c +++ b/sys/platform/vkernel64/x86_64/trap.c @@ -247,10 +247,10 @@ recheck: * Post any pending upcalls */ if (p->p_flag & P_UPCALLPEND) { - get_mplock(); + lwkt_gettoken(&p->p_token); p->p_flag &= ~P_UPCALLPEND; postupcall(lp); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; } @@ -260,9 +260,9 @@ recheck: * WARNING! postsig() can exit and not return. */ if ((sig = CURSIG_TRACE(lp)) != 0) { - get_mplock(); + lwkt_gettoken(&p->p_token); postsig(sig); - rel_mplock(); + lwkt_reltoken(&p->p_token); goto recheck; }