CVE-2019-11338: NULL Pointer Dereference (CWE-476)
value: libavcodec/hevcdec.c in FFmpeg 3.4 and 4.1.2 mishandles detection of duplicate first slices, which allows remote attackers to cause a denial of service (NULL pointer dereference and out-of-array access) or possibly have unspecified other impact via crafted HEVC data.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 8.8
Published: 2019-04-19T00:29Z
Repository: https://github.com/FFmpeg/FFmpeg
Language: C
Files changed: libavcodec/hevcdec.c
Commit date: 2019-03-27 08:42:10 +0100
Commit message: avcodec/hevcdec: Avoid only partly skiping duplicate first slices

Fixes: NULL pointer dereference and out of array access
Fixes: 13871/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_HEVC_fuzzer-5746167087890432
Fixes: 13845/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_HEVC_fuzzer-5650370728034304

This also fixes the return code for explode mode

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Reviewed-by: James Almer <jamrial@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Diff: diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 86adab0ae127..857c10dd122f 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -486,10 +486,15 @@ static int hls_slice_header(HEVCContext *s)
     SliceHeader *sh   = &s->sh;
     int i, ret;
 
     // Coded parameters
     sh->first_slice_in_pic_flag = get_bits1(gb);
+    if (s->ref && sh->first_slice_in_pic_flag) {
+        av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
+        return 1; // This slice will be skiped later, do not corrupt state
+    }
+
     if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {
         s->seq_decode = (s->seq_decode + 1) & 0xff;
         s->max_ra     = INT_MAX;
         if (IS_IDR(s))
             ff_hevc_clear_refs(s);
@@ -2916,23 +2921,24 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
     case HEVC_NAL_RASL_N:
     case HEVC_NAL_RASL_R:
         ret = hls_slice_header(s);
         if (ret < 0)
             return ret;
+        if (ret == 1) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+
 
         if (
             (s->avctx->skip_frame >= AVDISCARD_BIDIR && s->sh.slice_type == HEVC_SLICE_B) ||
             (s->avctx->skip_frame >= AVDISCARD_NONINTRA && s->sh.slice_type != HEVC_SLICE_I) ||
             (s->avctx->skip_frame >= AVDISCARD_NONKEY && !IS_IRAP(s))) {
             break;
         }
 
         if (s->sh.first_slice_in_pic_flag) {
-            if (s->ref) {
-                av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
-                goto fail;
-            }
             if (s->max_ra == INT_MAX) {
                 if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) {
                     s->max_ra = s->poc;
                 } else {
                     if (IS_IDR(s))

Vulnerable code:             if (s->ref) {
                av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
                goto fail;
            }
Fixed code:     if (s->ref && sh->first_slice_in_pic_flag) {
        av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
        return 1; // This slice will be skiped later, do not corrupt state
    }

        if (ret == 1) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }