aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/tty_io.c29
-rw-r--r--drivers/char/vt.c12
-rw-r--r--drivers/char/vt_ioctl.c17
-rw-r--r--include/linux/vt_kern.h3
5 files changed, 36 insertions, 27 deletions
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 71093a9fc462..74cff839c857 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -33,7 +33,7 @@ extern void poke_blanked_console(void);
33 33
34/* Variables for selection control. */ 34/* Variables for selection control. */
35/* Use a dynamic buffer, instead of static (Dec 1994) */ 35/* Use a dynamic buffer, instead of static (Dec 1994) */
36struct vc_data *sel_cons; /* must not be disallocated */ 36struct vc_data *sel_cons; /* must not be deallocated */
37static volatile int sel_start = -1; /* cleared by clear_selection */ 37static volatile int sel_start = -1; /* cleared by clear_selection */
38static int sel_end; 38static int sel_end;
39static int sel_buffer_lth; 39static int sel_buffer_lth;
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
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 0fca83ededff..b49f03375439 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -885,8 +885,17 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
885 return err; 885 return err;
886} 886}
887 887
888int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
889{
890 int rc;
891
892 acquire_console_sem();
893 rc = vc_resize(vc, cols, lines);
894 release_console_sem();
895 return rc;
896}
888 897
889void vc_disallocate(unsigned int currcons) 898void vc_deallocate(unsigned int currcons)
890{ 899{
891 WARN_CONSOLE_UNLOCKED(); 900 WARN_CONSOLE_UNLOCKED();
892 901
@@ -3790,6 +3799,7 @@ EXPORT_SYMBOL(default_blu);
3790EXPORT_SYMBOL(update_region); 3799EXPORT_SYMBOL(update_region);
3791EXPORT_SYMBOL(redraw_screen); 3800EXPORT_SYMBOL(redraw_screen);
3792EXPORT_SYMBOL(vc_resize); 3801EXPORT_SYMBOL(vc_resize);
3802EXPORT_SYMBOL(vc_lock_resize);
3793EXPORT_SYMBOL(fg_console); 3803EXPORT_SYMBOL(fg_console);
3794EXPORT_SYMBOL(console_blank_hook); 3804EXPORT_SYMBOL(console_blank_hook);
3795EXPORT_SYMBOL(console_blanked); 3805EXPORT_SYMBOL(console_blanked);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index a5628a8b6620..a53e382cc107 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -96,7 +96,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
96 if (!perm) 96 if (!perm)
97 return -EPERM; 97 return -EPERM;
98 if (!i && v == K_NOSUCHMAP) { 98 if (!i && v == K_NOSUCHMAP) {
99 /* disallocate map */ 99 /* deallocate map */
100 key_map = key_maps[s]; 100 key_map = key_maps[s];
101 if (s && key_map) { 101 if (s && key_map) {
102 key_maps[s] = NULL; 102 key_maps[s] = NULL;
@@ -819,20 +819,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
819 if (arg > MAX_NR_CONSOLES) 819 if (arg > MAX_NR_CONSOLES)
820 return -ENXIO; 820 return -ENXIO;
821 if (arg == 0) { 821 if (arg == 0) {
822 /* disallocate all unused consoles, but leave 0 */ 822 /* deallocate all unused consoles, but leave 0 */
823 acquire_console_sem(); 823 acquire_console_sem();
824 for (i=1; i<MAX_NR_CONSOLES; i++) 824 for (i=1; i<MAX_NR_CONSOLES; i++)
825 if (! VT_BUSY(i)) 825 if (! VT_BUSY(i))
826 vc_disallocate(i); 826 vc_deallocate(i);
827 release_console_sem(); 827 release_console_sem();
828 } else { 828 } else {
829 /* disallocate a single console, if possible */ 829 /* deallocate a single console, if possible */
830 arg--; 830 arg--;
831 if (VT_BUSY(arg)) 831 if (VT_BUSY(arg))
832 return -EBUSY; 832 return -EBUSY;
833 if (arg) { /* leave 0 */ 833 if (arg) { /* leave 0 */
834 acquire_console_sem(); 834 acquire_console_sem();
835 vc_disallocate(arg); 835 vc_deallocate(arg);
836 release_console_sem(); 836 release_console_sem();
837 } 837 }
838 } 838 }
@@ -847,11 +847,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
847 if (get_user(ll, &vtsizes->v_rows) || 847 if (get_user(ll, &vtsizes->v_rows) ||
848 get_user(cc, &vtsizes->v_cols)) 848 get_user(cc, &vtsizes->v_cols))
849 return -EFAULT; 849 return -EFAULT;
850 for (i = 0; i < MAX_NR_CONSOLES; i++) { 850 for (i = 0; i < MAX_NR_CONSOLES; i++)
851 acquire_console_sem(); 851 vc_lock_resize(vc_cons[i].d, cc, ll);
852 vc_resize(vc_cons[i].d, cc, ll);
853 release_console_sem();
854 }
855 return 0; 852 return 0;
856 } 853 }
857 854
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 918a29763aea..1009d3fe1fc2 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -33,7 +33,8 @@ extern int fg_console, last_console, want_console;
33int vc_allocate(unsigned int console); 33int vc_allocate(unsigned int console);
34int vc_cons_allocated(unsigned int console); 34int vc_cons_allocated(unsigned int console);
35int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); 35int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
36void vc_disallocate(unsigned int console); 36int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
37void vc_deallocate(unsigned int console);
37void reset_palette(struct vc_data *vc); 38void reset_palette(struct vc_data *vc);
38void do_blank_screen(int entering_gfx); 39void do_blank_screen(int entering_gfx);
39void do_unblank_screen(int leaving_gfx); 40void do_unblank_screen(int leaving_gfx);