From https://bugs.debian.org/878839
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
<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.
Confirmed. Marking this defect as high severity.
Thank you very much for the report.
I am attaching an interim fix. See optipng-076-sfbug-69.patch
I have a bunch of changes and fixes (including this one) piled up, so new release is due. I cannot publish that release just yet, but I am targetting it for some time before the end of this year.
This issue got assigned CVE number CVE-2017-16938 in the meantime, so for reference: https://nvd.nist.gov/vuln/detail/CVE-2017-16938
Fixed in OptiPNG version 0.7.7. Thanks again for the report.