diff options
author | Clément Bœsch <u@pkh.me> | 2017-03-15 23:26:10 +0100 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2017-03-15 23:26:10 +0100 |
commit | d96f6df3a649ab3276c7c854a1dfe23e89279d91 (patch) | |
tree | 8d79b107b7d68cd9aeb40684ef9bbcca40c6ed34 | |
parent | aabe525734aa591debd6a5a00adbe7c6af7f3882 (diff) | |
parent | 7ebdffc353f3f0827864e8e3461fdc00cc243b14 (diff) | |
download | ffmpeg-d96f6df3a649ab3276c7c854a1dfe23e89279d91.tar.gz |
Merge commit '7ebdffc353f3f0827864e8e3461fdc00cc243b14'
* commit '7ebdffc353f3f0827864e8e3461fdc00cc243b14':
dxv: Check to make sure we don't overrun buffers on corrupt inputs
Merged-by: Clément Bœsch <u@pkh.me>
-rw-r--r-- | libavcodec/dxv.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 05a9aadd24..c931577356 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -133,7 +133,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 */ @@ -186,7 +186,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--; @@ -215,7 +215,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++; @@ -260,10 +260,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) { - av_log(avctx, AV_LOG_ERROR, "idx %d > %d\n", idx, pos); + 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++; @@ -286,9 +284,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++; @@ -299,6 +301,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 |