aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorMichael Gehring <mg@ebfe.org>2012-03-20 20:26:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-09 15:10:23 -0400
commit871bdea6f8c64517635bec352b8bec6b72a26d80 (patch)
tree786a6dede8222338409a05e316cf58435ee97e72 /drivers/tty/vt
parentef4f9d4f09265b60fcb6bfa31a614ea84a72b7a8 (diff)
tty/vt: handle bad user buffer in {G,P}IO_CMAP ioctl
set_get_cmap() ignored the result of {get,put}_user(), causing ioctl(vt, {G,P}IO_CMAP, 0xdeadbeef) to silently fail. Another side effect of this: calling the PIO_CMAP ioctl with an invalid buffer would zero the default colormap and the palette for all vts (all colors set to black). Leave the default colormap intact and return -EFAULT when reading/writing to the userspace buffer fails. Signed-off-by: Michael Gehring <mg@ebfe.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/vt.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3bdd4b19dd06..5836289bd861 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3893,36 +3893,6 @@ static void set_palette(struct vc_data *vc)
3893 vc->vc_sw->con_set_palette(vc, color_table); 3893 vc->vc_sw->con_set_palette(vc, color_table);
3894} 3894}
3895 3895
3896static int set_get_cmap(unsigned char __user *arg, int set)
3897{
3898 int i, j, k;
3899
3900 WARN_CONSOLE_UNLOCKED();
3901
3902 for (i = 0; i < 16; i++)
3903 if (set) {
3904 get_user(default_red[i], arg++);
3905 get_user(default_grn[i], arg++);
3906 get_user(default_blu[i], arg++);
3907 } else {
3908 put_user(default_red[i], arg++);
3909 put_user(default_grn[i], arg++);
3910 put_user(default_blu[i], arg++);
3911 }
3912 if (set) {
3913 for (i = 0; i < MAX_NR_CONSOLES; i++)
3914 if (vc_cons_allocated(i)) {
3915 for (j = k = 0; j < 16; j++) {
3916 vc_cons[i].d->vc_palette[k++] = default_red[j];
3917 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3918 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3919 }
3920 set_palette(vc_cons[i].d);
3921 }
3922 }
3923 return 0;
3924}
3925
3926/* 3896/*
3927 * Load palette into the DAC registers. arg points to a colour 3897 * Load palette into the DAC registers. arg points to a colour
3928 * map, 3 bytes per colour, 16 colours, range from 0 to 255. 3898 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
@@ -3930,24 +3900,50 @@ static int set_get_cmap(unsigned char __user *arg, int set)
3930 3900
3931int con_set_cmap(unsigned char __user *arg) 3901int con_set_cmap(unsigned char __user *arg)
3932{ 3902{
3933 int rc; 3903 int i, j, k;
3904 unsigned char colormap[3*16];
3905
3906 if (copy_from_user(colormap, arg, sizeof(colormap)))
3907 return -EFAULT;
3934 3908
3935 console_lock(); 3909 console_lock();
3936 rc = set_get_cmap (arg,1); 3910 for (i = k = 0; i < 16; i++) {
3911 default_red[i] = colormap[k++];
3912 default_grn[i] = colormap[k++];
3913 default_blu[i] = colormap[k++];
3914 }
3915 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3916 if (!vc_cons_allocated(i))
3917 continue;
3918 for (j = k = 0; j < 16; j++) {
3919 vc_cons[i].d->vc_palette[k++] = default_red[j];
3920 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3921 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3922 }
3923 set_palette(vc_cons[i].d);
3924 }
3937 console_unlock(); 3925 console_unlock();
3938 3926
3939 return rc; 3927 return 0;
3940} 3928}
3941 3929
3942int con_get_cmap(unsigned char __user *arg) 3930int con_get_cmap(unsigned char __user *arg)
3943{ 3931{
3944 int rc; 3932 int i, k;
3933 unsigned char colormap[3*16];
3945 3934
3946 console_lock(); 3935 console_lock();
3947 rc = set_get_cmap (arg,0); 3936 for (i = k = 0; i < 16; i++) {
3937 colormap[k++] = default_red[i];
3938 colormap[k++] = default_grn[i];
3939 colormap[k++] = default_blu[i];
3940 }
3948 console_unlock(); 3941 console_unlock();
3949 3942
3950 return rc; 3943 if (copy_to_user(arg, colormap, sizeof(colormap)))
3944 return -EFAULT;
3945
3946 return 0;
3951} 3947}
3952 3948
3953void reset_palette(struct vc_data *vc) 3949void reset_palette(struct vc_data *vc)