tty: the vhangup syscall is racy
Alan Cox [Mon, 13 Oct 2008 09:40:30 +0000 (10:40 +0100)]
We now have the infrastructure to sort this out but rather than teaching
the syscall tty lock rules we move the hard work into a tty helper

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

drivers/char/tty_io.c
fs/open.c
include/linux/tty.h

index 913b502..b5f57d0 100644 (file)
@@ -730,6 +730,25 @@ void tty_vhangup(struct tty_struct *tty)
 EXPORT_SYMBOL(tty_vhangup);
 
 /**
+ *     tty_vhangup_self        -       process vhangup for own ctty
+ *
+ *     Perform a vhangup on the current controlling tty
+ */
+
+void tty_vhangup_self(void)
+{
+       struct tty_struct *tty;
+
+       mutex_lock(&tty_mutex);
+       tty = get_current_tty();
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
+       mutex_unlock(&tty_mutex);
+}
+
+/**
  *     tty_hung_up_p           -       was tty hung up
  *     @filp: file pointer of tty
  *
index 07da935..5596049 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -1141,8 +1141,7 @@ EXPORT_SYMBOL(sys_close);
 asmlinkage long sys_vhangup(void)
 {
        if (capable(CAP_SYS_TTY_CONFIG)) {
-               /* XXX: this needs locking */
-               tty_vhangup(current->signal->tty);
+               tty_vhangup_self();
                return 0;
        }
        return -EPERM;
index c30ed8d..e00393a 100644 (file)
@@ -361,6 +361,7 @@ extern int is_ignored(int sig);
 extern int tty_signal(int sig, struct tty_struct *tty);
 extern void tty_hangup(struct tty_struct *tty);
 extern void tty_vhangup(struct tty_struct *tty);
+extern void tty_vhangup_self(void);
 extern void tty_unhangup(struct file *filp);
 extern int tty_hung_up_p(struct file *filp);
 extern void do_SAK(struct tty_struct *tty);