signal: fix __send_signal() false positive kmemcheck warning
authorVegard Nossum <vegard.nossum@gmail.com>
Sat, 16 May 2009 09:28:33 +0000 (11:28 +0200)
committerVegard Nossum <vegard.nossum@gmail.com>
Mon, 15 Jun 2009 13:49:43 +0000 (15:49 +0200)
This false positive is due to field padding in struct sigqueue. When
this dynamically allocated structure is copied to the stack (in arch-
specific delivery code), kmemcheck sees a read from the padding, which
is, naturally, uninitialized.

Hide the false positive using the __GFP_NOTRACK_FALSE_POSITIVE flag.
Also made the rlimit override code a bit clearer by introducing a new
variable.

Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
kernel/signal.c

index 809a228019adeb06c8979d86f52473a0d4a168ac..d81f4952eebbcfa484c338256e3ff2e84c9d3b1e 100644 (file)
@@ -832,6 +832,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 {
        struct sigpending *pending;
        struct sigqueue *q;
+       int override_rlimit;
 
        trace_sched_signal_send(sig, t);
 
@@ -863,9 +864,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
           make sure at least one signal gets delivered and don't
           pass on the info struct.  */
 
-       q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
-                                            (is_si_special(info) ||
-                                             info->si_code >= 0)));
+       if (sig < SIGRTMIN)
+               override_rlimit = (is_si_special(info) || info->si_code >= 0);
+       else
+               override_rlimit = 0;
+
+       q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
+               override_rlimit);
        if (q) {
                list_add_tail(&q->list, &pending->list);
                switch ((unsigned long) info) {