tty/vt/keyboard: fix OOB access in do_compute_shiftstate()
[pandora-kernel.git] / drivers / tty / tty_ioctl.c
index 53f2442..1740117 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
+#include <linux/compat.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -153,11 +154,17 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
 #endif
        if (!timeout)
                timeout = MAX_SCHEDULE_TIMEOUT;
+
        if (wait_event_interruptible_timeout(tty->write_wait,
-                       !tty_chars_in_buffer(tty), timeout) >= 0) {
-               if (tty->ops->wait_until_sent)
-                       tty->ops->wait_until_sent(tty, timeout);
+                       !tty_chars_in_buffer(tty), timeout) < 0) {
+               return;
        }
+
+       if (timeout == MAX_SCHEDULE_TIMEOUT)
+               timeout = 0;
+
+       if (tty->ops->wait_until_sent)
+               tty->ops->wait_until_sent(tty, timeout);
 }
 EXPORT_SYMBOL(tty_wait_until_sent);
 
@@ -617,7 +624,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
        if (opt & TERMIOS_WAIT) {
                tty_wait_until_sent(tty, 0);
                if (signal_pending(current))
-                       return -EINTR;
+                       return -ERESTARTSYS;
        }
 
        tty_set_termios(tty, &tmp_termios);
@@ -684,7 +691,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
        if (opt & TERMIOS_WAIT) {
                tty_wait_until_sent(tty, 0);
                if (signal_pending(current))
-                       return -EINTR;
+                       return -ERESTARTSYS;
        }
 
        mutex_lock(&tty->termios_mutex);
@@ -1179,3 +1186,19 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
        }
 }
 EXPORT_SYMBOL(n_tty_ioctl_helper);
+
+#ifdef CONFIG_COMPAT
+long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case TIOCGLCKTRMIOS:
+       case TIOCSLCKTRMIOS:
+               return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
+#endif
+