]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/tty_io.c
tty_open can return to userspace holding tty_mutex
[linux-2.6-omap-h63xx.git] / drivers / char / tty_io.c
index d8d240c8a25ac34412087368f62b46a3e5fca119..bc84e125c6bc428ca1d51cbcb29909466ea96b87 100644 (file)
@@ -1211,7 +1211,7 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
  *     be held until the 'fast-open' is also done. Will change once we
  *     have refcounting in the driver and per driver locking
  */
-struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
+static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
                struct inode *inode, int idx)
 {
        struct tty_struct *tty;
@@ -1817,8 +1817,10 @@ got_driver:
                /* check whether we're reopening an existing tty */
                tty = tty_driver_lookup_tty(driver, inode, index);
 
-               if (IS_ERR(tty))
+               if (IS_ERR(tty)) {
+                       mutex_unlock(&tty_mutex);
                        return PTR_ERR(tty);
+               }
        }
 
        if (tty) {
@@ -2048,7 +2050,6 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
 /**
  *     tty_do_resize           -       resize event
  *     @tty: tty being resized
- *     @real_tty: real tty (not the same as tty if using a pty/tty pair)
  *     @rows: rows (character)
  *     @cols: cols (character)
  *
@@ -2056,41 +2057,34 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
  *     peform a terminal resize correctly
  */
 
-int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
-                                       struct winsize *ws)
+int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
 {
-       struct pid *pgrp, *rpgrp;
+       struct pid *pgrp;
        unsigned long flags;
 
-       /* For a PTY we need to lock the tty side */
-       mutex_lock(&real_tty->termios_mutex);
-       if (!memcmp(ws, &real_tty->winsize, sizeof(*ws)))
+       /* Lock the tty */
+       mutex_lock(&tty->termios_mutex);
+       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
                goto done;
        /* Get the PID values and reference them so we can
           avoid holding the tty ctrl lock while sending signals */
        spin_lock_irqsave(&tty->ctrl_lock, flags);
        pgrp = get_pid(tty->pgrp);
-       rpgrp = get_pid(real_tty->pgrp);
        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 
        if (pgrp)
                kill_pgrp(pgrp, SIGWINCH, 1);
-       if (rpgrp != pgrp && rpgrp)
-               kill_pgrp(rpgrp, SIGWINCH, 1);
-
        put_pid(pgrp);
-       put_pid(rpgrp);
 
        tty->winsize = *ws;
-       real_tty->winsize = *ws;
 done:
-       mutex_unlock(&real_tty->termios_mutex);
+       mutex_unlock(&tty->termios_mutex);
        return 0;
 }
 
 /**
  *     tiocswinsz              -       implement window size set ioctl
- *     @tty; tty
+ *     @tty; tty side of tty
  *     @arg: user buffer for result
  *
  *     Copies the user idea of the window size to the kernel. Traditionally
@@ -2103,17 +2097,16 @@ done:
  *     then calls into the default method.
  */
 
-static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
-       struct winsize __user *arg)
+static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
 {
        struct winsize tmp_ws;
        if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
                return -EFAULT;
 
        if (tty->ops->resize)
-               return tty->ops->resize(tty, real_tty, &tmp_ws);
+               return tty->ops->resize(tty, &tmp_ws);
        else
-               return tty_do_resize(tty, real_tty, &tmp_ws);
+               return tty_do_resize(tty, &tmp_ws);
 }
 
 /**
@@ -2538,7 +2531,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case TIOCGWINSZ:
                return tiocgwinsz(real_tty, p);
        case TIOCSWINSZ:
-               return tiocswinsz(tty, real_tty, p);
+               return tiocswinsz(real_tty, p);
        case TIOCCONS:
                return real_tty != tty ? -EINVAL : tioccons(file);
        case FIONBIO: