avcodec/rasc: Check that 32-bit DLTA accesses stay within the row

Found-by: bikini (github.com/bikini/exploitarium)
Fixes: out of array access
Fixes: rowspill_128x1.avi / gen_rowspill_avi.py
Fixes: xGV79bIb7uAJ
This commit is contained in:
Umar Pathan
2026-06-28 23:02:52 +02:00
committed by michaelni
parent 9579983197
commit 11ff18a6c8
+13
View File
@@ -320,6 +320,11 @@ static int decode_move(AVCodecContext *avctx,
return 0;
}
static inline int dlta_room(unsigned cx, unsigned w, unsigned bpp, unsigned need)
{
return cx + need <= w * bpp;
}
#define NEXT_LINE \
if (cx >= w * s->bpp) { \
cx = 0; \
@@ -418,6 +423,8 @@ static int decode_dlta(AVCodecContext *avctx,
case 4:
fill = bytestream2_get_byte(&dc);
while (len > 0 && cy > 0) {
if (!dlta_room(cx, w, s->bpp, 4))
return AVERROR_INVALIDDATA;
AV_WL32(b1 + cx, AV_RL32(b2 + cx));
AV_WL32(b2 + cx, fill);
cx++;
@@ -427,6 +434,8 @@ static int decode_dlta(AVCodecContext *avctx,
case 7:
fill = bytestream2_get_le32(&dc);
while (len > 0 && cy > 0) {
if (!dlta_room(cx, w, s->bpp, 4))
return AVERROR_INVALIDDATA;
AV_WL32(b1 + cx, AV_RL32(b2 + cx));
AV_WL32(b2 + cx, fill);
cx += 4;
@@ -443,6 +452,8 @@ static int decode_dlta(AVCodecContext *avctx,
while (len > 0 && cy > 0) {
unsigned v0, v1;
if (!dlta_room(cx, w, s->bpp, 4))
return AVERROR_INVALIDDATA;
v0 = AV_RL32(b2 + cx);
v1 = AV_RL32(b1 + cx);
AV_WL32(b2 + cx, v1);
@@ -454,6 +465,8 @@ static int decode_dlta(AVCodecContext *avctx,
case 13:
while (len > 0 && cy > 0) {
fill = bytestream2_get_le32(&dc);
if (!dlta_room(cx, w, s->bpp, 4))
return AVERROR_INVALIDDATA;
AV_WL32(b1 + cx, AV_RL32(b2 + cx));
AV_WL32(b2 + cx, fill);
cx += 4;