kernel - Fix signal delivery races
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 29 Jul 2011 08:19:29 +0000 (01:19 -0700)
committerVenkatesh Srinivas <me@endeavour.zapto.org>
Sat, 30 Jul 2011 10:47:47 +0000 (03:47 -0700)
* 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.

sys/kern/kern_sig.c
sys/platform/pc32/i386/trap.c
sys/platform/pc64/x86_64/trap.c
sys/platform/vkernel/i386/trap.c
sys/platform/vkernel64/x86_64/trap.c

index d82b1a9..e5651b8 100644 (file)
@@ -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)
index 96b8af2..0432e54 100644 (file)
@@ -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;
        }
 
index d22e5d4..e507758 100644 (file)
@@ -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;
        }
 
index ff69ae1..fc025de 100644 (file)
@@ -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;
        }
 
index 874dfc5..02227ba 100644 (file)
@@ -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;
        }