aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index eb881cfa53e0..2a1e95b0f282 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2770,12 +2770,11 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
2770 * actually has driver level meaning and triggers a VC resize. 2770 * actually has driver level meaning and triggers a VC resize.
2771 * 2771 *
2772 * Locking: 2772 * Locking:
2773 * The console_sem is used to ensure we do not try and resize 2773 * Called function use the console_sem is used to ensure we do
2774 * the console twice at once. 2774 * not try and resize the console twice at once.
2775 * FIXME: Two racing size sets may leave the console and kernel 2775 * The tty->termios_sem is used to ensure we don't double
2776 * parameters disagreeing. Is this exploitable ? 2776 * resize and get confused. Lock order - tty->termios.sem before
2777 * FIXME: Random values racing a window size get is wrong 2777 * console sem
2778 * should lock here against that
2779 */ 2778 */
2780 2779
2781static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, 2780static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
@@ -2785,17 +2784,17 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2785 2784
2786 if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) 2785 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2787 return -EFAULT; 2786 return -EFAULT;
2787
2788 down(&tty->termios_sem);
2788 if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg))) 2789 if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
2789 return 0; 2790 goto done;
2791
2790#ifdef CONFIG_VT 2792#ifdef CONFIG_VT
2791 if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) { 2793 if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
2792 int rc; 2794 if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row)) {
2793 2795 up(&tty->termios_sem);
2794 acquire_console_sem(); 2796 return -ENXIO;
2795 rc = vc_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row); 2797 }
2796 release_console_sem();
2797 if (rc)
2798 return -ENXIO;
2799 } 2798 }
2800#endif 2799#endif
2801 if (tty->pgrp > 0) 2800 if (tty->pgrp > 0)
@@ -2804,6 +2803,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2804 kill_pg(real_tty->pgrp, SIGWINCH, 1); 2803 kill_pg(real_tty->pgrp, SIGWINCH, 1);
2805 tty->winsize = tmp_ws; 2804 tty->winsize = tmp_ws;
2806 real_tty->winsize = tmp_ws; 2805 real_tty->winsize = tmp_ws;
2806done:
2807 up(&tty->termios_sem);
2807 return 0; 2808 return 0;
2808} 2809}
2809 2810