Headline
CVE-2020-15470: ffjpeg "jfif_decode()" function heap-overflow vulnerability · Issue #26 · rockcarry/ffjpeg
ffjpeg through 2020-02-24 has a heap-based buffer overflow in jfif_decode in jfif.c.
ffjpeg "jfif_decode()" function heap-overflow vulnerability
Description:
There is a heap-overflow bug in jfif_decode(void *ctxt, BMP *pb) function at ffjpeg/src/jfif.c : line 516.
An attacker can exploit this bug to cause a Denial of Service (DoS) by submitting a malicious jpeg image.
The bug is caused by the following dangerous memcpy calling in jfif_decode() function:
for (i=0; i<8; i++) {
memcpy(idst, isrc, 8 * sizeof(int));
idst += yuv_stride[c];
isrc += 8;
}
We used AddressSanitizer instrumented in ffjpeg and triggered this bug, the asan output is:
root@01964a1f36aa:~/ffjpeg/src# ./ffjpeg -d …/crashout/SIGABRT.PC.43a618.STACK.186c7604dd.CODE.-6.ADDR.0.INSTR.pushq__$0x0.fuzz
==40906==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f3d587ffc00 at pc 0x0000004a6134 bp 0x7ffe72bc97d0 sp 0x7ffe72bc8f80
WRITE of size 32 at 0x7f3d587ffc00 thread T0
#0 0x4a6133 in __asan_memcpy /root/llvm-project/llvm/projects/compiler/lib/asan/asan_interceptors_memintrinsics.cc:22
#1 0x4f24df in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f24df)
#2 0x4eb545 in main (/root/ffjpeg/src/ffjpeg+0x4eb545)
#3 0x7f3d5badeb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/…/csu/libc-start.c:310
#4 0x41ac89 in _start (/root/ffjpeg/src/ffjpeg+0x41ac89)
0x7f3d587ffc00 is located 1024 bytes to the right of 4194304-byte region [0x7f3d583ff800,0x7f3d587ff800)
allocated by thread T0 here:
#0 0x4a71a0 in malloc /root/llvm-project/llvm/projects/compiler/lib/asan/asan_malloc_linux.cc:145
#1 0x4f132b in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f132b)
#2 0x4eb545 in main (/root/ffjpeg/src/ffjpeg+0x4eb545)
#3 0x7f3d5badeb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/…/csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-buffer-overflow /root/llvm-project/llvm/projects/compiler/lib/asan/asan_interceptors_memintrinsics.cc:22 in __asan_memcpy
Shadow bytes around the buggy address:
0x0fe82b0f7f30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7f40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7f50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7f60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0fe82b0f7f80:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7f90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0fe82b0f7fd0: 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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==40906==ABORTING
ASAN telled us there is a heap-buffer-overflow on 0x4f24df in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f24df)
Then we used IDA to locate this triggered bug.
Lastly, we used GDB to debug this bug, the GDB outputs:
gdb-peda$ b * 0x4f24df
Breakpoint 1 at 0x4f24df
gdb-peda$ r
Starting program: /root/ffjpeg/src/ffjpeg -d hh
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x7ffff36ff800 --> 0xbebebebebebebebe
RBX: 0x7fffffffdd00 --> 0x3e7620 (' v>’)
RCX: 0x7fffffffdbc0 --> 0x7ad90c007af07c
RDX: 0x20 (' ')
RSI: 0x7fffffffdbc0 --> 0x7ad90c007af07c
RDI: 0x7ffff36ff800 --> 0xbebebebebebebebe
RBP: 0x7fffffffe3d0 --> 0x7fffffffe510 --> 0x501c10 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffda58 --> 0x4f24e0 (<jfif_decode+8448>: movsxd rcx,DWORD PTR [rbx+0x638])
RIP: 0xffffffffcd4a5e60
R8 : 0xc2a00000000 --> 0x0
R9 : 0x0
R10: 0x10007fff7b98 --> 0xf3f3f3f3f3f3f3f3
R11: 0x10007fff7b78 --> 0x0
R12: 0x7fffffffe400 --> 0x0
R13: 0x80
R14: 0x10007fff7b4c --> 0xf1f1f1f1 --> 0x0
R15: 0x615000000080 --> 0xffff0000ffee
EFLAGS: 0x10293 (CARRY parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0xffffffffcd4a5e60
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffda58 --> 0x4f24e0 (<jfif_decode+8448>: movsxd rcx,DWORD PTR [rbx+0x638])
0008| 0x7fffffffda60 --> 0x41b58ab3
0016| 0x7fffffffda68 --> 0x5155e8 (“6 32 128 4 ftab 192 16 2 dc 224 12 10 yuv_stride 256 12 10 yuv_height 288 24 10 yuv_datbuf 352 256 2 du”)
0024| 0x7fffffffda70 --> 0x4f03e0 (<jfif_decode>: push rbp)
0032| 0x7fffffffda78 --> 0x3a (‘:’)
0040| 0x7fffffffda80 --> 0x6110000002c0 --> 0xc7b00000d00 --> 0x0
0048| 0x7fffffffda88 --> 0x611000000400 --> 0x136b00000e00
0056| 0x7fffffffda90 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xffffffffcd4a5e60 in ?? ()
We ensured there is a heap overflow because of the dangerous using of memcpy function, attacker can use this bug to finish a DoS attack.
You can reproduce this heap overflow vulnerability by the follow step:
ffjpeg -d PoC_heapoverflow1_ffjpeg