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>
This commit is contained in:
Samuel CUELLA 2009-03-10 12:56:00 -07:00 committed by Linus Torvalds
parent 9233ecc5c4
commit 16b71fdf97
1 changed files with 3 additions and 2 deletions

View File

@ -993,6 +993,7 @@ static int i810_check_params(struct fb_var_screeninfo *var,
struct i810fb_par *par = info->par; struct i810fb_par *par = info->par;
int line_length, vidmem, mode_valid = 0, retval = 0; int line_length, vidmem, mode_valid = 0, retval = 0;
u32 vyres = var->yres_virtual, vxres = var->xres_virtual; u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
/* /*
* Memory limit * Memory limit
*/ */
@ -1002,12 +1003,12 @@ static int i810_check_params(struct fb_var_screeninfo *var,
if (vidmem > par->fb.size) { if (vidmem > par->fb.size) {
vyres = par->fb.size/line_length; vyres = par->fb.size/line_length;
if (vyres < var->yres) { if (vyres < var->yres) {
vyres = yres; vyres = info->var.yres;
vxres = par->fb.size/vyres; vxres = par->fb.size/vyres;
vxres /= var->bits_per_pixel >> 3; vxres /= var->bits_per_pixel >> 3;
line_length = get_line_length(par, vxres, line_length = get_line_length(par, vxres,
var->bits_per_pixel); var->bits_per_pixel);
vidmem = line_length * yres; vidmem = line_length * info->var.yres;
if (vxres < var->xres) { if (vxres < var->xres) {
printk("i810fb: required video memory, " printk("i810fb: required video memory, "
"%d bytes, for %dx%d-%d (virtual) " "%d bytes, for %dx%d-%d (virtual) "