kohler / gifsicle

Create, manipulate, and optimize GIF images and animations
http://www.lcdf.org/gifsicle/
GNU General Public License v2.0
3.77k stars 239 forks source link

Bad gif can cause segfault while access out of bounds memory #101

Closed strazzere closed 7 years ago

strazzere commented 7 years ago

While fuzzing I came across this following;

Starting program: /home/tstrazzere/repo/gifsicle/src/gifsicle -O2 repo_crash.min --output /dev/null
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
gifsicle:repo_crash.min:#0: read error: image corrupted, min_code_size too big
gifsicle:repo_crash.min:#0: read error: missing 6529 pixels of image data
gifsicle:repo_crash.min:#1: read error: image corrupted, min_code_size too big
gifsicle:repo_crash.min:#1: read error: missing 399 pixels of image data
gifsicle:repo_crash.min:#2: read error: image corrupted, min_code_size too big
gifsicle:repo_crash.min:#2: read error: missing 1081 pixels of image data
gifsicle:/dev/null: read error: image corrupted, min_code_size too big
gifsicle:/dev/null: read error: missing 6529 pixels of image data
gifsicle: warning: too many colors, using local colormaps
  (You may want to try ‘--colors 256’.)
gifsicle:/dev/null:#2: read error: image corrupted, min_code_size too big
gifsicle:/dev/null:#2: read error: missing 1081 pixels of image data

Program received signal SIGSEGV, Segmentation fault.
-----------------------------------------------------------------------------------------------------------------------[regs]
  RAX: 0x0000000000000000  RBX: 0x0000000000000021  RBP: 0x0000000000632180  RSP: 0x00007FFFFFFFE020  o d I t s Z a P c 
  RDI: 0x00007FFFF731EAEE  RSI: 0x0000000000000001  RDX: 0x0000000000000001  RCX: 0x0000000000000100  RIP: 0x000000000040C6B0
  R8 : 0x020000000063AC24  R9 : 0x0000000000000000  R10: 0x000000000063B608  R11: 0x00000000000000A2  R12: 0x000000000063B958
  R13: 0x00000000000F3F60  R14: 0x00007FFFF7133010  R15: 0x00000000000F3F30
  CS: 0033  DS: 0000  ES: 0000  FS: 0000  GS: 0000  SS: 002B                
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x40c6b0 <apply_frame16+384>:    movzx  edx,BYTE PTR [r8+rax*1]
   0x40c6b5 <apply_frame16+389>:    movzx  edx,WORD PTR [rsp+rdx*2+0x10]
   0x40c6ba <apply_frame16+394>:    mov    WORD PTR [rdi+rax*2],dx
   0x40c6be <apply_frame16+398>:    add    rax,0x1
   0x40c6c2 <apply_frame16+402>:    cmp    ebx,eax
   0x40c6c4 <apply_frame16+404>:    jg     0x40c6b0 <apply_frame16+384>
   0x40c6c6 <apply_frame16+406>:    add    r10,0x8
   0x40c6ca <apply_frame16+410>:    add    rdi,r11
-----------------------------------------------------------------------------------------------------------------------------
apply_frame16 (dst=0x7ffff731eaee, dst@entry=0x7ffff7133010, gfs=gfs@entry=0x62eb20, gfi=gfi@entry=0x632180, save_uncompressed=save_uncompressed@entry=0x0, replace=0x1) at opttemplate.c:164
164         dst[x] = map[gfi_pointer[x]];

This does not appear to be exploitable, though segfaulting is never good. Test case attached;

gfi_pointer_out_of_bounds.zip

kohler commented 7 years ago

Also could not replicate this.

strazzere commented 7 years ago

This one replicates for me using clang at HEAD on OSX and also gcc 4.9 on debian latest.

strazzere commented 7 years ago

Appears to be mitigated by a0a3651