History

fork/exit: move tty_kref_put() outside of __cleanup_signal()

tty_kref_put() has two callsites in copy_process() paths, 1. if copy_process() suceeds it is called before we copy signal->tty from parent 2. otherwise it is called from __cleanup_signal() under bad_fork_cleanup_signal: label In both cases tty_kref_put() is not right and unneeded because we don't have the balancing tty_kref_get(). Fortunately, this is harmless because this can only happen without CLONE_THREAD, and in this case signal->tty must be NULL. Remove tty_kref_put() from copy_process() and __cleanup_signal(), and change another caller of __cleanup_signal(), __exit_signal(), to call tty_kref_put() by hand. I hope this change makes sense by itself, but it is also needed to make ->signal refcountable.

Oleg Nesterov committed 16 years ago

Commit 4dec2a91 parent ffdf9182 files · +1 −2Browse files

Unified · Split

2 files
  1. kernel/exit.c +1 −0
  2. kernel/fork.c +0 −2
kernel/exit.c+1−0
@@ -149,6 +149,7 @@ static void __exit_signal(struct task_struct *tsk) · 148 unmodified lines
149 * see account_group_exec_runtime().149 * see account_group_exec_runtime().
150 */150 */
151 task_rq_unlock_wait(tsk);151 task_rq_unlock_wait(tsk);
152 tty_kref_put(sig->tty);
152 __cleanup_signal(sig);153 __cleanup_signal(sig);
153 }154 }
154}155}
kernel/fork.c+0−2
@@ -892,7 +892,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) · 891 unmodified lines
892void __cleanup_signal(struct signal_struct *sig)892void __cleanup_signal(struct signal_struct *sig)
893{893{
894 thread_group_cputime_free(sig);894 thread_group_cputime_free(sig);
895 tty_kref_put(sig->tty);
896 kmem_cache_free(signal_cachep, sig);895 kmem_cache_free(signal_cachep, sig);
897}896}
898 897
@@ -1263,7 +1262,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, · 364 unmodified lines
1263 p->nsproxy->pid_ns->child_reaper = p;1262 p->nsproxy->pid_ns->child_reaper = p;
1264 1263
1265 p->signal->leader_pid = pid;1264 p->signal->leader_pid = pid;
1266 tty_kref_put(p->signal->tty);
1267 p->signal->tty = tty_kref_get(current->signal->tty);1265 p->signal->tty = tty_kref_get(current->signal->tty);
1268 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));1266 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
1269 attach_pid(p, PIDTYPE_SID, task_session(current));1267 attach_pid(p, PIDTYPE_SID, task_session(current));