aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-07-12 16:58:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-12 19:01:01 -0400
commit5323125031799a7fd8602ce150c3902aedfdcba6 (patch)
tree43281ea094cba176e88ba50561e2a04aa8beed8c /fs
parent5c888d531823f8ce2853fb717ebefbcca9acdcd0 (diff)
[PATCH] reset real_timer target on exec leader change
When a noninitial thread does exec, it becomes the new group leader. If there is a ITIMER_REAL timer running, it points at the old group leader and when it fires it can follow a stale pointer. The timer data needs to be reset to point at the exec'ing thread that is becoming the group leader. This has to synchronize with any concurrent firing of the timer to make sure that it_real_fn can never run when the data points to a thread that might have been reaped already. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 48871917d363..222ab1c572d8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -642,6 +642,18 @@ static inline int de_thread(struct task_struct *tsk)
642 count = 2; 642 count = 2;
643 if (thread_group_leader(current)) 643 if (thread_group_leader(current))
644 count = 1; 644 count = 1;
645 else {
646 /*
647 * The SIGALRM timer survives the exec, but needs to point
648 * at us as the new group leader now. We have a race with
649 * a timer firing now getting the old leader, so we need to
650 * synchronize with any firing (by calling del_timer_sync)
651 * before we can safely let the old group leader die.
652 */
653 sig->real_timer.data = (unsigned long)current;
654 if (del_timer_sync(&sig->real_timer))
655 add_timer(&sig->real_timer);
656 }
645 while (atomic_read(&sig->count) > count) { 657 while (atomic_read(&sig->count) > count) {
646 sig->group_exit_task = current; 658 sig->group_exit_task = current;
647 sig->notify_count = count; 659 sig->notify_count = count;