tty_io: Fix remaining pid struct locking
Subsystems (3)
PATCH 1/1 tty_io: Fix remaining pid struct locking
This fixes the last couple of pid struct locking failures I know about. Goes on top of the other -mm patches for pid struct locking in the tty layer
Signed-off-by Alan Cox <[email protected]>
drivers/char/tty_io.c +27 -1
@@ -3098,6 +3260,27 @@ }/** +* 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 * @real_tty: tty side of the tty pased by the user if a pty else the tty
@@ -3111,13 +3294,18 @@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; }/**
fs/proc/array.c +4 -1
@@ -408,6 +408,7 @@unsigned long rsslim =0 ;char tcomm[sizeof (task->comm)];unsigned long flags; +struct pid *pgrp; state = *get_task_state (task); vsize = eip = esp =0 ;
@@ -430,7 +431,9 @@struct signal_struct *sig = task->signal;if (sig->tty) { - tty_pgrp =pid_nr_ns (sig->tty->pgrp, ns); + 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)); }
include/linux/tty.h +1 -0
@@ -295,6 +315,7 @@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);