summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2011-02-21 21:33:29 +0100
committerAnatolij Gustschin <agust@denx.de>2011-04-28 21:30:46 +0200
commit74446b63dd4ec386fc5de554d5c4a3536096072f (patch)
tree43e21408379b18a47ca04285a0ac178c639a1429 /drivers
parenta000b7950da938d2df37ec5e081cd0680e6e4bbe (diff)
cfb_console: fix RLE bitmap drawing code
There seems to be tools producing incorrect 'end of bitmap data' markers '0100' in a RLE bitmap. Drawing such bitmaps can result in overwriting memory above the frame buffer. E.g. on MPC5121e based boards this memory can contain U-Boot environment. We may not rely on the correct end of bitmap data marker 0001 only, but also have to check whether we are going to draw a valid frame buffer scan line. The patch provides a fix by maintaining a pixel counter which is incremented by the amount of pixels we are going to draw. If the counter exceeds frame buffer pixels limit we stop the drawing with the error message. Reported-by: Michael Weiss <michael.weiss@ifm.com> Signed-off-by: Anatolij Gustschin <agust@denx.de> Tested-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/cfb_console.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index dd849c2dc1..b427c84877 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -882,6 +882,8 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
struct palette p[256];
bmp_color_table_entry_t cte;
int green_shift, red_off;
+ int limit = VIDEO_COLS * VIDEO_ROWS;
+ int pixels = 0;
x = 0;
y = __le32_to_cpu(img->header.height) - 1;
@@ -962,6 +964,10 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
/* unencoded run */
cnt = bm[1];
runlen = cnt;
+ pixels += cnt;
+ if (pixels > limit)
+ goto error;
+
bm += 2;
if (y < height) {
if (x >= width) {
@@ -970,7 +976,6 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
}
if (x + runlen > width)
cnt = width - x;
-
draw_bitmap (&fbp, bm, p, cnt, 0);
x += runlen;
}
@@ -982,9 +987,13 @@ next_run:
break;
default:
/* encoded run */
+ cnt = bm[0];
+ runlen = cnt;
+ pixels += cnt;
+ if (pixels > limit)
+ goto error;
+
if (y < height) { /* only draw into visible area */
- cnt = bm[0];
- runlen = cnt;
if (x >= width) {
x += runlen;
bm += 2;
@@ -992,7 +1001,6 @@ next_run:
}
if (x + runlen > width)
cnt = width - x;
-
draw_bitmap (&fbp, bm, p, cnt, 1);
x += runlen;
}
@@ -1001,6 +1009,9 @@ next_run:
}
}
return 0;
+error:
+ printf("Error: Too much encoded pixel data, validate your bitmap\n");
+ return -1;
}
#endif