pids: introduce change_pid() helper
Based on Eric W. Biederman's idea.
Without tasklist_lock held task_session()/task_pgrp() can return NULL if the
caller races with setprgp()/setsid() which does detach_pid() + attach_pid().
This can happen even if task == current.
Intoduce the new helper, change_pid(), which should be used instead. This way
the caller always sees the special pid != NULL, either old or new.
Also change the prototype of attach_pid(), it always returns 0 and nobody
check the returned value.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/include/linux/pid.h b/include/linux/pid.h
index c798081..8d19903 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -89,9 +89,11 @@
* attach_pid() and detach_pid() must be called with the tasklist_lock
* write-held.
*/
-extern int attach_pid(struct task_struct *task, enum pid_type type,
- struct pid *pid);
+extern void attach_pid(struct task_struct *task, enum pid_type type,
+ struct pid *pid);
extern void detach_pid(struct task_struct *task, enum pid_type);
+extern void change_pid(struct task_struct *task, enum pid_type,
+ struct pid *pid);
extern void transfer_pid(struct task_struct *old, struct task_struct *new,
enum pid_type);