Menu

#89 Buffer over-read in gifbuild due to extra data after netscape extension block

v1.0_(example)
closed
nobody
None
1
2016-03-29
2016-03-28
No

Hi,

Found this with afl-fuzz, can create a segfault on gifbuild when compiled with ASAN, due to a buffer overread. The cause was found to be due to there not being a block after the netscape extension block, and a read still taking place. The input file is below, then the output of the crash, and a patch to fix below that. I'll upload a git format patch as a comment.

 $ xxd -g 1 netscape-one-after.gif 
0000000: 47 49 46 30 30 30 30 30 30 30 f2 30 30 30 30 30  GIF0000000.00000
0000010: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
0000020: 30 30 30 30 30 21 ff 18 4e 45 54 53 43 41 50 45  00000!..NETSCAPE
0000030: 32 2e 30 30 30 30 30 30 30 30 30 30 30 30 30 30  2.00000000000000
0000040: 00 2c 30 30 30 30 00 00 30 30 30 03 8b 30 30 30  .,0000..000..000
0000050: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
0000060: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
0000070: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
0000080: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
0000090: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
00000a0: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
00000b0: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
00000c0: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30  0000000000000000
00000d0: 30 30 30 30 30 30 30 30 00 3b                    00000000.;
 $ ASAN_OPTIONS="abort_on_error=1 symbolize=1" ./util/.libs/lt-gifbuild -d netscape-one-after.gif 
#
# GIF information from netscape-one-after.gif
screen width 12336
screen height 12336
screen colors 256
screen background 48
pixel aspect byte 48

screen map
        sort flag off
        rgb 048 048 048 is 0
        rgb 048 048 048 is 1
        rgb 048 048 048 is 2
        rgb 048 048 048 is 3
        rgb 048 048 048 is 4
        rgb 048 048 048 is 5
        rgb 048 048 048 is 6
        rgb 048 048 048 is 7
end

=================================================================
==21834== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60060000efa0 at pc 0x404a5a bp 0x7ffcfc998830 sp 0x7ffcfc998828
READ of size 8 at 0x60060000efa0 thread T0
    #0 0x404a59 in DumpExtensions.isra.0 /root/giflib-code/util/gifbuild.c:729
    #1 0x405871 in Gif2Icon.isra.1 /root/giflib-code/util/gifbuild.c:804
    #2 0x402196 in main /root/giflib-code/util/gifbuild.c:100
    #3 0x7f79e8bc6ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #4 0x402761 in _start (/root/giflib-code/util/.libs/lt-gifbuild+0x402761)
0x60060000efa0 is located 8 bytes to the right of 24-byte region [0x60060000ef80,0x60060000ef98)
allocated by thread T0 here:
    #0 0x7f79e91b441a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1541a)
    #1 0x7f79e8f92f77 in GifAddExtensionBlock /root/giflib-code/lib/gifalloc.c:233
SUMMARY: AddressSanitizer: heap-buffer-overflow /root/giflib-code/util/gifbuild.c:729 fprintf
Shadow bytes around the buggy address:
  0x0c013fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9de0: fa fa fa fa fa fa fa fa fa fa 00 00 00 fa fa fa
=>0x0c013fff9df0: 00 00 00 fa[fa]fa 00 00 00 fa fa fa 00 00 00 fa
  0x0c013fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c013fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==21834== ABORTING
Aborted
diff --git a/util/gifbuild.c b/util/gifbuild.c
index 42edce5..c55192e 100644
--- a/util/gifbuild.c
+++ b/util/gifbuild.c
@@ -723,7 +723,8 @@ static void DumpExtensions(GifFileType *GifFileOut,
            printf("\ttransparent index %d\n", gcb.TransparentColor);
            printf("end\n\n");
        }
-       else if (ep->Function == APPLICATION_EXT_FUNC_CODE 
+       else if (!last
+                && ep->Function == APPLICATION_EXT_FUNC_CODE
                 && ep->ByteCount >= 11
                 && memcmp(ep->Bytes, "NETSCAPE2.0", 11) == 0) {
            unsigned char *params = (++ep)->Bytes;

Cheers,

Hugh

Discussion

  • Eric S. Raymond

    Eric S. Raymond - 2016-03-29

    Merged, thanks.

     
  • Eric S. Raymond

    Eric S. Raymond - 2016-03-29
    • status: open --> closed
    • private: Yes --> No
     

Log in to post a comment.