aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJeremy Kerr <jeremy@redfishsoftware.com.au>2004-06-01 17:18:12 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-01 17:18:12 -0700
commit651bea8c072b9ab412719f69a5e76bc91f3124cc (patch)
treea1dd8804b285848ac5f85b695339ab09bf5242a8 /kernel
parent8012a7f767b59fca384aad773b0cd87ccecc6ad9 (diff)
downloadhistory-651bea8c072b9ab412719f69a5e76bc91f3124cc.tar.gz
[PATCH] Fix signal race during process exit
Fix a race identified by Jeremy Kerr <jeremy@redfishsoftware.com.au>: if update_process_times() decides to deliver a signal due to process timer expiry, it can race with __exit_sighand()'s freeing of task->sighand. Fix that by clearing the per-process timer state in exit_notify(), while under local_irq_disable() and under tasklist_lock. tasklist_lock provides exclusion wrt release_task()'s freeing of task->sighand and local_irq_disable() provides exclusion wrt update_process_times()'s inspection of the per-process timer state. We also need to deal with the send_sig() calls in do_process_times() by setting rlim_cur to RLIM_INFINITY. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 8c1a599db266e1..0be17fec85fe44 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -737,6 +737,14 @@ static void exit_notify(struct task_struct *tsk)
tsk->flags |= PF_DEAD;
/*
+ * Clear these here so that update_process_times() won't try to deliver
+ * itimer, profile or rlimit signals to this task while it is in late exit.
+ */
+ tsk->it_virt_incr = 0;
+ tsk->it_prof_value = 0;
+ tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY;
+
+ /*
* In the preemption case it must be impossible for the task
* to get runnable again, so use "_raw_" unlock to keep
* preempt_count elevated until we schedule().