From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 270274C891 for ; Wed, 6 Aug 2025 09:03:08 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id BAA7568C880; Wed, 6 Aug 2025 12:03:03 +0300 (EEST) Received: from 264e01bdf0e5 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id E5D4168BB78 for ; Wed, 6 Aug 2025 12:03:01 +0300 (EEST) MIME-Version: 1.0 From: michaelni To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] =?utf-8?q?=5BPATCH=5D_out_of_array_fixes_in_exr_?= =?utf-8?b?KFBSICMyMDEzMCk=?= X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Message-Id: <20250806090303.BAA7568C880@ffbox0-bg.ffmpeg.org> Date: Wed, 6 Aug 2025 12:03:03 +0300 (EEST) Archived-At: List-Archive: List-Post: 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 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 --- 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 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 --- 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".