[PR] avcodec/rasc: Check that 32-bit DLTA accesses stay within the row (PR #23628)

michaelni via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178268097605.59.10999730206715904228@29965ddac10e>
PR #23628 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23628
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23628.patch

Found-by: bikini (github.com/bikini/exploitarium)
Fixes: out of array access
Fixes: rowspill_128x1.avi / gen_rowspill_avi.py
Fixes: xGV79bIb7uAJ



>From 7ae64dba3c5ee27e63efe5958d20d96f6f03da9b Mon Sep 17 00:00:00 2001
From: Umar Pathan <[email protected]>
Date: Sun, 28 Jun 2026 23:02:52 +0200
Subject: [PATCH] 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
---
 libavcodec/rasc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c
index 5f956a9b2c..d784a44063 100644
--- a/libavcodec/rasc.c
+++ b/libavcodec/rasc.c
@@ -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;
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.