[PATCH] fork: fix race in setting child's pgrp and tty
In fork, child should recopy parent's pgrp/tty after it has tasklist_lock. Otherwise following a setpgid() on the parent, *after* copy_signal(), the child will own a stale pgrp (which may be reused); (eg. if copy_mm() sleeps a long while due to memory pressure). Similar issue for the tty. Signed-off-by: Oren Laadan <orenl@cs.columbia.edu> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
fb86a35b9d
commit
9a5d3023e6
@ -811,9 +811,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
|
||||
sig->it_prof_expires = cputime_zero;
|
||||
sig->it_prof_incr = cputime_zero;
|
||||
|
||||
sig->tty = current->signal->tty;
|
||||
sig->pgrp = process_group(current);
|
||||
sig->session = current->signal->session;
|
||||
sig->leader = 0; /* session leadership doesn't inherit */
|
||||
sig->tty_old_pgrp = 0;
|
||||
|
||||
@ -1136,15 +1133,15 @@ static task_t *copy_process(unsigned long clone_flags,
|
||||
attach_pid(p, PIDTYPE_PID, p->pid);
|
||||
attach_pid(p, PIDTYPE_TGID, p->tgid);
|
||||
if (thread_group_leader(p)) {
|
||||
p->signal->tty = current->signal->tty;
|
||||
p->signal->pgrp = process_group(current);
|
||||
p->signal->session = current->signal->session;
|
||||
attach_pid(p, PIDTYPE_PGID, process_group(p));
|
||||
attach_pid(p, PIDTYPE_SID, p->signal->session);
|
||||
if (p->pid)
|
||||
__get_cpu_var(process_counts)++;
|
||||
}
|
||||
|
||||
if (!current->signal->tty && p->signal->tty)
|
||||
p->signal->tty = NULL;
|
||||
|
||||
nr_threads++;
|
||||
total_forks++;
|
||||
write_unlock_irq(&tasklist_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user