Vulnerability: FFmpeg before commit 5aba5b89d0b1d73164d3b81764828bb8b20ff32a contains an out of array read vulnerability in ASF_F format demuxer that can result in heap memory reading. This attack appear to be exploitable via specially crafted ASF file that has to provided as input. This vulnerability appears to have been fixed in 5aba5b89d0b1d73164d3b81764828bb8b20ff32a and later.
Vulnerability ID: CVE-2018-1999015
CWE: CWE-125
Severity score: 2.9
Project: https://github.com/FFmpeg/FFmpeg
Published: 2018-07-23
File: libavcodec/mpeg4videodec.c
Commit message: avcodec/mpeg4videodec: Check for bitstream end in read_quant_matrix_ext()

Fixes: out of array read
Fixes: asff-crash-0e53d0dc491dfdd507530b66562812fbd4c36678

Found-by: Paul Ch <paulcher@icloud.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Commit author: Michael Niedermayer

Vulnerable version (before fix):
 static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)     return 0; }  static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) {     int i, j, v;      if (get_bits1(gb)) {         /* intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             v = get_bits(gb, 8); static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)     }      if (get_bits1(gb)) {         /* non_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             get_bits(gb, 8);         }     }      if (get_bits1(gb)) {         /* chroma_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             v = get_bits(gb, 8); static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)     }      if (get_bits1(gb)) {         /* chroma_non_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             get_bits(gb, 8);         }     }      next_start_code_studio(gb); }  static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id)

Fixed version (after fix):
 static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)     return 0; }  static int read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) {     int i, j, v;      if (get_bits1(gb)) {         if (get_bits_left(gb) < 64*8)             return AVERROR_INVALIDDATA;         /* intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             v = get_bits(gb, 8); static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)     }      if (get_bits1(gb)) {         if (get_bits_left(gb) < 64*8)             return AVERROR_INVALIDDATA;         /* non_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             get_bits(gb, 8);         }     }      if (get_bits1(gb)) {         if (get_bits_left(gb) < 64*8)             return AVERROR_INVALIDDATA;         /* chroma_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             v = get_bits(gb, 8); static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)     }      if (get_bits1(gb)) {         if (get_bits_left(gb) < 64*8)             return AVERROR_INVALIDDATA;         /* chroma_non_intra_quantiser_matrix */         for (i = 0; i < 64; i++) {             get_bits(gb, 8);         }     }      next_start_code_studio(gb);     return 0; }  static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id)

Patch:
patch: @@ -2867,11 +2867,13 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
     return 0;
 }
 
-static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)
+static int read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)
 {
     int i, j, v;
 
     if (get_bits1(gb)) {
+        if (get_bits_left(gb) < 64*8)
+            return AVERROR_INVALIDDATA;
         /* intra_quantiser_matrix */
         for (i = 0; i < 64; i++) {
             v = get_bits(gb, 8);
@@ -2882,13 +2884,17 @@ static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)
     }
 
     if (get_bits1(gb)) {
+        if (get_bits_left(gb) < 64*8)
+            return AVERROR_INVALIDDATA;
         /* non_intra_quantiser_matrix */
         for (i = 0; i < 64; i++) {
             get_bits(gb, 8);
         }
     }
 
     if (get_bits1(gb)) {
+        if (get_bits_left(gb) < 64*8)
+            return AVERROR_INVALIDDATA;
         /* chroma_intra_quantiser_matrix */
         for (i = 0; i < 64; i++) {
             v = get_bits(gb, 8);
@@ -2898,13 +2904,16 @@ static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb)
     }
 
     if (get_bits1(gb)) {
+        if (get_bits_left(gb) < 64*8)
+            return AVERROR_INVALIDDATA;
         /* chroma_non_intra_quantiser_matrix */
         for (i = 0; i < 64; i++) {
             get_bits(gb, 8);
         }
     }
 
     next_start_code_studio(gb);
+    return 0;
 }
 
 static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id)
path: libavcodec/mpeg4videodec.c