diff mbox series

[FFmpeg-devel,04/36] avcodec/vp9_superframe_bsf: Check superframe size for overflow

Message ID 20200530160541.29517-4-andreas.rheinhardt@gmail.com
State New
Headers show
Series [FFmpeg-devel,01/36] avcodec/vp9_superframe_bsf: Check for existence of data before reading it
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt May 30, 2020, 4:05 p.m. UTC
This is not dangerous now, because init_get_bits8() already restricts
the size of each packet to INT_MAX/8 - AV_INPUT_BUFFER_PADDING_SIZE.
But it is nevertheless better to check this explicitly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/vp9_superframe_bsf.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/vp9_superframe_bsf.c b/libavcodec/vp9_superframe_bsf.c
index f330970acc..a8b58a7fd3 100644
--- a/libavcodec/vp9_superframe_bsf.c
+++ b/libavcodec/vp9_superframe_bsf.c
@@ -42,10 +42,11 @@  static void vp9_superframe_flush(AVBSFContext *ctx)
 }
 
 static void stats(AVPacket * const *in, int n_in,
-                  unsigned *_max, unsigned *_sum)
+                  unsigned *_max, uint64_t *_sum)
 {
     int n;
-    unsigned max = 0, sum = 0;
+    uint64_t sum = 0;
+    unsigned max = 0;
 
     for (n = 0; n < n_in; n++) {
         unsigned sz = in[n]->size;
@@ -61,15 +62,18 @@  static void stats(AVPacket * const *in, int n_in,
 
 static int merge_superframe(AVPacket * const *in, int n_in, AVPacket *out)
 {
-    unsigned max, sum, mag, marker, n, sz;
+    unsigned max, mag, marker, n;
+    uint64_t sum;
     uint8_t *ptr;
     int res;
 
     stats(in, n_in, &max, &sum);
     mag = av_log2(max) >> 3;
     marker = 0xC0 + (mag << 3) + (n_in - 1);
-    sz = sum + 2 + (mag + 1) * n_in;
-    res = av_new_packet(out, sz);
+    sum += 2 + (mag + 1) * n_in;
+    if (sum > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
+        return AVERROR(ERANGE);
+    res = av_new_packet(out, sum);
     if (res < 0)
         return res;
     ptr = out->data;