Hi,
We found a buffer overflow in global memory affecting optipng 0.7.5 (and probably other versions) using a gif file. Find attached the test case. ASAN report is here:
$ ./optipng g.gif.-1694659802519428239
Processing: g.gif.-1694659802519428239
Warning: Bogus data in GIF
==24439== ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000069541e at pc 0x46d24b bp 0x7ffca6545830 sp 0x7ffca6545828
READ of size 1 at 0x00000069541e thread T0
#0 0x46d24a (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x46d24a)
#1 0x46d724 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x46d724)
#2 0x46cfe8 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x46cfe8)
#3 0x46cbde (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x46cbde)
#4 0x46c35b (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x46c35b)
#5 0x41c013 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x41c013)
#6 0x418878 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x418878)
#7 0x408c9a (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x408c9a)
#8 0x40c309 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x40c309)
#9 0x40e7c5 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x40e7c5)
#10 0x404f3b (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x404f3b)
#11 0x40503d (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x40503d)
#12 0x7fe3b26f8ec4 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21ec4)
#13 0x401848 (/home/vagrant/repos/optipng-0.7.5/src/optipng/optipng+0x401848)
0x00000069541e is located 58 bytes to the right of global variable 'last_byte (gifread.c)' (0x6953e0) of size 4
'last_byte (gifread.c)' is ascii string ''
0x00000069541e is located 2 bytes to the left of global variable 'buffer (gifread.c)' (0x695420) of size 280
'buffer (gifread.c)' is ascii string ''
Shadow bytes around the buggy address:
0x0000800caa30: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0000800caa40: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0000800caa50: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0000800caa60: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0000800caa70: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
=>0x0000800caa80: f9 f9 f9[f9]00 00 00 00 00 00 00 00 00 00 00 00
0x0000800caa90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800caaa0: 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0000800caab0: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0000800caac0: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x0000800caad0: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
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 righ 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
ASan internal: fe
==24439== ABORTING
Regards,
Gustavo.
Hello, Gustavo, and thank you very much for your report.
I confirm the error reported by ASAN, and I also confirm that all versions of OptiPNG that can read GIF files (i.e. all versions from v0.5 onwards) are affected.
Fortunately, it's benign: there is storage of uninitialized data into buffer[0] and buffer[1] inside the LZWGetCode, but that is discarded later, and no actual data loss occurs. In theory, it could crash due to reading from buffer[-1] and buffer[-2]; in practice, it (luckily) didn't, because the buffer (luckily) is sandwitched between other static globals in the BSS segment.
This is why it was never caught before, neither by regular use or conventional testing, nor by memory checkers such as Valgrind. I'm glad it was caught by ASAN.
The fix to this is easy, and already available in David Koblas' original GIFREAD.C code. (The OptiPNG GIF reader was forked off from the 1993 version; the fix is present in the 1994 version, found, for example, in GIF2PNG.) Here is the cherry-picked fix:
Great job!. Let me know when this patch is applied so i can email to
oss-security to remind the people in different OS to upgrade their optipng
packages. Later i will continue my testing of optipng.
Regards,
Gustavo.
2015-10-05 7:23 GMT+02:00 Cosmin Truta cosmin@users.sf.net:
Fixed in version 0.7.6.