tty_io: fix remaining pid struct locking

This fixes the last couple of pid struct locking failures I know about.

[oleg@tv-sign.ru: clean up do_task_stat()]
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Alan Cox 2008-04-30 00:53:31 -07:00 committed by Linus Torvalds
parent 575537b324
commit 5d0fdf1e01
3 changed files with 31 additions and 2 deletions

View file

@ -3173,6 +3173,27 @@ static int tiocsctty(struct tty_struct *tty, int arg)
return ret;
}
/**
* tty_get_pgrp - return a ref counted pgrp pid
* @tty: tty to read
*
* Returns a refcounted instance of the pid struct for the process
* group controlling the tty.
*/
struct pid *tty_get_pgrp(struct tty_struct *tty)
{
unsigned long flags;
struct pid *pgrp;
spin_lock_irqsave(&tty->ctrl_lock, flags);
pgrp = get_pid(tty->pgrp);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
return pgrp;
}
EXPORT_SYMBOL_GPL(tty_get_pgrp);
/**
* tiocgpgrp - get process group
* @tty: tty passed by user
@ -3187,13 +3208,18 @@ static int tiocsctty(struct tty_struct *tty, int arg)
static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
struct pid *pid;
int ret;
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
return put_user(pid_vnr(real_tty->pgrp), p);
pid = tty_get_pgrp(real_tty);
ret = put_user(pid_vnr(pid), p);
put_pid(pid);
return ret;
}
/**

View file

@ -429,7 +429,9 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
struct signal_struct *sig = task->signal;
if (sig->tty) {
tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns);
struct pid *pgrp = tty_get_pgrp(sig->tty);
tty_pgrp = pid_nr_ns(pgrp, ns);
put_pid(pgrp);
tty_nr = new_encode_dev(tty_devnum(sig->tty));
}

View file

@ -297,6 +297,7 @@ extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp,
extern void tty_write_message(struct tty_struct *tty, char *msg);
extern int is_current_pgrp_orphaned(void);
extern struct pid *tty_get_pgrp(struct tty_struct *tty);
extern int is_ignored(int sig);
extern int tty_signal(int sig, struct tty_struct *tty);
extern void tty_hangup(struct tty_struct * tty);