diff options
author | Samuel CUELLA <samuel.cuella@supinfo.com> | 2009-03-10 15:56:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-10 18:55:12 -0400 |
commit | 16b71fdf97599f1b1b7f38418ee9922d9f117396 (patch) | |
tree | 86ceac6117f5a678aaa177bbcdf8d84d2559010c /drivers/video | |
parent | 9233ecc5c4b5f31921d914b3ef3baa3dc1ae4cc6 (diff) |
i810: fix kernel crash fix when struct fb_var_screeninfo is supplied
Prevent the kernel from being crashed by a divide-by-zero operation when
supplied an incorrectly filled 'struct fb_var_screeninfo' from userland.
Previously i810_main.c:1005 (i810_check_params) was using the global
'yres' symbol previously defined at i810_main.c:145 as a module parameter
value holder (i810_main.c:2174). If i810fb is compiled-in or if this
param doesn't get a default value, this direct usage leads to a
divide-by-zero at i810_main.c:1005 (i810_check_params). The patch simply
replace the 'yres' global, perhaps undefined symbol usage by a given
parameter structure lookup.
This problem occurs with directfb, mplayer -vo fbdev, SDL library.
It was also reported ( but non solved ) at:
http://mail.directfb.org/pipermail/directfb-dev/2008-March/004050.html
Signed-off-by: Samuel CUELLA <samuel.cuella@supinfo.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/i810/i810_main.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index a24e680d2b9c..2e940199fc89 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -993,6 +993,7 @@ static int i810_check_params(struct fb_var_screeninfo *var, | |||
993 | struct i810fb_par *par = info->par; | 993 | struct i810fb_par *par = info->par; |
994 | int line_length, vidmem, mode_valid = 0, retval = 0; | 994 | int line_length, vidmem, mode_valid = 0, retval = 0; |
995 | u32 vyres = var->yres_virtual, vxres = var->xres_virtual; | 995 | u32 vyres = var->yres_virtual, vxres = var->xres_virtual; |
996 | |||
996 | /* | 997 | /* |
997 | * Memory limit | 998 | * Memory limit |
998 | */ | 999 | */ |
@@ -1002,12 +1003,12 @@ static int i810_check_params(struct fb_var_screeninfo *var, | |||
1002 | if (vidmem > par->fb.size) { | 1003 | if (vidmem > par->fb.size) { |
1003 | vyres = par->fb.size/line_length; | 1004 | vyres = par->fb.size/line_length; |
1004 | if (vyres < var->yres) { | 1005 | if (vyres < var->yres) { |
1005 | vyres = yres; | 1006 | vyres = info->var.yres; |
1006 | vxres = par->fb.size/vyres; | 1007 | vxres = par->fb.size/vyres; |
1007 | vxres /= var->bits_per_pixel >> 3; | 1008 | vxres /= var->bits_per_pixel >> 3; |
1008 | line_length = get_line_length(par, vxres, | 1009 | line_length = get_line_length(par, vxres, |
1009 | var->bits_per_pixel); | 1010 | var->bits_per_pixel); |
1010 | vidmem = line_length * yres; | 1011 | vidmem = line_length * info->var.yres; |
1011 | if (vxres < var->xres) { | 1012 | if (vxres < var->xres) { |
1012 | printk("i810fb: required video memory, " | 1013 | printk("i810fb: required video memory, " |
1013 | "%d bytes, for %dx%d-%d (virtual) " | 1014 | "%d bytes, for %dx%d-%d (virtual) " |