[FFmpeg-devel,2/5,RFC] avcodec/hevcdec: Check for overread in hls_decode_entry()

Submitted by Michael Niedermayer on Aug. 6, 2019, 9:30 p.m.

Details

Message ID 20190806213006.25210-2-michael@niedermayer.cc
State New
Headers show

Commit Message

Michael Niedermayer Aug. 6, 2019, 9:30 p.m.
This checks by adjusting the bytestream end pointer so as to detect
overread without the need of additional code in the innermost loop.
This should be safe as arrays have additional AV_INPUT_BUFFER_PADDING_SIZE
at their end.
This is simple and does not cause a slowdown but it is hackish.
The clean way to check for overread is a counter in the cabac reader.
There may or may not be other ways to infer that overread must occur,
that would require more in depth analysis of the following syntax
elements and their absolute minimum size.

The being a RFC as it is unquestionable not pretty and as i myself
would of course prefer a fast AND pretty solution in case anyone has
ideas ...

Improves: Timeout (190 seconds -> 86 seconds)
Improves: 15702/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_HEVC_fuzzer-5657764929470464

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/hevcdec.c | 3 +++
 1 file changed, 3 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index f1934975d5..6ba07b959a 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2434,6 +2434,7 @@  static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
             s->tab_slice_address[ctb_addr_rs] = -1;
             return ret;
         }
+        s->HEVClc->cc.bytestream_end += 4;
 
         hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);
 
@@ -2442,6 +2443,8 @@  static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)
         s->filter_slice_edges[ctb_addr_rs]  = s->sh.slice_loop_filter_across_slices_enabled_flag;
 
         more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);
+        if (s->HEVClc->cc.bytestream >= s->HEVClc->cc.bytestream_end)
+            more_data = AVERROR_INVALIDDATA;
         if (more_data < 0) {
             s->tab_slice_address[ctb_addr_rs] = -1;
             return more_data;