[Pkg-phototools-devel] Bug#878839: optipng: global-buffer-overflow bug while parsing GIF file

Joonun Jang joonun.jang at gmail.com
Tue Oct 17 04:10:15 UTC 2017


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 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: poc
Type: image/gif
Size: 94 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-phototools-devel/attachments/20171017/bfbb3708/attachment-0001.gif>


More information about the Pkg-phototools-devel mailing list