libpng icon indicating copy to clipboard operation
libpng copied to clipboard

OOB Read in pngimage.c

Open BrieflyX opened this issue 5 years ago • 0 comments

I found an OOB read issue by fuzzing. The output of ASAN is like

==16275==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000cc00 at pc 0x000000405871 bp 0x7ffd58fd0740 sp 0x7ffd58fd0730
READ of size 1 at 0x60200000cc00 thread T0
    #0 0x405870 in compare_read contrib/libtests/pngimage.c:1240
    #1 0x406837 in test_one_file contrib/libtests/pngimage.c:1484
    #2 0x406ab8 in do_test contrib/libtests/pngimage.c:1564
    #3 0x4070da in main contrib/libtests/pngimage.c:1668
    #4 0x7ff8a144282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #5 0x401bd8 in _start (pngimage+0x401bd8)

0x60200000cc00 is located 0 bytes to the right of 16-byte region [0x60200000cbf0,0x60200000cc00)
allocated by thread T0 here:
    #0 0x7ff8a1da7602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x41e5c0 in png_malloc_base pngmem.c:95
    #2 0x41e785 in png_malloc pngmem.c:179
    #3 0x422470 in png_read_png pngread.c:1237
    #4 0x403962 in read_png contrib/libtests/pngimage.c:902
    #5 0x406826 in test_one_file contrib/libtests/pngimage.c:1483
    #6 0x406ab8 in do_test contrib/libtests/pngimage.c:1564
    #7 0x4070da in main contrib/libtests/pngimage.c:1668
    #8 0x7ff8a144282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

The related code is as follow: (line 1228 pngimage.c)

for (y=0; y<height; ++y)
         {
            png_bytep row = rows[y];
            png_bytep orig = dp->original_rows[y];
            unsigned long x;

            for (x=0; x<(width-(mask!=0)); ++x)
            {
               int b;

               for (b=0; b<bpp; ++b)
               {
                  if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))
                  {
                     display_log(dp, APP_FAIL,
                        "significant bits at (%lu[%u],%lu) changed %.2x->%.2x",
                        x, b, y, orig[-1], row[-1]);
                     return 0;
                  }
               }
            }

The poc IHDR has 32x32 image size and bits 4, which leads rowbytes = 0x10. However, code above uses width (32) to access row array, thus causes out of bound read.

poc

BrieflyX avatar Oct 25 '19 10:10 BrieflyX