Package: optipng Version: 0.7.6-1 Severity: normal Dear Maintainer,
global-buffer-overflow bug while parsing GIF file Running 'optipng' with the attached file raises global-buffer-overflow bug, which may allow a remote attacker to cause a denial-of-service attack or other unspecified impact with a crafted file. I expected the program to terminate without segfault, but the program crashes as follow ************************************************************************ * Please consider that this bug isn't found in default debian optipng * * which is installed by apt-get. * * This bug is only triggered when optipng was compiled by clang or by * * gcc without any optimizations. * ************************************************************************ ----------------------------- <logs with address sanitizer> june@june:~/project/analyze/poc/optipng$ optipng poc ** Processing: poc Warning: Bogus data in GIF ================================================================= ==11381==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55c9084bf040 at pc 0x55c908286630 bp 0x7fffd3831e40 sp 0x7fffd3831e38 WRITE of size 4 at 0x55c9084bf040 thread T0 ================================================================= ==11381==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55c9084bf040 at pc 0x55c908286630 bp 0x7fffd3831e40 sp 0x7fffd3831e38 WRITE of size 4 at 0x55c9084bf040 thread T0 #0 0x55c90828662f (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x7362f) #1 0x55c908285912 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x72912) #2 0x55c90828549f (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x7249f) #3 0x55c908284e00 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x71e00) #4 0x55c908239928 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x26928) #5 0x55c9082367a7 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x237a7) #6 0x55c908229674 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x16674) #7 0x55c90822b778 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x18778) #8 0x55c90822c9fe (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x199fe) #9 0x55c90822731e (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x1431e) #10 0x55c908227436 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x14436) #11 0x7fb1b02de2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) #12 0x55c908224389 (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x11389) 0x55c9084bf040 is located 0 bytes to the right of global variable 'stack' defined in 'gifread.c:401:16' (0x55c9084b7040) of size 32768 0x55c9084bf040 is located 32 bytes to the left of global variable 'oldcode' defined in 'gifread.c:398:27' (0x55c9084bf060) of size 4 SUMMARY: AddressSanitizer: global-buffer-overflow (/home/june/project/analyze/bins/optipng-0.7.6/src/optipng/optipng+0x7362f) Shadow bytes around the buggy address: 0x0ab9a108fdb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fdd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fde0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fdf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0ab9a108fe00: 00 00 00 00 00 00 00 00[f9]f9 f9 f9 04 f9 f9 f9 0x0ab9a108fe10: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 0x0ab9a108fe20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fe30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fe40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0ab9a108fe50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==11381==ABORTING <stack trace> (gdb) r poc Starting program: /usr/bin/optipng poc ** Processing: poc Warning: Bogus data in GIF Program received signal SIGSEGV, Segmentation fault. 0x000055555557d075 in LZWReadByte (init_flag=0, input_code_size=2, stream=0x55555579e010) at gifread.c:499 499 *sp++ = table[1][code]; (gdb) bt #0 0x000055555557d075 in LZWReadByte (init_flag=0, input_code_size=2, stream=0x55555579e010) at gifread.c:499 #1 0x000055555557ca05 in GIFReadImageData (image=0x7fffffffb310, stream=0x55555579e010) at gifread.c:261 #2 0x000055555557c846 in GIFReadNextImage (image=0x7fffffffb310, stream=0x55555579e010) at gifread.c:217 #3 0x000055555557c618 in GIFReadNextBlock (image=0x7fffffffb310, ext=0x7fffffffb2f0, stream=0x55555579e010) at gifread.c:163 #4 0x0000555555561055 in pngx_read_gif (png_ptr=0x55555579e240, info_ptr=0x55555579e4a0, stream=0x55555579e010) at pngxrgif.c:151 #5 0x000055555555f658 in pngx_read_image (png_ptr=0x55555579e240, info_ptr=0x55555579e4a0, fmt_name_ptr=0x7fffffffbc30, fmt_long_name_ptr=0x0) at pngxread.c:130 #6 0x0000555555558d3b in opng_read_file (infile=0x55555579e010) at optim.c:939 #7 0x000055555555a106 in opng_optimize_impl (infile_name=0x7fffffffe487 "poc") at optim.c:1503 #8 0x000055555555b01b in opng_optimize (infile_name=0x7fffffffe487 "poc") at optim.c:1853 #9 0x0000555555557525 in process_files (argc=2, argv=0x7fffffffe178) at optipng.c:941 #10 0x00005555555575da in main (argc=2, argv=0x7fffffffe178) at optipng.c:975 This bug happened because below loop worked infinitely. while (code >= clear_code) { *sp++ = table[1][code]; if (code == table[0][code]) GIFError("GIF/LZW error: circular table entry"); code = table[0][code]; } (gdb) p table[0] $3 = {0, 0, 0, 0, 0, 0, 3, 0, 0, 15, 9, 15, 8, 10, 1, 13, 0 <repeats 4080 times>} code value is assigned 15 -> 13 -> 10 -> 9 -> 15 -> 13 -> 10 -> 9 -> ... repetedely. 15, 13, 10, 9 are always bigger than clear_code so this loop runs forever and sp pointer will increase forever which causes buffer overflow. ----------------------------- The bug was found with a fuzzer developed by 'SoftSec' group at KAIST. -- System Information: Debian Release: 9.2 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'testing'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 4.9.0-3-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages optipng depends on: ii libc6 2.24-11+deb9u1 ii libpng16-16 1.6.28-1 ii zlib1g 1:1.2.8.dfsg-5 optipng recommends no packages. optipng suggests no packages. -- no debconf information