aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-09-29 05:00:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-29 12:18:12 -0400
commitca9bda00b4aafc42cd3d1b9d32934463e2993b4c (patch)
treedbb7ba5320bb8d1cbf97b3493687cb87932ad5f4 /drivers/char/tty_io.c
parentae78bf9c4f5fde3c67e2829505f195d7347ce3e4 (diff)
[PATCH] tty locking on resize
The current kernel serializes console resizes but does not serialize the resize against the tty structure updates. This means that while two parallel resizes cannot mess up the console you can get incorrect results reported. Secondly while doing this I added vc_lock_resize() to lock and resize the console. This leaves all knowledge of the console_sem in the vt/console driver and kicks it out of the tty layer, which is good Thirdly while doing this I decided I couldn't stand "disallocate" any longer so I switched it to "deallocate". Signed-off-by: Alan Cox <alan@redhat.com> Cc: Paul Fulghum <paulkf@microgate.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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