Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] out of array fixes in exr (PR #20130)
@ 2025-08-06  9:03 michaelni
  0 siblings, 0 replies; only message in thread
From: michaelni @ 2025-08-06  9:03 UTC (permalink / raw)
  To: ffmpeg-devel

PR #20130 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20130
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20130.patch


From 92a9948ae44ac4cee869c239b2a3667e2d36ac63 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael@niedermayer.cc>
Date: Wed, 6 Aug 2025 10:08:14 +0200
Subject: [PATCH 1/2] avcodec/exr: Check rle_raw_data and surroundings

Fixes: out of array read

Fixes: BIGSLEEP-436510153/dwa_uncompress_read.exr

Found-by: Google Big Sleep
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/exr.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 0a6aab662e..504fea0aac 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -996,6 +996,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
     const int dc_h = td->ysize >> 3;
     GetByteContext gb, agb;
     int skip, ret;
+    int have_rle = 0;
 
     if (compressed_size <= 88)
         return AVERROR_INVALIDDATA;
@@ -1020,6 +1021,11 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
     )
         return AVERROR_INVALIDDATA;
 
+    if ((uint64_t)rle_raw_size > INT_MAX) {
+        avpriv_request_sample(s->avctx, "Too big rle_raw_size");
+        return AVERROR_INVALIDDATA;
+    }
+
     bytestream2_init(&gb, src + 88, compressed_size - 88);
     skip = bytestream2_get_le16(&gb);
     if (skip < 2)
@@ -1090,6 +1096,9 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
     if (rle_raw_size > 0 && rle_csize > 0 && rle_usize > 0) {
         unsigned long dest_len = rle_usize;
 
+        if (2LL * td->xsize * td->ysize > rle_raw_size)
+            return AVERROR_INVALIDDATA;
+
         av_fast_padded_malloc(&td->rle_data, &td->rle_size, rle_usize);
         if (!td->rle_data)
             return AVERROR(ENOMEM);
@@ -1106,6 +1115,8 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
         if (ret < 0)
             return ret;
         bytestream2_skip(&gb, rle_csize);
+
+        have_rle = 1;
     }
 
     bytestream2_init(&agb, td->ac_data, ac_count * 2);
@@ -1187,7 +1198,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
         return 0;
 
     if (s->pixel_type == EXR_HALF) {
-        for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
+        for (int y = 0; y < td->ysize && have_rle; y++) {
             uint16_t *ao = ((uint16_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
             uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
             uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
@@ -1196,7 +1207,7 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
                 ao[x] = ai0[x] | (ai1[x] << 8);
         }
     } else {
-        for (int y = 0; y < td->ysize && td->rle_raw_data; y++) {
+        for (int y = 0; y < td->ysize && have_rle; y++) {
             uint32_t *ao = ((uint32_t *)td->uncompressed_data) + y * td->xsize * s->nb_channels;
             uint8_t *ai0 = td->rle_raw_data + y * td->xsize;
             uint8_t *ai1 = td->rle_raw_data + y * td->xsize + rle_raw_size / 2;
-- 
2.49.1


From d775d29225393e7dc7fed5a1b9821c01a37105ca Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael@niedermayer.cc>
Date: Wed, 6 Aug 2025 10:35:15 +0200
Subject: [PATCH 2/2] avcodec/exr: Dont access outside xsize/ysize

Fixes: out of array access
Fixes: BIGSLEEP-436510316/dwa_uncompress_write.exr

Found-by: Google Big Sleep
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/exr.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 504fea0aac..dea612a42b 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1127,6 +1127,8 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
             float *yb = td->block[0];
             float *ub = td->block[1];
             float *vb = td->block[2];
+            int bw = FFMIN(8, td->xsize - x);
+            int bh = FFMIN(8, td->ysize - y);
 
             memset(td->block, 0, sizeof(td->block));
 
@@ -1151,8 +1153,8 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
                 uint16_t *ro = ((uint16_t *)td->uncompressed_data) +
                     y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
 
-                for (int yy = 0; yy < 8; yy++) {
-                    for (int xx = 0; xx < 8; xx++) {
+                for (int yy = 0; yy < bh; yy++) {
+                    for (int xx = 0; xx < bw; xx++) {
                         const int idx = xx + yy * 8;
                         float b, g, r;
 
@@ -1175,8 +1177,8 @@ static int dwa_uncompress(const EXRContext *s, const uint8_t *src, int compresse
                 float *ro = ((float *)td->uncompressed_data) +
                     y * td->xsize * s->nb_channels + td->xsize * (o + 2) + x;
 
-                for (int yy = 0; yy < 8; yy++) {
-                    for (int xx = 0; xx < 8; xx++) {
+                for (int yy = 0; yy < bh; yy++) {
+                    for (int xx = 0; xx < bw; xx++) {
                         const int idx = xx + yy * 8;
 
                         convert(yb[idx], ub[idx], vb[idx], &bo[xx], &go[xx], &ro[xx]);
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-08-06  9:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-06  9:03 [FFmpeg-devel] [PATCH] out of array fixes in exr (PR #20130) michaelni

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git