indeo: Bound-check before applying motion compensation
authorLuca Barbato <lu_zero@gentoo.org>
Sun, 14 Jul 2013 12:06:16 +0000 (14:06 +0200)
committerLuca Barbato <lu_zero@gentoo.org>
Sat, 24 Aug 2013 10:09:02 +0000 (12:09 +0200)
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
(cherry picked from commit 25a6666f6c07c6ac8449a63d7fbce0dfd29c54cd)

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
libavcodec/ivi_common.c

index 4901feb..66f94c1 100644 (file)
@@ -44,16 +44,22 @@ static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
 typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf,
                              uint32_t pitch, int mc_type);
 
-static int ivi_mc(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf,
-                  int offs, int mv_x, int mv_y, uint32_t pitch,
-                  int mc_type)
+static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc,
+                  int offs, int mv_x, int mv_y, int mc_type)
 {
-    int ref_offs = offs + mv_y * pitch + mv_x;
+    int ref_offs = offs + mv_y * band->pitch + mv_x;
+    int buf_size = band->pitch * band->aheight;
+    int min_size = band->pitch * (band->blk_size - 1) + band->blk_size;
+    int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1);
 
-    if (offs < 0 || ref_offs < 0 || !ref_buf)
+    if (offs < 0 || ref_offs < 0 || !band->ref_buf)
+        return AVERROR_INVALIDDATA;
+    if (buf_size - min_size < offs)
+        return AVERROR_INVALIDDATA;
+    if (buf_size - min_size - ref_size < ref_offs)
         return AVERROR_INVALIDDATA;
 
-    mc(buf + offs, ref_buf + ref_offs, pitch, mc_type);
+    mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type);
 
     return 0;
 }
@@ -513,8 +519,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band,
 
     /* apply motion compensation */
     if (!is_intra)
-        return ivi_mc(mc, band->buf, band->ref_buf, offs, mv_x, mv_y,
-                      band->pitch, mc_type);
+        return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type);
 
     return 0;
 }
@@ -613,8 +618,8 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band,
                     if (ret < 0)
                         return ret;
                 } else {
-                    ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf,
-                                 buf_offs, mv_x, mv_y, band->pitch, mc_type);
+                    ret = ivi_mc(band, mc_no_delta_func, buf_offs,
+                                 mv_x, mv_y, mc_type);
                     if (ret < 0)
                         return ret;
                 }
@@ -720,8 +725,8 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
             for (blk = 0; blk < num_blocks; blk++) {
                 /* adjust block position in the buffer according with its number */
                 offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
-                ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf,
-                             offs, mv_x, mv_y, band->pitch, mc_type);
+                ret = ivi_mc(band, mc_no_delta_func, offs,
+                             mv_x, mv_y, mc_type);
                 if (ret < 0)
                     return ret;
             }