DentonW / DevIL

Developer's Image Library (DevIL) is a cross-platform image library utilizing a simple syntax to load, save, convert, manipulate, filter, and display a variety of images with ease. It is highly portable and has been ported to several platforms.
http://openil.sourceforge.net/
GNU Lesser General Public License v2.1
446 stars 138 forks source link

Invalid write / SIGSEGV #61

Open stze opened 7 years ago

stze commented 7 years ago

Following sample file crashes libdevil. The bug was found using examples/simple_example/simple.c with the sample file as input. Sample gif input file is fuzzed with american fuzzy lop http://lcamtuf.coredump.cx/afl/.

sample file hexdump:

00000000  47 49 46 38 39 61 10 00  00 00 f7 ff 00 00 00 00  |GIF89a..........|
00000010  03 04 04 04 05 05 05 06  06 06 07 07 07 08 08 08  |................|
00000020  09 09 09 0a 0a 0a 0b 0b  0b 0c 0c 0c 0d 0d 0d 0e  |................|
00000030  0e 0e 0f 0f 0f 10 10 10  11 11 11 12 12 12 13 13  |................|
00000040  13 14 14 14 15 15 15 16  16 16 17 17 17 18 18 18  |................|
00000050  19 19 19 1a 1a 1a 1b 1b  1b 1c 1c 1c 1d 1d 1d 1e  |................|
00000060  1e 1e 1f 1f 1f 20 20 20  21 21 21 22 22 22 23 23  |.....   !!!"""##|
00000070  23 24 24 24 25 25 25 26  26 26 27 27 27 28 28 28  |#$$$%%%&&&'''(((|
00000080  29 29 29 2a 2a 2a 2b 2b  2b 2c 2c 2c 2d 2d 2d 2e  |)))***+++,,,---.|
00000090  2e 2e 2f 2f 2f 30 30 30  31 31 31 32 32 32 33 33  |..///00011122233|
000000a0  33 34 34 34 35 35 35 36  36 36 37 37 37 38 38 38  |3444555666777888|
000000b0  39 39 39 3a 3a 3a 3b 3b  3b 3c 3c 3c 3d 3d 3d 3e  |999:::;;;<<<===>|
000000c0  3e 3e 3f 3f 3f 40 40 40  41 41 41 42 42 42 43 43  |>>???@@@AAABBBCC|
000000d0  43 44 44 44 45 45 45 46  46 46 47 47 47 48 48 48  |CDDDEEEFFFGGGHHH|
000000e0  49 49 49 4a 4a 4a 4b 4b  4b 4c 4c 4c 4d 4d 4d 4e  |IIIJJJKKKLLLMMMN|
000000f0  4e 4e 4f 4f 4f 50 50 50  51 51 51 52 52 52 53 53  |NNOOOPPPQQQRRRSS|
00000100  53 54 54 54 55 55 55 56  56 56 57 57 57 58 58 58  |STTTUUUVVVWWWXXX|
00000110  59 59 59 5a 5a 5a 5b 5b  5b 5c 5c 5c 5d 5d 5d 5e  |YYYZZZ[[[\\\]]]^|
00000120  5e 5e 5f 5f 5f 60 60 60  61 61 61 62 62 62 63 63  |^^___```aaabbbcc|
00000130  63 64 64 64 65 65 65 66  66 66 67 67 67 68 68 68  |cdddeeefffggghhh|
00000140  69 69 69 6a 6a 6a 6b 6b  6b 6c 6c 6c 6d 6d 6d 6e  |iiijjjkkklllmmmn|
00000150  6e 6e 6f 6f 6f 70 70 70  71 71 71 72 72 72 73 73  |nnooopppqqqrrrss|
00000160  73 74 74 74 75 75 75 76  76 76 77 77 77 78 78 78  |stttuuuvvvwwwxxx|
00000170  79 79 79 7a 7a 7a 7b 7b  7b 7c 7c 7c 7d 7d 7d 7e  |yyyzzz{{{|||}}}~|
00000180  7e 7e 7f 7f 7f 80 80 80  81 81 81 82 82 82 83 83  |~~..............|
00000190  83 84 84 84 85 85 85 86  86 86 87 87 87 88 88 88  |................|
000001a0  89 89 89 8a 8a 8a 8b 8b  8b 8c 8c 8c 8d 8d 8d 8e  |................|
000001b0  8e 8e 8f 8f 8f 90 90 90  91 91 91 92 92 92 93 93  |................|
000001c0  93 94 94 94 95 95 95 96  96 96 97 97 97 98 98 98  |................|
000001d0  99 99 99 9a 9a 9a 9b 9b  9b 9c 9c 9c 9d 9d 9d 9e  |................|
000001e0  9e 9e 9f 9f 9f a0 a0 a0  a1 a1 a1 a2 a2 a2 a3 a3  |................|
000001f0  a3 a4 a4 a4 a5 a5 a5 a6  a6 a6 a7 a7 a7 a8 a8 a8  |................|
00000200  a9 a9 a9 aa aa aa ab ab  ab ac ac ac ad ad ad ae  |................|
00000210  ae ae af af af b0 b0 b0  b1 b1 b1 b2 b2 b2 b3 b3  |................|
00000220  b3 b4 b4 b4 b5 b5 b5 b6  b6 b6 b7 b7 b7 b8 b8 b8  |................|
00000230  b9 b9 b9 ba ba ba bb bb  bb bc bc bc bd bd bd be  |................|
00000240  be be bf bf bf c0 c0 c0  c1 c1 c1 c2 c2 c2 c3 c3  |................|
00000250  c3 c4 c4 c4 c5 c5 c5 c6  c6 c6 c7 c7 c7 c8 c8 c8  |................|
00000260  c9 c9 c9 ca ca ca cb cb  cb cc cc cc cd cd cd ce  |................|
00000270  ce ce cf cf cf d0 d0 d0  d1 d1 d1 d2 d2 d2 d3 d3  |................|
00000280  d3 d4 d4 d4 d5 d5 d5 d6  d6 d6 d7 d7 d7 d8 d8 d8  |................|
00000290  d9 d9 d9 da da da db db  db dc dc dc dd dd dd de  |................|
000002a0  de de df df df e0 e0 e0  e1 e1 e1 e2 e2 e2 e3 e3  |................|
000002b0  e3 e4 e4 e4 e5 e5 e5 e6  e6 e6 e7 e7 e7 e8 e8 e8  |................|
000002c0  e9 e9 e9 ea ea ea eb eb  eb ec ec ec ed ed ed ee  |................|
000002d0  ee ee ef ef ef f0 f0 f0  f1 f1 f1 f2 f2 f2 f3 f3  |................|
000002e0  f3 f4 f4 f4 f5 f5 f5 f6  f6 f6 f7 f7 f7 f8 f8 f8  |................|
000002f0  f9 f9 f9 fa fa fa fb fb  fb fc fc fc fd fd fd fe  |................|
00000300  fe fe ff ff ff 21 f9 04  00 00 00 00 00 2c 00 00  |.....!.......,..|
00000310  00 00 10 00 10 00 00 08  80 02 06 05 18 2c a8 10  |.............,..|
00000320  10 40 c4 7f fd 04 ea f3  f7 cf df 41 82 04 02 74  |.@.........A...t|
00000330  8c 28 20 40 44 92 02 2b  3e 84 68 70 e5 bf 8a 04  |.( @D..+>.hp....|
00000340  4d 3e f4 47 b1 20 00 8a  06 07 22 20 08 13 e3 bf  |M>.G. ...." ....|
00000350  7d 22 21 be 0c 10 60 20  00 01 fd 3a 4a f4 97 94  |}"!...` ...:J...|
00000360  9f 51 85 44 2f 7a 5c a9  af 80 4d a3 b7 b2 a2 01  |.Q.D/z\...M.....|
00000370  82 08 79 02 f8 5a d0 2a  cc b3 0b 05 40 3d 9a b3  |..y..Z.*....@=..|
00000380  62 51 b4 09 2b 2a 1c 58  60 e0 00 01 77 79 7e 95  |bQ..+*.X`...wy~.|
00000390  0b 73 6d c3 82 36 71 36  1c 1c 10 00              |.sm..6q6....|
0000039c

How to reproduce:

# clang -o simple examples/simple_example/simple.c -lIL -lILU -lILUT
# ./simple <sample-file>

gdb:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff731ea35 in getc () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff731ea35 in getc () from /usr/lib/libc.so.6
#1  0x00007ffff789db28 in iDefaultGetc () from build/lib/x64/libIL.so
#2  0x00007ffff789df4e in iGetcFile() () from build/lib/x64/libIL.so
#3  0x00007ffff78a0cc8 in GetImages(ILpal*, GIFHEAD*) () from build/lib/x64/libIL.so
#4  0x00007ffff78a0604 in iLoadGifInternal() () from build/lib/x64/libIL.so
#5  0x00007ffff78a0416 in ilLoadGifF () from build/lib/x64/libIL.so
#6  0x00007ffff78a03bd in ilLoadGif () from build/lib/x64/libIL.so
#7  0x00007ffff78ab4fe in ilLoad () from build/lib/x64/libIL.so
#8  0x00007ffff78ac315 in ilLoadImage () from build/lib/x64/libIL.so
#9  0x00000000004010c9 in main (argc=2, argv=0x7fffffffe5c8) at examples/simple_example/simple.c:64

valgrind:

==25225== Memcheck, a memory error detector                                                  
==25225== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25225== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25225== Command: build/lib/x64/simple findings/crashes/id:000001,sig:11,src:000000,op:flip1,pos:8
==25225== 
==25225== Conditional jump or move depends on uninitialised value(s)
==25225==    at 0x509D649: GifGetData(ILimage*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, GFXCONTROL*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509CC26: GetImages(ILpal*, GIFHEAD*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C603: iLoadGifInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C415: ilLoadGifF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C3BC: ilLoadGif (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A74FD: ilLoad (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A8314: ilLoadImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4010C8: main (simple.c:64)
==25225==  Uninitialised value was created by a heap allocation
==25225==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25225==    by 0x50752A4: DefaultAllocFunc(unsigned long) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5075193: ialloc (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509D2FC: GifGetData(ILimage*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, GFXCONTROL*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509CC26: GetImages(ILpal*, GIFHEAD*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C603: iLoadGifInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C415: ilLoadGifF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C3BC: ilLoadGif (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A74FD: ilLoad (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A8314: ilLoadImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4010C8: main (simple.c:64)
==25225== 
==25225== Invalid write of size 1
==25225==    at 0x509D84A: GifGetData(ILimage*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, GFXCONTROL*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509CC26: GetImages(ILpal*, GIFHEAD*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C603: iLoadGifInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C415: ilLoadGifF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C3BC: ilLoadGif (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A74FD: ilLoad (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A8314: ilLoadImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4010C8: main (simple.c:64)
==25225==  Address 0xa192610 is 0 bytes after a block of size 16 alloc'd
==25225==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25225==    by 0x50752A4: DefaultAllocFunc(unsigned long) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5075193: ialloc (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5091B77: ilInitImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5091FE3: ilTexImage_ (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5091E62: ilTexImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C598: iLoadGifInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C415: ilLoadGifF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C3BC: ilLoadGif (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A74FD: ilLoad (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A8314: ilLoadImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4010C8: main (simple.c:64)
==25225== 
Width: 16  Height: 1  Depth: 1  Bpp: 8
==25225== Syscall param write(buf) points to uninitialised byte(s)
==25225==    at 0x569D3C0: __write_nocancel (in /usr/lib/libc-2.25.so)
==25225==    by 0x5632F96: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x5632231: new_do_write (in /usr/lib/libc-2.25.so)
==25225==    by 0x5634078: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x5633937: _IO_file_close_it@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x5626DEE: fclose@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x5099CC4: iDefaultCloseW(void*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50D1435: ilSaveTarga (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A9960: ilSaveImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4011C0: main (simple.c:83)
==25225==  Address 0xa197790 is 800 bytes inside a block of size 4,096 alloc'd
==25225==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25225==    by 0x5626B6B: _IO_file_doallocate (in /usr/lib/libc-2.25.so)
==25225==    by 0x5635285: _IO_doallocbuf (in /usr/lib/libc-2.25.so)
==25225==    by 0x5634577: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x5633635: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib/libc-2.25.so)
==25225==    by 0x56281CA: fwrite (in /usr/lib/libc-2.25.so)
==25225==    by 0x5099D2A: iDefaultWrite (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509A82C: iWriteFile(void const*, unsigned int, unsigned int) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50D15FB: iSaveTargaInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50D1485: ilSaveTargaF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50D1417: ilSaveTarga (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A9960: ilSaveImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==  Uninitialised value was created by a heap allocation
==25225==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25225==    by 0x50752A4: DefaultAllocFunc(unsigned long) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x5075193: ialloc (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509D2FC: GifGetData(ILimage*, unsigned char*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, GFXCONTROL*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509CC26: GetImages(ILpal*, GIFHEAD*) (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C603: iLoadGifInternal() (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C415: ilLoadGifF (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x509C3BC: ilLoadGif (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A74FD: ilLoad (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x50A8314: ilLoadImage (in /tmp/DevIL/build/lib/x64/libIL.so.1)
==25225==    by 0x4010C8: main (simple.c:64)
==25225== 
==25225== 
==25225== HEAP SUMMARY:
==25225==     in use at exit: 32 bytes in 1 blocks
==25225==   total heap usage: 113 allocs, 112 frees, 133,452 bytes allocated
==25225== 
==25225== LEAK SUMMARY:
==25225==    definitely lost: 0 bytes in 0 blocks
==25225==    indirectly lost: 0 bytes in 0 blocks
==25225==      possibly lost: 0 bytes in 0 blocks
==25225==    still reachable: 32 bytes in 1 blocks
==25225==         suppressed: 0 bytes in 0 blocks
==25225== Rerun with --leak-check=full to see details of leaked memory
==25225== 
==25225== For counts of detected and suppressed errors, rerun with: -v
==25225== ERROR SUMMARY: 82 errors from 3 contexts (suppressed: 0 from 0)