[FFmpeg-devel,2/2] avcodec/utvideodec: Add several out of array read related checks

Submitted by Michael Niedermayer on Feb. 9, 2018, 9:24 p.m.

Details

Message ID 20180209212459.30350-2-michael@niedermayer.cc
State New
Headers show

Commit Message

Michael Niedermayer Feb. 9, 2018, 9:24 p.m.
Fixes: OV_decode_plane.avi

Found-by: GwanYeong Kim <gy741.kim@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/utvideodec.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

Comments

Michael Niedermayer Feb. 11, 2018, 1:40 a.m.
On Fri, Feb 09, 2018 at 10:24:59PM +0100, Michael Niedermayer wrote:
> Fixes: OV_decode_plane.avi
> 
> Found-by: GwanYeong Kim <gy741.kim@gmail.com>
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/utvideodec.c | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)

applied

[...]

Patch hide | download patch | download mbox

diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 1bcd14e74c..f0be2b231b 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -268,8 +268,12 @@  static int decode_plane(UtvideoContext *c, int plane_no,
             send   = (height * (slice + 1) / c->slices) & cmask;
             dest   = dst + sstart * stride;
 
+            if (3 * ((dst + send * stride - dest + 7)/8) > get_bits_left(&cbit))
+                return AVERROR_INVALIDDATA;
+
             for (p = dest; p < dst + send * stride; p += 8) {
-                int bits = get_bits_le(&cbit, 3);
+                int bits;
+                bits = get_bits_le(&cbit, 3);
 
                 if (bits == 0) {
                     *(uint64_t *) p = 0;
@@ -277,6 +281,9 @@  static int decode_plane(UtvideoContext *c, int plane_no,
                     uint32_t sub = 0x80 >> (8 - (bits + 1)), add;
                     int k;
 
+                    if ((bits + 1) * 8 > get_bits_left(&pbit))
+                        return AVERROR_INVALIDDATA;
+
                     for (k = 0; k < 8; k++) {
 
                         p[k] = get_bits_le(&pbit, bits + 1);
@@ -639,9 +646,9 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             for (j = 0; j < c->slices; j++) {
                 c->packed_stream[i][j] = packed_stream;
                 c->packed_stream_size[i][j] = bytestream2_get_le32(&pb);
-                left -= c->packed_stream_size[i][j];
-                if (left < 0)
+                if (c->packed_stream_size[i][j] > left)
                     return AVERROR_INVALIDDATA;
+                left -= c->packed_stream_size[i][j];
                 packed_stream += c->packed_stream_size[i][j];
             }
         }
@@ -652,9 +659,9 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             for (j = 0; j < c->slices; j++) {
                 c->control_stream[i][j] = control_stream;
                 c->control_stream_size[i][j] = bytestream2_get_le32(&pb);
-                left -= c->control_stream_size[i][j];
-                if (left < 0)
+                if (c->control_stream_size[i][j] > left)
                     return AVERROR_INVALIDDATA;
+                left -= c->control_stream_size[i][j];
                 control_stream += c->control_stream_size[i][j];
             }
         }