Opened 6 months ago

Closed 6 months ago

#9099 closed defect (fixed)

HEVC Null pointer dereference

Reported by: QiuhaoLi Owned by:
Priority: important Component: avcodec
Version: git-master Keywords: hevc crash SIGSEGV regression
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description (last modified by Carl Eugen Hoyos)

-- [ Description

During fuzzing, we found a null pointer dereference (CWE-476) in the latest FFmpeg/libavcodec.

I sent a report to ffmpeg-security@ffmpeg.org, but didn't get a reply yet.

-- [ Affected Version

ubuntu@VM-0-6-ubuntu:~/ffmpeg_sources/FFmpeg$ git log | head -n 4
commit 129978af6b6503109517777eba8890713a787cb5
Author: Paul B Mahol <onemda@gmail.com>
Date: Wed Feb 10 14:08:23 2021 +0100

-- [ Reproduce with ASAN & Report

ubuntu@VM-0-6-ubuntu:~$ FFREPORT=1 ./bin/ffmpeg -i PoC output.mp4 # sorry I didn't go deep to figure out the format of the PoC
Report written to "ffmpeg-20210210-224350.log"
Log level: 48
ffmpeg version N-101043-g129978af6b Copyright (c) 2000-2021 the FFmpeg developers
  built with clang version 10.0.0-4ubuntu1
  configuration: --prefix=/home/ubuntu/ffmpeg_build --pkg-config-flags=--static --extra-cflags='-I/home/ubuntu/ffmpeg_build/include -ggdb -fsanitize=address -fsanitize=undefined' --extra-ldflags='-L/home/ubuntu/ffmpeg_build/lib -fsanitize=address -fsanitize=undefined' --extra-libs='-lpthread -lm' --bindir=/home/ubuntu/bin --cc=clang --cxx=clang++ --disable-ffplay --disable-ffprobe --disable-stripping --assert-level=2 --enable-gpl --enable-gnutls --enable-libaom --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      56. 65.100 / 56. 65.100
  libavcodec     58.122.100 / 58.122.100
  libavformat    58. 67.100 / 58. 67.100
  libavdevice    58. 11.103 / 58. 11.103
  libavfilter     7.103.100 /  7.103.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] overread end of atom 'stsd' by 808464282 bytes
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] stream 0, timescale not set
[hevc @ 0x619000000f80] Invalid NAL unit size in extradata.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Failed to open codec in avformat_find_stream_info
[hevc @ 0x619000000f80] Invalid NAL unit size in extradata.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Failed to open codec in avformat_find_stream_info
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Could not find codec parameters for stream 0 (Video: hevc (Hvc1 / 0x31637648), none, 12336x12336): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'PoC':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: hevc (Hvc1 / 0x31637648), none, 12336x12336, 1 tbr, 1 tbn, 1 tbc
    Metadata:
      handler_name    : 0000000000000
      vendor_id       : 0000
      encoder         : 0000000000000000000000000000000
[hevc @ 0x619000002d80] Invalid NAL unit size in extradata.
libavcodec/hevcdec.c:3427:22: runtime error: applying zero offset to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior libavcodec/hevcdec.c:3427:22 in 
libavcodec/hevcdec.c:3427:22: runtime error: load of null pointer of type 'HEVCLocalContext *' (aka 'struct HEVCLocalContext *')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior libavcodec/hevcdec.c:3427:22 in 
AddressSanitizer:DEADLYSIGNAL
=================================================================
==23809==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000035bf9ad bp 0x0c4c00001224 sp 0x7ffef55e8e20 T0)
==23809==The signal is caused by a READ memory access.
==23809==Hint: address points to the zero page.
    #0 0x35bf9ad in hevc_decode_free /home/ubuntu/ffmpeg_sources/FFmpeg/libavcodec/hevcdec.c:3427:19
    #1 0x4688cde in ff_frame_thread_free /home/ubuntu/ffmpeg_sources/FFmpeg/libavcodec/pthread_frame.c:712:13
    #2 0x468d646 in ff_frame_thread_init /home/ubuntu/ffmpeg_sources/FFmpeg/libavcodec/pthread_frame.c:885:5
    #3 0x4e0ffa8 in avcodec_open2 /home/ubuntu/ffmpeg_sources/FFmpeg/libavcodec/utils.c:759:15
    #4 0x57c0c4 in init_input_stream /home/ubuntu/ffmpeg_sources/FFmpeg/fftools/ffmpeg.c:2988:20
    #5 0x57c0c4 in transcode_init /home/ubuntu/ffmpeg_sources/FFmpeg/fftools/ffmpeg.c:3751:20
    #6 0x56f0d7 in transcode /home/ubuntu/ffmpeg_sources/FFmpeg/fftools/ffmpeg.c:4752:11
    #7 0x56c7b2 in main /home/ubuntu/ffmpeg_sources/FFmpeg/fftools/ffmpeg.c:4986:9
    #8 0x7fe2dcb100b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #9 0x4251ad in _start (/home/ubuntu/bin/ffmpeg+0x4251ad)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ubuntu/ffmpeg_sources/FFmpeg/libavcodec/hevcdec.c:3427:19 in hevc_decode_free
==23809==ABORTING
ubuntu@VM-0-6-ubuntu:~$ cat ffmpeg-20210210-224350.log
ffmpeg started on 2021-02-10 at 22:43:50
Report written to "ffmpeg-20210210-224350.log"
Log level: 48
Command line:
./bin/ffmpeg -i PoC output.mp4
ffmpeg version N-101043-g129978af6b Copyright (c) 2000-2021 the FFmpeg developers
  built with clang version 10.0.0-4ubuntu1
  configuration: --prefix=/home/ubuntu/ffmpeg_build --pkg-config-flags=--static --extra-cflags='-I/home/ubuntu/ffmpeg_build/include -ggdb -fsanitize=address -fsanitize=undefined' --extra-ldflags='-L/home/ubuntu/ffmpeg_build/lib -fsanitize=address -fsanitize=undefined' --extra-libs='-lpthread -lm' --bindir=/home/ubuntu/bin --cc=clang --cxx=clang++ --disable-ffplay --disable-ffprobe --disable-stripping --assert-level=2 --enable-gpl --enable-gnutls --enable-libaom --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      56. 65.100 / 56. 65.100
  libavcodec     58.122.100 / 58.122.100
  libavformat    58. 67.100 / 58. 67.100
  libavdevice    58. 11.103 / 58. 11.103
  libavfilter     7.103.100 /  7.103.100
  libswscale      5.  8.100 /  5.  8.100
  libswresample   3.  8.100 /  3.  8.100
  libpostproc    55.  8.100 / 55.  8.100
Splitting the commandline.
Reading option '-i' ... matched as input url with argument 'PoC'.
Reading option 'output.mp4' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Successfully parsed a group of options.
Parsing a group of options: input url PoC.
Successfully parsed a group of options.
Opening an input file: PoC.
[NULL @ 0x61b000000080] Opening 'PoC' for reading
[file @ 0x610000000040] Setting default whitelist 'file,crypto,data'
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Format mov,mp4,m4a,3gp,3g2,mj2 probed with size=2048 and score=100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] overread end of atom 'stsd' by 808464282 bytes
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] stream 0, timescale not set
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Before avformat_find_stream_info() pos: 495 bytes read:495 seeks:2 nb_streams:1
[hevc @ 0x619000000f80] Invalid NAL unit size in extradata.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Failed to open codec in avformat_find_stream_info
[hevc @ 0x619000000f80] Invalid NAL unit size in extradata.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Failed to open codec in avformat_find_stream_info
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] Could not find codec parameters for stream 0 (Video: hevc (Hvc1 / 0x31637648), none, 12336x12336): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x61b000000080] After avformat_find_stream_info() pos: 495 bytes read:495 seeks:2 frames:0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'PoC':
  Duration: N/A, bitrate: N/A
  Stream #0:0, 0, 1/1: Video: hevc (Hvc1 / 0x31637648), none, 12336x12336, 1 tbr, 1 tbn, 1 tbc
    Metadata:
      handler_name    : 0000000000000
      vendor_id       : 0000
      encoder         : 0000000000000000000000000000000
Successfully opened the file.
Parsing a group of options: output url output.mp4.
Successfully parsed a group of options.
Opening an output file: output.mp4.
[file @ 0x610000001640] Setting default whitelist 'file,crypto,data'
Successfully opened the file.
detected 16 logical cores
[hevc @ 0x619000002d80] Invalid NAL unit size in extradata.

-- [ GDB Report

ubuntu@VM-0-6-ubuntu:~$ gdb --args ./bin/ffmpeg -i PoC output.mp4
(gdb) run
(gdb) bt
#0  0x00000000035bf9ad in hevc_decode_free (avctx=<optimized out>) at libavcodec/hevcdec.c:3427
#1  0x0000000004688cdf in ff_frame_thread_free (avctx=0x619000001480, thread_count=<optimized out>) at libavcodec/pthread_frame.c:712
#2  0x000000000468d647 in ff_frame_thread_init (avctx=<optimized out>) at libavcodec/pthread_frame.c:885
#3  0x00000000070a9b23 in ff_thread_init (avctx=<optimized out>) at libavcodec/pthread.c:77
#4  0x0000000004e0ffa9 in avcodec_open2 (avctx=<optimized out>, codec=0x9aa5ec0 <ff_hevc_decoder>, options=<optimized out>) at libavcodec/utils.c:759
#5  0x000000000057c0c5 in init_input_stream (ist_index=<optimized out>, error=0x7fffffffc660 "", error_len=1024) at fftools/ffmpeg.c:2988
#6  transcode_init () at fftools/ffmpeg.c:3751
#7  0x000000000056f0d8 in transcode () at fftools/ffmpeg.c:4752
#8  0x000000000056c7b3 in main (argc=<optimized out>, argv=<optimized out>) at fftools/ffmpeg.c:4986

(gdb) disass $pc-32,$pc+32
Dump of assembler code from 0x35bf98d to 0x35bf9cd:
   0x00000000035bf98d <hevc_decode_free+1317>:  add    (%rax),%al
   0x00000000035bf98f <hevc_decode_free+1319>:  add    %cl,-0x7b(%rax)
   0x00000000035bf992 <hevc_decode_free+1322>:  fisttpl (%rdi)
   0x00000000035bf994 <hevc_decode_free+1324>:  test   %ah,(%rbx)
   0x00000000035bf996 <hevc_decode_free+1326>:  add    (%rax),%al
   0x00000000035bf998 <hevc_decode_free+1328>:  add    %cl,-0x77(%rax)
   0x00000000035bf99b <hevc_decode_free+1331>:  fmuls  -0x3f(%rax)
   0x00000000035bf99e <hevc_decode_free+1334>:  callq  0x41479a6 <skip_bits_long+742>
   0x00000000035bf9a3 <hevc_decode_free+1339>:  cmp    $0x7f,%bh
   0x00000000035bf9a6 <hevc_decode_free+1342>:  add    %cl,(%rdi)
   0x00000000035bf9a8 <hevc_decode_free+1344>:  test   %ebp,(%rdx)
   0x00000000035bf9aa <hevc_decode_free+1346>:  add    (%rax),%eax
   0x00000000035bf9ac <hevc_decode_free+1348>:  add    %cl,0x23(%rbx,%rdi,1)
   0x00000000035bf9b0 <hevc_decode_free+1352>:  mov    0x8(%rsp),%r12
   0x00000000035bf9b5 <hevc_decode_free+1357>:  jne    0x35bf9de <hevc_decode_free+1398>
   0x00000000035bf9b7 <hevc_decode_free+1359>:  test   %r14b,%r14b
   0x00000000035bf9ba <hevc_decode_free+1362>:  je     0x35bfc69 <hevc_decode_free+2049>
   0x00000000035bf9c0 <hevc_decode_free+1368>:  test   $0x7,%r15b
   0x00000000035bf9c4 <hevc_decode_free+1372>:  jne    0x35bfc7f <hevc_decode_free+2071>
   0x00000000035bf9ca <hevc_decode_free+1378>:  cmpb   $0x0,0x7fff8000(%rbp)
End of assembler dump.

(gdb) info all-registers
rax            0x0                 0
rbx            0x0                 0
rcx            0x0                 0
rdx            0xc4c00001223       13520557052451
rsi            0x0                 0
rdi            0x7fffffffb6a9      140737488336553
rbp            0xc4c00001224       0xc4c00001224
rsp            0x7fffffffb780      0x7fffffffb780
r8             0x7fffffffaa70      140737488333424
r9             0x2                 2
r10            0x7e98b73           132746099
r11            0x206               518
r12            0x0                 0
r13            0x626000009118      108164456419608
r14            0x624000002101      108027017437441
r15            0x626000009120      108164456419616
rip            0x35bf9ad           0x35bf9ad <hevc_decode_free+1349>
eflags         0x10246             [ PF ZF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
st0            0                   (raw 0x00000000000000000000)
st1            0                   (raw 0x00000000000000000000)
st2            0                   (raw 0x00000000000000000000)
st3            0                   (raw 0x00000000000000000000)
st4            0                   (raw 0x00000000000000000000)
st5            0                   (raw 0x00000000000000000000)
st6            0                   (raw 0x00000000000000000000)
st7            0                   (raw 0x00000000000000000000)
fctrl          0x37f               895
fstat          0x0                 0
ftag           0xffff              65535
fiseg          0x0                 0
fioff          0x0                 0
foseg          0x0                 0
fooff          0x0                 0
fop            0x0                 0
mxcsr          0x1fa0              [ PE IM DM ZM OM UM PM ]
bndcfgu        {raw = 0x0, config = {base = 0x0, reserved = 0x0, preserved = 0x0, enabled = 0x0}} {raw = 0x0, config = {base = 0, reserved = 0, preserved = 0, enabled = 0}}
bndstatus      {raw = 0x0, status = {bde = 0x0, error = 0x0}} {raw = 0x0, status = {bde = 0, error = 0}}
k0             0x0                 0
k1             0x0                 0
k2             0x0                 0
k3             0x0                 0
k4             0x0                 0
k5             0x0                 0
k6             0x0                 0
k7             0x0                 0
/* ... */

-- [ PoC base64 encoded

ubuntu@VM-0-6-ubuntu:~$ base64 PoC 
MDAwMG1vb3YAAABsMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
MDAwMDAwdHJhawAAAFwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAHDAwMDAwMDAw
MDAwMDAwMDAwMDAwMDAwMAAAAC1oZGxyMDAwMDAwMDB2aWRlMDAwMDAwMDAwMDAwMDAwMDAwMDAw
MDAwMAAAAAEwMDAwAAAAAAAAABwwMDAwMDAwMDAwMDAAAAAMMDAwMDAwMDAwMDAwc3RzZDAwMDAA
AAABMDAwMGVuY3YwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAA0YXZjQzAwMDAwMDAwMDAwMDAwMDAw
MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZybWFIdmMx

Thank you.

Qiuhao Li

Attachments (1)

PoC (495 bytes ) - added by QiuhaoLi 6 months ago.
The crash input file (SEGV: Read on address 0x000000000000)

Download all attachments as: .zip

Change History (6)

by QiuhaoLi, 6 months ago

Attachment: PoC added

The crash input file (SEGV: Read on address 0x000000000000)

comment:1 by QiuhaoLi, 6 months ago

Reproduced by developer: set

comment:2 by Carl Eugen Hoyos, 6 months ago

Description: modified (diff)
Keywords: asan hevc added; NULL Pointer Dereference removed
Priority: importantnormal
Reproduced by developer: unset
Summary: FFmpeg/libavcodec: NULL Pointer DereferenceUndefined behaviour in the hevc decoder

I cannot reproduce a crash.

comment:3 by richardpl, 6 months ago

Reproduced by developer: set
Status: newopen

I can.

comment:4 by Carl Eugen Hoyos, 6 months ago

Keywords: crash SIGSEGV regression added; asan removed
Priority: normalimportant
Summary: Undefined behaviour in the hevc decoderHEVC Null pointer dereference

Indeed, a regression since d4751d8c630983e6343c3100debb5de80be50ac3

comment:5 by James, 6 months ago

Resolution: fixed
Status: openclosed
Note: See TracTickets for help on using tickets.