ffjpeg "jfif_decode" function heap-overflow vulnerabilities
Description:
There are two heap-overflow bugs in jfif_decode(void ctxt, BMP pb) function at ffjpeg/src/jfif.c: line 544 & line 545
An attacker can exploit this bug to cause a Denial of Service (DoS) by submitting a malicious jpeg image.
We finded the integer pointer array variable yuv_datbuf[] which cannot have bound sanity, so the using of variable yuv_datbuf[] is dangerous.
As the issue 27 (https://github.com/rockcarry/ffjpeg/issues/27) showed, the using of yuv_datbuf[] caused security vulnerabilities.
We tracked the using of yuv_datbuf, and finded two heap-overflow bugs, at ffjpeg/src/jfif.c: line 544 & line 545 :
usrc = yuv_datbuf[2] + uy yuv_stride[2] + ux;
vsrc = yuv_datbuf[1] + vy yuv_stride[1] + vx;
We used asan to recognize these vulnerabilities, the output of asan as follow:
==40953==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x0000004f2f0a bp 0x7ffecaf45690 sp 0x7ffecaf45688
READ of size 4 at 0x602000000010 thread T0
0 0x4f2f09 in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f2f09)
#1 0x4eb545 in main (/root/ffjpeg/src/ffjpeg+0x4eb545)
#2 0x7fbe45680b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
#3 0x41ac89 in _start (/root/ffjpeg/src/ffjpeg+0x41ac89)
0x602000000011 is located 0 bytes to the right of 1-byte region [0x602000000010,0x602000000011)
allocated by thread T0 here:
0 0x4a71a0 in malloc /root/llvm-project/llvm/projects/compiler/lib/asan/asan_malloc_linux.cc:145
#1 0x4f1457 in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f1457)
#2 0x4eb545 in main (/root/ffjpeg/src/ffjpeg+0x4eb545)
#3 0x7fbe45680b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-buffer-overflow (/root/ffjpeg/src/ffjpeg+0x4f2f09) in jfif_decode
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[01]fa fa fa 01 fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: 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
==40953==ABORTING
the asan telled us there is a heap-buffer-overflow on address 0x602000000010 at pc 0x0000004f2f0a bp 0x7ffecaf45690 sp 0x7ffecaf45688
Then we used IDA to locate this triggered bug.
Lastly, we used GDB to debug this bug, the GDB outputs:
gdb-peda$ b * 0x4f2f09
Breakpoint 1 at 0x4f2f09
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.
We ensured there is a heap overflow because of the dangerous using of the int pointer array variable yuv_datbuf
This is the analysis of line 544, and the analysis of line 545 is similar, so we do not dump the detail analysis.
You can reproduce this heap overflow vulnerability by the follow step:
ffjpeg -d PoC_heapoverflow_line544_ffjpeg
ffjpeg -d PoC_heapoverflow_line545_ffjpeg
ffjpeg "jfif_decode" function heap-overflow vulnerabilities
Description: There are two heap-overflow bugs in jfif_decode(void ctxt, BMP pb) function at ffjpeg/src/jfif.c: line 544 & line 545 An attacker can exploit this bug to cause a Denial of Service (DoS) by submitting a malicious jpeg image. We finded the integer pointer array variable yuv_datbuf[] which cannot have bound sanity, so the using of variable yuv_datbuf[] is dangerous. As the issue 27 (https://github.com/rockcarry/ffjpeg/issues/27) showed, the using of yuv_datbuf[] caused security vulnerabilities. We tracked the using of yuv_datbuf, and finded two heap-overflow bugs, at ffjpeg/src/jfif.c: line 544 & line 545 : usrc = yuv_datbuf[2] + uy yuv_stride[2] + ux; vsrc = yuv_datbuf[1] + vy yuv_stride[1] + vx;
We used asan to recognize these vulnerabilities, the output of asan as follow:
==40953==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x0000004f2f0a bp 0x7ffecaf45690 sp 0x7ffecaf45688 READ of size 4 at 0x602000000010 thread T0
0 0x4f2f09 in jfif_decode (/root/ffjpeg/src/ffjpeg+0x4f2f09)
0x602000000011 is located 0 bytes to the right of 1-byte region [0x602000000010,0x602000000011) allocated by thread T0 here:
0 0x4a71a0 in malloc /root/llvm-project/llvm/projects/compiler/lib/asan/asan_malloc_linux.cc:145
SUMMARY: AddressSanitizer: heap-buffer-overflow (/root/ffjpeg/src/ffjpeg+0x4f2f09) in jfif_decode Shadow bytes around the buggy address: 0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c047fff8000: fa fa[01]fa fa fa 01 fa fa fa fa fa fa fa fa fa 0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8050: 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 ==40953==ABORTING
the asan telled us there is a heap-buffer-overflow on address 0x602000000010 at pc 0x0000004f2f0a bp 0x7ffecaf45690 sp 0x7ffecaf45688
Then we used IDA to locate this triggered bug.![image](https://user-images.githubusercontent.com/23331814/86354742-28951380-bc9c-11ea-8106-160cc3b778f5.png)
Lastly, we used GDB to debug this bug, the GDB outputs: gdb-peda$ b * 0x4f2f09 Breakpoint 1 at 0x4f2f09 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: 0x3 RBX: 0x7fffffffdd20 --> 0x4a6e81 (<interceptor_free(void*)+193>: test r13d,r13d) RCX: 0x602000000001 --> 0x102ffffff000000 RDX: 0xc0400000002 --> 0x0 RSI: 0xffffefcb501 --> 0x0 RDI: 0x602000000010 --> 0xbe RBP: 0x7fffffffe3f0 --> 0x7fffffffe540 --> 0x501c10 (<__libc_csu_init>: push r15) RSP: 0x7fffffffda78 --> 0x4f2f0a (<jfif_decode+11050>: mov rax,QWORD PTR [rbx+0x88]) RIP: 0xffffffffcd4b4f00 R8 : 0x0 R9 : 0x0 R10: 0x7fffffffd1c0 --> 0x4a71a1 (<interceptor_malloc(__sanitizer::uptr)+257>: test r13d,r13d) R11: 0x2 R12: 0x7fffffffe420 --> 0xdd000000dc --> 0x0 R13: 0x80 R14: 0x10007fff7b50 --> 0xf1f1f1f1 --> 0x0 R15: 0x615000000080 --> 0xdd000000dc --> 0x0 EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] Invalid $PC address: 0xffffffffcd4b4f00 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffda78 --> 0x4f2f0a (<jfif_decode+11050>: mov rax,QWORD PTR [rbx+0x88]) 0008| 0x7fffffffda80 --> 0x41b58ab3 0016| 0x7fffffffda88 --> 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| 0x7fffffffda90 --> 0x4f03e0 (: push rbp)
0032| 0x7fffffffda98 --> 0x3a (':')
0040| 0x7fffffffdaa0 --> 0x611000000180 --> 0x58c00000600 --> 0x0
0048| 0x7fffffffdaa8 --> 0x0
0056| 0x7fffffffdab0 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xffffffffcd4b4f00 in ?? ()
We ensured there is a heap overflow because of the dangerous using of the int pointer array variable yuv_datbuf This is the analysis of line 544, and the analysis of line 545 is similar, so we do not dump the detail analysis. You can reproduce this heap overflow vulnerability by the follow step: ffjpeg -d PoC_heapoverflow_line544_ffjpeg ffjpeg -d PoC_heapoverflow_line545_ffjpeg