[FFmpeg-cvslog] indeo3: check motion vectors.
Anton Khirnov
git at videolan.org
Mon Jul 29 02:44:27 CEST 2013
ffmpeg | branch: release/0.10 | Anton Khirnov <anton at khirnov.net> | Tue Apr 16 09:41:28 2013 +0200| [9b2af4d080c7baccd2b175d8f2b95ed653df2361] | committer: Reinhard Tartler
indeo3: check motion vectors.
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC:libav-stable at libav.org
(cherry picked from commit a0a872d0733f60876b0c93f236bc4606f36fbf89)
Signed-off-by: Reinhard Tartler <siretart at tauware.de>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9b2af4d080c7baccd2b175d8f2b95ed653df2361
---
libavcodec/indeo3.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 83aadf6..5d44f97 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -222,7 +222,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
* @param plane pointer to the plane descriptor
* @param cell pointer to the cell descriptor
*/
-static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
+static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
{
int h, w, mv_x, mv_y, offset, offset_dst;
uint8_t *src, *dst;
@@ -232,6 +232,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
dst = plane->pixels[ctx->buf_sel] + offset_dst;
mv_y = cell->mv_ptr[0];
mv_x = cell->mv_ptr[1];
+
+ /* -1 because there is an extra line on top for prediction */
+ if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
+ ((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
+ ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Motion vectors point out of the frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
offset = offset_dst + mv_y * plane->pitch + mv_x;
src = plane->pixels[ctx->buf_sel ^ 1] + offset;
@@ -259,6 +269,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
dst += 4;
}
}
+
+ return 0;
}
@@ -584,11 +596,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
} else if (mode >= 10) {
/* for mode 10 and 11 INTER first copy the predicted cell into the current one */
/* so we don't need to do data copying for each RLE code later */
- copy_cell(ctx, plane, cell);
+ int ret = copy_cell(ctx, plane, cell);
+ if (ret < 0)
+ return ret;
} else {
/* set the pointer to the reference pixels for modes 0-4 INTER */
mv_y = cell->mv_ptr[0];
mv_x = cell->mv_ptr[1];
+
+ /* -1 because there is an extra line on top for prediction */
+ if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
+ ((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
+ ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Motion vectors point out of the frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
offset += mv_y * plane->pitch + mv_x;
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
}
@@ -720,7 +744,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
const int depth, const int strip_width)
{
Cell curr_cell;
- int bytes_used;
+ int bytes_used, ret;
if (depth <= 0) {
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
@@ -771,8 +795,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
CHECK_CELL
if (!curr_cell.mv_ptr)
return AVERROR_INVALIDDATA;
- copy_cell(ctx, plane, &curr_cell);
- return 0;
+ ret = copy_cell(ctx, plane, &curr_cell);
+ return ret;
}
break;
case INTER_DATA:
More information about the ffmpeg-cvslog
mailing list