Menu

#53 Buffer overflow in global memory affecting optipng 0.7.5

v1.0 (example)
closed-fixed
None
9
2016-04-04
2015-09-23
g042
No

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.

1 Attachments

Discussion

  • Cosmin Truta

    Cosmin Truta - 2015-10-05

    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:

    --- src/gifread/gifread.c
    +++ src/gifread/gifread.c
    @@ -12,7 +12,7 @@
      * The original copyright notice is provided below.
      * <pre>
      * +-------------------------------------------------------------------+
    - * | Copyright 1990, 1991, 1993, David Koblas.  (koblas@netcom.com)    |
    + * | Copyright 1990 - 1994, David Koblas. (koblas@netcom.com)          |
      * |   Permission to use, copy, modify, and distribute this software   |
      * |   and its documentation for any purpose and without fee is hereby |
      * |   granted, provided that the above copyright notice appear in all |
    @@ -357,6 +357,7 @@ static int LZWGetCode(int code_size, int init_flag, FILE *stream)
         {
             curbit = 0;
             lastbit = 0;
    +        last_byte = 2;
             done = LZW_FALSE;
             return 0;
         }
    
     
  • Cosmin Truta

    Cosmin Truta - 2015-10-05
    • status: open --> open-accepted
    • assigned_to: Cosmin Truta
    • Priority: 5 --> 9
     
    • g042

      g042 - 2015-10-05

      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:

      • status: open --> open-accepted
      • assigned_to: Cosmin Truta
      • Priority: 5 --> 9

      [bugs:#53] Buffer overflow in global memory affecting optipng 0.7.5

      Status: open-accepted
      Group: v1.0 (example)
      Labels: security
      Created: Wed Sep 23, 2015 11:59 AM UTC by g042
      Last Updated: Mon Oct 05, 2015 05:14 AM UTC
      Owner: Cosmin Truta
      Attachments:

      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.


      Sent from sourceforge.net because you indicated interest in <
      https://sourceforge.net/p/optipng/bugs/53/>

      To unsubscribe from further messages, please visit <
      https://sourceforge.net/auth/subscriptions/>

       
  • Cosmin Truta

    Cosmin Truta - 2015-10-14
    • labels: security -->
    • private: Yes --> No
     
  • Ramona Truta

    Ramona Truta - 2016-04-04
    • status: open-accepted --> closed-fixed
     
  • Ramona Truta

    Ramona Truta - 2016-04-04

    Fixed in version 0.7.6.

     

Log in to post a comment.