From 7ebdffc353f3f0827864e8e3461fdc00cc243b14 Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Thu, 28 Jul 2016 13:45:24 +0300 Subject: dxv: Check to make sure we don't overrun buffers on corrupt inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/dxv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 32137f5392..99327dface 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -125,7 +125,7 @@ static int dxv_decompress_dxt1(AVCodecContext *avctx) AV_WL32(ctx->tex_data + 4, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ - while (pos < ctx->tex_size / 4) { + while (pos + 2 <= ctx->tex_size / 4) { CHECKPOINT(2); /* Copy two elements from a previous offset or from the input buffer */ @@ -178,7 +178,7 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) AV_WL32(ctx->tex_data + 12, bytestream2_get_le32(gbc)); /* Process input until the whole texture has been filled */ - while (pos < ctx->tex_size / 4) { + while (pos + 2 <= ctx->tex_size / 4) { if (run) { run--; @@ -207,7 +207,7 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) check += probe; } while (probe == 0xFFFF); } - while (check && pos < ctx->tex_size / 4) { + while (check && pos + 4 <= ctx->tex_size / 4) { prev = AV_RL32(ctx->tex_data + 4 * (pos - 4)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -252,6 +252,8 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) case 2: /* Copy two dwords from a previous index */ idx = 8 + bytestream2_get_le16(gbc); + if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -274,9 +276,13 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) } CHECKPOINT(4); + if (pos + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; /* Copy two elements from a previous offset or from the input buffer */ if (op) { + if (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4) + return AVERROR_INVALIDDATA; prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); AV_WL32(ctx->tex_data + 4 * pos, prev); pos++; @@ -287,6 +293,8 @@ static int dxv_decompress_dxt5(AVCodecContext *avctx) } else { CHECKPOINT(4); + if (op && (idx > pos || (unsigned int)(pos - idx) + 2 > ctx->tex_size / 4)) + return AVERROR_INVALIDDATA; if (op) prev = AV_RL32(ctx->tex_data + 4 * (pos - idx)); else -- cgit v1.2.3