diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2007-02-12 00:52:56 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 09:48:31 -0800 |
commit | 04a2e6a5cbf84e85fe86de0a18f6509b147e1d89 (patch) | |
tree | 67dd67d2c4c18e5c36654dfe569e3085bd262ba5 /drivers | |
parent | 8d42db189ca99703f0f4f91c477cb54808c8eaaa (diff) |
[PATCH] pid: make session_of_pgrp use struct pid instead of pid_t
To properly implement a pid namespace I need to deal exclusively in terms of
struct pid, because pid_t values become ambiguous.
To this end session_of_pgrp is transformed to take and return a struct pid
pointer. To avoid the need to worry about reference counting I now require my
caller to hold the appropriate locks. Leaving callers repsonsible for
increasing the reference count if they need access to the result outside of
the locks.
Since session_of_pgrp currently only has one caller and that caller simply
uses only test the result for equality with another process group, the locking
change means I don't actually have to acquire the tasklist_lock at all.
tiocspgrp is also modified to take and release the lock. The logic there is a
little more complicated but nothing I won't need when I convert pgrp of a tty
to a struct pid pointer.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/tty_io.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index abfe24d28c5..95f3596189c 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2990,7 +2990,8 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { - pid_t pgrp; + struct pid *pgrp; + pid_t pgrp_nr; int retval = tty_check_change(real_tty); if (retval == -EIO) @@ -3001,14 +3002,23 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t (current->signal->tty != real_tty) || (real_tty->session != process_session(current))) return -ENOTTY; - if (get_user(pgrp, p)) + if (get_user(pgrp_nr, p)) return -EFAULT; - if (pgrp < 0) + if (pgrp_nr < 0) return -EINVAL; - if (session_of_pgrp(pgrp) != process_session(current)) - return -EPERM; - real_tty->pgrp = pgrp; - return 0; + rcu_read_lock(); + pgrp = find_pid(pgrp_nr); + retval = -ESRCH; + if (!pgrp) + goto out_unlock; + retval = -EPERM; + if (session_of_pgrp(pgrp) != task_session(current)) + goto out_unlock; + retval = 0; + real_tty->pgrp = pgrp_nr; +out_unlock: + rcu_read_unlock(); + return retval; } /** |