[FFmpeg-devel] [PATCH 2/4] avcodec/vp9_superframe_bsf: Check for existence of data before reading it

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Wed Mar 23 01:09:10 EET 2022

Packets without data need to be handled specially in order to avoid
undefined reads. Pass these packets through unchanged in case there
are no cached packets* and error out in case there are cached packets:
Returning the packet would mess with the order of the packets;
if one returned the zero-sized packet before the superframe that will
be created from the packets in the cache, the zero-sized packet would
overtake the packets in the cache; if one returned the packet later,
the packets that complete the superframe will overtake the zero-sized

*: This case e.g. encompasses the scenario of updated extradata
side-data at the end.

Fixes: Out of array read
Fixes: 45722/clusterfuzz-testcase-minimized-ffmpeg_BSF_VP9_SUPERFRAME_fuzzer-5173378975137792

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
The current way of passthrough has been suggested by James.

 libavcodec/vp9_superframe_bsf.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/libavcodec/vp9_superframe_bsf.c b/libavcodec/vp9_superframe_bsf.c
index 57681e29e4..df9b97fa3c 100644
--- a/libavcodec/vp9_superframe_bsf.c
+++ b/libavcodec/vp9_superframe_bsf.c
@@ -108,6 +108,15 @@ static int vp9_superframe_filter(AVBSFContext *ctx, AVPacket *pkt)
     if (res < 0)
         return res;
+    if (!pkt->size) {
+        /* In case the cache is empty we can pass side-data-only packets
+         * through unchanged. Otherwise, such a packet makes no sense. */
+        if (!s->n_cache)
+            return 0;
+        goto done;
+    }
     marker = pkt->data[pkt->size - 1];
     if ((marker & 0xe0) == 0xc0) {
         int nbytes = 1 + ((marker >> 3) & 0x3);

More information about the ffmpeg-devel mailing list