diff options
author | Vegard Nossum <vegard.nossum@gmail.com> | 2009-05-16 05:28:33 -0400 |
---|---|---|
committer | Vegard Nossum <vegard.nossum@gmail.com> | 2009-06-15 09:49:43 -0400 |
commit | 7a0aeb14e18ad59394bd9bbc6e57fb345819e748 (patch) | |
tree | 04c7229103e1009ad8886ed663e047abe58805fb | |
parent | 3b5c760efcddf1ebdd39a2035b554e96febd7466 (diff) |
signal: fix __send_signal() false positive kmemcheck warning
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>
-rw-r--r-- | kernel/signal.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 809a228019ad..d81f4952eebb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -832,6 +832,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
832 | { | 832 | { |
833 | struct sigpending *pending; | 833 | struct sigpending *pending; |
834 | struct sigqueue *q; | 834 | struct sigqueue *q; |
835 | int override_rlimit; | ||
835 | 836 | ||
836 | trace_sched_signal_send(sig, t); | 837 | trace_sched_signal_send(sig, t); |
837 | 838 | ||
@@ -863,9 +864,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
863 | make sure at least one signal gets delivered and don't | 864 | make sure at least one signal gets delivered and don't |
864 | pass on the info struct. */ | 865 | pass on the info struct. */ |
865 | 866 | ||
866 | q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN && | 867 | if (sig < SIGRTMIN) |
867 | (is_si_special(info) || | 868 | override_rlimit = (is_si_special(info) || info->si_code >= 0); |
868 | info->si_code >= 0))); | 869 | else |
870 | override_rlimit = 0; | ||
871 | |||
872 | q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE, | ||
873 | override_rlimit); | ||
869 | if (q) { | 874 | if (q) { |
870 | list_add_tail(&q->list, &pending->list); | 875 | list_add_tail(&q->list, &pending->list); |
871 | switch ((unsigned long) info) { | 876 | switch ((unsigned long) info) { |