patch-2.2.14 linux/kernel/signal.c

Next file: linux/kernel/sysctl.c
Previous file: linux/kernel/sched.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.13/linux/kernel/signal.c linux/kernel/signal.c
@@ -44,6 +44,8 @@
 
 /*
  * Flush all pending signals for a task.
+ * Callers must hold the sigmask_lock so that we do not race
+ * with dequeue_signal or send_sig_info.
  */
 
 void
@@ -270,12 +272,16 @@
 		goto out_nolock;
 
 	/* The null signal is a permissions and process existance probe.
-	   No signal is actually delivered.  Same goes for zombies. */
+	   No signal is actually delivered.  Same goes for zombies.
+	   We have to grab the spinlock now so that we do not race
+	   with flush_signals. */
 	ret = 0;
-	if (!sig || !t->sig)
+	spin_lock_irqsave(&t->sigmask_lock, flags);
+	if (!sig || !t->sig) {
+		spin_unlock_irqrestore(&t->sigmask_lock, flags);
 		goto out_nolock;
+	}
 
-	spin_lock_irqsave(&t->sigmask_lock, flags);
 	switch (sig) {
 	case SIGKILL: case SIGCONT:
 		/* Wake up the process if stopped.  */
@@ -674,7 +680,8 @@
 			break;
 		}
 
-		current->blocked = new_set;
+		if (!error)
+		    current->blocked = new_set;
 		recalc_sigpending(current);
 		spin_unlock_irq(&current->sigmask_lock);
 		if (error)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)