Bug 1284421 (CVE-2015-7507, CVE-2015-7508) - CVE-2015-7507 CVE-2015-7508 libnsbmp: Heap overflow in bmp_decode_rle() and out-of-bounds read in bmp_decode_rle()/bmp_decode_rgb()
Summary: CVE-2015-7507 CVE-2015-7508 libnsbmp: Heap overflow in bmp_decode_rle() and o...
Keywords:
Status: CLOSED UPSTREAM
Alias: CVE-2015-7507, CVE-2015-7508
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1292162
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-11-23 10:14 UTC by Adam Mariš
Modified: 2019-09-29 13:40 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-06-08 02:45:46 UTC


Attachments (Terms of Use)

Description Adam Mariš 2015-11-23 10:14:13 UTC
1. CVE-2015-7508:
A heap-based buffer overflow vulnerability was found in bmp_decode_rle function when processing run-length endoded BMP data, that can expand beyond the allocated buffer.

Vulnerable code:

951: static bmp_result bmp_decode_rle(bmp_image *bmp, uint8_t *data, int bytes, int size) {
[...]
962: swidth = bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bitmap) * bmp->width;
963: top = bmp->bitmap_callbacks.bitmap_get_buffer(bmp->bitmap);
[...]
973: length = *data++;
[...]
1048: /* NN means perform RLE for NN pixels */
1049: if (bmp->reversed) {
1050: pixels_left = (y + 1) * bmp->width - x;
1051: scanline = (void *)(top + (y * swidth));
1052: } else {
1053: pixels_left = (bmp->height - y + 1) * bmp->width - x;
1054: scanline = (void *)(bottom - (y * swidth));
1055: }
1056: if (length > pixels_left)
1057: length = pixels_left;
[...]
1078: pixel2 = *data++;
1079: pixel = bmp->colour_table[pixel2 >> 4];
1080: pixel2 = bmp->colour_table[pixel2 & 0xf];
1081: for (i = 0; i < length; i++) {
1082: if (x >= bmp->width) {
1083: x = 0;
1084: if (++y > bmp->height)
1085: return BMP_DATA_ERROR;
1086: scanline -= bmp->width;
1087: }
1088: if ((i & 1) == 0)
1089: scanline[x++] = pixel;
1090: else
1091: scanline[x++] = pixel2;
1092: }

libnsbmp expects that the user-supplied `bmp_bitmap_cb_create` callback allocates enough memory to accommodate for `bmp->width * bmp->height * bmp->bpp` bytes of data. Due to the way `pixels_left` is calculated, the last row of BMP-encoded data may expand beyond the end of `bmp->bitmap`.

2. CVE-2015-7508:
An out-of-bounds read due to a lack of boundary checking before  dereferencing `bmp->colour_table` in `bmp_decode_rgb()` and `bmp_decode_rle()` with an index based on a user-supplied value was found.

Vulnerable code:

306: static bmp_result bmp_analyse_header(bmp_image *bmp, uint8_t *data) {
[...]
319: header_size = read_uint32(data, 0);
[...]
322: if (header_size == 12) {
323: /* the following header is for os/2 and windows 2.x and consists of:
324: *
325: * +0 UINT32 size of this header (in bytes)
326: * +4 INT16 image width (in pixels)
327: * +6 INT16 image height (in pixels)
328: * +8 UINT16 number of colour planes (always 1)
329: * +10 UINT16 number of bits per pixel
330: */
[...]
358: bmp->bpp = read_uint16(data, 10);
359: /**
360: * The bpp value should be in the range 1-32, but the only
361: * values considered legal are:
362: * RGB ENCODING: 1, 4, 8, 16, 24 and 32
363: */
364: if ((bmp->bpp != 1) && (bmp->bpp != 4) &&
365: (bmp->bpp != 8) &&
366: (bmp->bpp != 16) &&
367: (bmp->bpp != 24) &&
368: (bmp->bpp != 32))
369: return BMP_DATA_ERROR;
370: bmp->colours = (1 << bmp->bpp);
[...]
374: } else {
[...]
501: bmp->colours = read_uint32(data, 32);
502: if (bmp->colours == 0)
503: bmp->colours = (1 << bmp->bpp);
504: palette_size = 4;
505: }
[...]
515: if (bmp->bpp < 16) {
[...]
531: bmp->colour_table = (uint32_t *)malloc(bmp->colours * 4);
532: if (!bmp->colour_table)
533: return BMP_INSUFFICIENT_MEMORY;
534: for (i = 0; i < bmp->colours; i++) {
535: bmp->colour_table[i] = data[2] | (data[1] << 8) | (data[0] << 16);
536: if (bmp->opaque)
537: bmp->colour_table[i] |= (0xff << 24);
538: data += palette_size;
539: bmp->colour_table[i] = read_uint32((uint8_t *)&bmp->colour_table[i],0);
540: }
541: }
[...]

844: static bmp_result bmp_decode_rgb(bmp_image *bmp, uint8_t **start, int bytes) {
845: uint8_t *top, *bottom, *end, *data;
846: uint32_t *scanline;
847: intptr_t addr;
848: uint32_t x, y, swidth;
849: uint8_t bit_shifts[8];
850: uint8_t ppb = 8 / bmp->bpp;
851: uint8_t bit_mask = (1 << bmp->bpp) - 1;
852: uint8_t cur_byte = 0, bit, i;
853:
854: for (i = 0; i < ppb; i++)
855: bit_shifts[i] = 8 - ((i + 1) * bmp->bpp);
856: data = *start;
[..]
868: if (bmp->limited_trans)
869: bmp->transparent_index = bmp->colour_table[(*data >> bit_shifts[0]) & bit_mask];
[...]
871: for (y = 0; y < bmp->height; y++) {
[...]
874: bit = 8;
[...]
881: for (x = 0; x < bmp->width; x++) {
882: if (bit >= ppb) {
883: bit = 0;
884: cur_byte = *data++;
885: }
886: scanline[x] = bmp->colour_table[(cur_byte >> bit_shifts[bit++]) & bit_mask];
[...]

These issues affect libnsbmp <= 0.1.2

Comment 3 Martin Prpič 2015-12-16 15:37:04 UTC
Created libnsbmp tracking bugs for this issue:

Affects: fedora-all [bug 1292162]

Comment 4 Martin Prpič 2015-12-16 15:37:28 UTC
External References:

http://seclists.org/bugtraq/2015/Dec/87

Comment 5 Product Security DevOps Team 2019-06-08 02:45:46 UTC
This CVE Bugzilla entry is for community support informational purposes only as it does not affect a package in a commercially supported Red Hat product. Refer to the dependent bugs for status of those individual community products.


Note You need to log in before you can comment on or make changes to this bug.