aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2017-03-15 23:26:10 +0100
committerClément Bœsch <u@pkh.me>2017-03-15 23:26:10 +0100
commitd96f6df3a649ab3276c7c854a1dfe23e89279d91 (patch)
tree8d79b107b7d68cd9aeb40684ef9bbcca40c6ed34 /libavcodec
parentaabe525734aa591debd6a5a00adbe7c6af7f3882 (diff)
parent7ebdffc353f3f0827864e8e3461fdc00cc243b14 (diff)
downloadffmpeg-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>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/dxv.c16
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