[PATCH] Possible bug in dequeue_signal()

From: Benjamin Herrenschmidt (benh@kernel.crashing.org)
Date: Sun Aug 26 2001 - 12:02:24 EST


I had a crash on PPC that I tracked down to be a bug in dequeue_signal()
in kernel/signal.c, and that probably happens on other archs as well.

do_signal() can loop & block. The exit condition of the loop in this case
is when dequeue_signal() returns 0. It continues calling it until that
point, it doesn't re-check current->sigpending.

That means on the second iteration, dequeue_signal() can actually be called
with no pending signal.

A that point, dequeue_signal() calls next_signal() which returns 0. The
problem begins when the current task has a "notifier" installed (which
in my case was done by DRM). If current->notifier is non-null, then we
call sigismember() passing it 0 as the "sig" parameter.

sigismember will then do pointer arithmetic with "sig-1", that is
0xffffffff which will crashes when dereferencing.

The patch is simple:

===== kernel/signal.c 1.1 vs edited =====
--- 1.1/kernel/signal.c Sat Jan 6 08:26:12 2001
+++ edited/kernel/signal.c Sun Aug 26 18:50:51 2001
@@ -242,7 +242,7 @@
 #endif
 
         sig = next_signal(current, mask);
- if (current->notifier) {
+ if (sig && current->notifier) {
                 if (sigismember(current->notifier_mask, sig)) {
                         if (!(current->notifier)(current->notifier_data)) {
                                 current->sigpending = 0;

(You may want to factor with the other if (sig) that is
done just after that code).

Ben.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Aug 31 2001 - 21:00:20 EST