[FFmpeg-devel] [PATCH 1/2] avcodec: Add AV_CODEC_FLAG2_FAST_UNSAFE, move unsafe uses of FAST to it

Michael Niedermayer michael at niedermayer.cc
Thu May 28 19:20:55 EEST 2020


TODO: Bump

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 doc/APIchanges             | 3 +++
 doc/codecs.texi            | 2 ++
 libavcodec/avcodec.h       | 6 ++++++
 libavcodec/h264dec.c       | 2 +-
 libavcodec/options_table.h | 1 +
 tools/target_dec_fuzzer.c  | 2 +-
 6 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index fb5534b5f5..3e20a44379 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-xx-xx - xxxxxxxxxx - lavc 58.xx.100 - avcodec.h
+  Add AV_CODEC_FLAG2_FAST_UNSAFE
+
 2020-xx-xx - xxxxxxxxxx - lavc 58.88.100 - avcodec.h codec.h
   Move AVCodec-related public API to new header codec.h.
 
diff --git a/doc/codecs.texi b/doc/codecs.texi
index c092aadc0e..46790b66b3 100644
--- a/doc/codecs.texi
+++ b/doc/codecs.texi
@@ -787,6 +787,8 @@ Possible values:
 @table @samp
 @item fast
 Allow non spec compliant speedup tricks.
+ at item fast_unsafe
+Allow speedup tricks which can lead to out of array reads and crashes on damaged or crafted files.
 @item noout
 Skip bitstream encoding.
 @item ignorecrop
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 01099bc8cd..479f219b43 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -346,6 +346,12 @@ typedef struct RcOverride{
  * Allow non spec compliant speedup tricks.
  */
 #define AV_CODEC_FLAG2_FAST           (1 <<  0)
+
+/**
+ * Allow speedups tricks which can read out of array on non compliant streams.
+ */
+#define AV_CODEC_FLAG2_FAST_UNSAFE    (1 <<  1)
+
 /**
  * Skip bitstream encoding.
  */
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index e463fde2a5..b764caa942 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -603,7 +603,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
     }
 
     ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc, h->nal_length_size,
-                                avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST, 0);
+                                avctx->codec_id, avctx->flags2 & AV_CODEC_FLAG2_FAST_UNSAFE, 0);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR,
                "Error splitting the input into NAL units.\n");
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 8ba137f51e..4e26b844f6 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -71,6 +71,7 @@ static const AVOption avcodec_options[] = {
 {"drop_changed", "Drop frames whose parameters differ from first decoded frame", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D, "flags"},
 {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D|S, "flags2"},
 {"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"fast_unsafe", "allow speedup tricks which can read out of arrays", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST_UNSAFE }, INT_MIN, INT_MAX, V|E, "flags2"},
 {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
 {"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c
index d01deaf8d5..414cdab593 100644
--- a/tools/target_dec_fuzzer.c
+++ b/tools/target_dec_fuzzer.c
@@ -208,7 +208,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
             if (flags & 8)
                 ctx->err_recognition |= AV_EF_EXPLODE;
         }
-        if ((flags & 0x10) && c->id != AV_CODEC_ID_H264)
+        if (flags & 0x10)
             ctx->flags2 |= AV_CODEC_FLAG2_FAST;
 
         if (flags & 0x40)
-- 
2.17.1



More information about the ffmpeg-devel mailing list