[PATCH] [FBDEV]: accel_putcs() buffer overflow fix

From: Antonino Daplas (adaplas@pol.net)
Date: Thu Jan 02 2003 - 08:34:39 EST


1. If size of bitmap exceeds size of pixmap buffer, subdivide and do
multiple imageblits.

2. Use generic fb_pan_display() instead of info->fbops->fb_pan_display()
in update_var()

Diff is against linux-2.5.54.

Tony

diff -Naur linux-2.5.54/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.54/drivers/video/console/fbcon.c 2003-01-02 13:11:06.000000000 +0000
+++ linux/drivers/video/console/fbcon.c 2003-01-02 13:10:32.000000000 +0000
@@ -378,6 +378,7 @@
         info->fbops->fb_fillrect(info, &region);
 }
 
+#define FB_PIXMAPSIZE 8192
 void accel_putcs(struct vc_data *vc, struct display *p,
                         const unsigned short *s, int count, int yy, int xx)
 {
@@ -387,7 +388,7 @@
         unsigned int cellsize = vc->vc_font.height * width;
         struct fb_image image;
         u16 c = scr_readw(s);
- static u8 pixmap[8192];
+ static u8 pixmap[FB_PIXMAPSIZE];
         
         image.fg_color = attr_fgcol(p, c);
         image.bg_color = attr_bgcol(p, c);
@@ -396,43 +397,47 @@
         image.height = vc->vc_font.height;
         image.depth = 1;
 
-/* pixmap = kmalloc((info->var.bits_per_pixel + 7) >> 3 *
- vc->vc_font.height, GFP_KERNEL);
-*/
-
- if (!(vc->vc_font.width & 7) && pixmap != NULL) {
- unsigned int pitch = width * count, i, j;
+ if (!(vc->vc_font.width & 7)) {
+ unsigned int pitch, cnt, i, j, k;
+ unsigned int maxcnt = FB_PIXMAPSIZE/(vc->vc_font.height * width);
                 char *src, *dst, *dst0;
 
- dst0 = pixmap;
- image.width = vc->vc_font.width * count;
                 image.data = pixmap;
- while (count--) {
- src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
- dst = dst0;
- for (i = image.height; i--; ) {
- for (j = 0; j < width; j++)
- dst[j] = *src++;
- dst += pitch;
- }
- dst0 += width;
- }
- info->fbops->fb_imageblit(info, &image);
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
+ while (count) {
+ if (count > maxcnt)
+ cnt = k = maxcnt;
+ else
+ cnt = k = count;
+
+ dst0 = pixmap;
+ pitch = width * cnt;
+ image.width = vc->vc_font.width * cnt;
+ while (k--) {
+ src = p->fontdata + (scr_readw(s++)&charmask)*
+ cellsize;
+ dst = dst0;
+ for (i = image.height; i--; ) {
+ for (j = 0; j < width; j++)
+ dst[j] = *src++;
+ dst += pitch;
+ }
+ dst0 += width;
+ }
+
+ info->fbops->fb_imageblit(info, &image);
+ image.dx += cnt * vc->vc_font.width;
+ count -= cnt;
+ }
         } else {
                 image.width = vc->vc_font.width;
                 while (count--) {
                         image.data = p->fontdata +
- (scr_readw(s++) & charmask) * vc->vc_font.height * width;
+ (scr_readw(s++) & charmask) *
+ vc->vc_font.height * width;
                         info->fbops->fb_imageblit(info, &image);
                         image.dx += vc->vc_font.width;
                 }
         }
- /*
- if (pixmap);
- kfree(pixmap);
- */
 }
 
 void accel_clear_margins(struct vc_data *vc, struct display *p,
@@ -1271,16 +1276,9 @@
 
 int update_var(int con, struct fb_info *info)
 {
- int err;
+ if (con == info->currcon)
+ return fb_pan_display(&info->var, info);
 
- if (con == info->currcon) {
- if (info->fbops->fb_pan_display) {
- if ((err =
- info->fbops->fb_pan_display(&info->var,
- info)))
- return err;
- }
- }
         return 0;
 }
 
diff -Naur linux-2.5.54/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.5.54/drivers/video/fbmem.c 2003-01-02 13:10:54.000000000 +0000
+++ linux/drivers/video/fbmem.c 2003-01-02 13:10:18.000000000 +0000
@@ -1188,5 +1188,6 @@
 EXPORT_SYMBOL(fb_show_logo);
 EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
+EXPORT_SYMBOL(fb_pan_display);
 
 MODULE_LICENSE("GPL");

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Jan 07 2003 - 22:00:17 EST