oss-sec mailing list archives

[Bug report] Vulnerability In libbpg-2


From: "wykcomputer () gmail com" <wykcomputer () gmail com>
Date: Fri, 18 Nov 2016 16:55:12 +0800

Hello,
I find a out-of-bounds write issue in libbpg(0.9.7, maybe other early versions), which can lead to memory corruption or 
even remote code execution.
I have reported it to the author of libbpg, but no responding, so I report it to you.

Run ./bpgenc PoC.jpg out.bpg, get the crash as follows.
Crash Log:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004069ce in gray8_to_gray (s=0x7fffffffd320, y_ptr=0x0, 
    src=0x7ffff0000df0 "\233\264\237\255\257\252\256\253", '\254' <repeats 56 times>, 'Y' <repeats 24 times>, 
"\020\342T]P\023\233q\377\377\377\377\377\377\377\377", 'w' <repeats 64 times>, "vwx{uw~m\221", '\377' <repeats 23 
times>..., n=65260, incr=1) at bpgenc.c:255
255         y_ptr[i] = (c * g + rnd) >> shift;
(gdb) bt
#0  0x00000000004069ce in gray8_to_gray (s=0x7fffffffd320, y_ptr=0x0, 
    src=0x7ffff0000df0 "\233\264\237\255\257\252\256\253", '\254' <repeats 56 times>, 'Y' <repeats 24 times>, 
"\020\342T]P\023\233q\377\377\377\377\377\377\377\377", 'w' <repeats 64 times>, "vwx{uw~m\221", '\377' <repeats 23 
times>..., n=65260, incr=1) at bpgenc.c:255
#1  0x000000000040a0d3 in read_jpeg (pmd=0x7fffffffd8f8, f=0x11ca730, out_bit_depth=8) at bpgenc.c:1368
#2  0x000000000040a496 in load_image (pmd=0x7fffffffd978, infilename=0x7fffffffe28a 
"../libbpg-0.9.7/out_enc_jpg/crashes/0.jpg", color_space=BPG_CS_YCbCr, bit_depth=8, limited_range=0, 
    premultiplied_alpha=0) at bpgenc.c:1451
#3  0x000000000040e0e1 in main (argc=4, argv=0x7fffffffdeb8) at bpgenc.c:2942

read_jpeg function in bpgenc.c, img->data[i] = malloc(linesize * h1), linesize * h1 maybe integer over-flow(larger than 
0xffffffff), this lead to malloc a smaller memory than expected, when execute to gray8_to_gray, maybe cause 
out-of-bounds write.

Image *read_jpeg(BPGMetaData **pmd, FILE *f, int out_bit_depth)
//...
img = image_alloc(w, h, format, has_alpha, color_space, out_bit_depth);
|
|->for(i = 0; i < c_count; i++) {
get_plane_res(img, &w1, &h1, i);
/* multiple of 16 pixels to add borders */
w1 = (w1 + (W_PAD - 1)) & ~(W_PAD - 1);
h1 = (h1 + (W_PAD - 1)) & ~(W_PAD - 1);

linesize = w1 << img->pixel_shift;
img->data[i] = malloc(linesize * h1);//maybe integer overflow

//...
ptr = (PIXEL *)(img->data[idx] + 
                                    img->linesize[idx] * (y1 + i));
        gray8_to_gray(cvt, ptr, rows[c_idx][i], w1, 1);
|
|->y_ptr[i] = (c * g + rnd) >> shift;

Fix:
To check the integer overflow issue. Such as,
linesize = w1 << img->pixel_shift;
+ uint64_t tmp = (uint64_t)linesize * h1;
+ if(tmp > 0xffffffff)
return NULL;
img->data[i] = malloc(linesize * h1);

Thank you for your reading!


wykcomputer () gmail com

Attachment: PoC.jpg
Description:


Current thread: