[PR] avcodec/tiff: reject inflate output shorter than the strip (PR #23899)

michaelni via ffmpeg-devel <[email protected]> Fri, 24 Jul 2026 19:00:47 -0000
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178491964962.59.8020334873787144515@29965ddac10e>
PR #23899 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23899
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23899.patch

Fixes: use of uninitialized memory
Fixes: tiff_short_deflate_heap_disclosure.tiff
Fixes: 1cRIkpUVMQtn
Found-by: Adrian Junge (vurlo)



>From 73d310e00be1de05c4f234875defe7287569c170 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Wed, 22 Jul 2026 05:44:41 +0200
Subject: [PATCH] avcodec/tiff: reject inflate output shorter than the strip

Fixes: use of uninitialized memory
Fixes: tiff_short_deflate_heap_disclosure.tiff
Fixes: 1cRIkpUVMQtn
Found-by: Adrian Junge (vurlo)
---
 libavcodec/tiff.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 8a179f0fd0..b8ce7b0b55 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -526,6 +526,7 @@ static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride
     uint8_t *zbuf;
     unsigned long outlen;
     int ret, line;
+    int rows = is_yuv ? (lines + s->subsampling[1] - 1) / s->subsampling[1] : lines;
     outlen = width * lines;
     zbuf   = av_malloc(outlen);
     if (!zbuf)
@@ -545,6 +546,12 @@ static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride
         av_free(zbuf);
         return AVERROR_UNKNOWN;
     }
+    if (outlen < (unsigned long)width * rows) {
+        av_log(s->avctx, AV_LOG_ERROR, "Deflated %lu bytes, but %lu are needed\n",
+               outlen, (unsigned long)width * rows);
+        av_free(zbuf);
+        return AVERROR_INVALIDDATA;
+    }
     src = zbuf;
     for (line = 0; line < lines; line++) {
         if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
@@ -592,6 +599,7 @@ static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride
 {
     uint64_t outlen = width * (uint64_t)lines;
     int ret, line;
+    int rows = is_yuv ? (lines + s->subsampling[1] - 1) / s->subsampling[1] : lines;
     uint8_t *buf = av_malloc(outlen);
     if (!buf)
         return AVERROR(ENOMEM);
@@ -610,6 +618,12 @@ static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride
         av_free(buf);
         return AVERROR_UNKNOWN;
     }
+    if (outlen < (uint64_t)width * rows) {
+        av_log(s->avctx, AV_LOG_ERROR, "Uncompressed %"PRIu64" bytes, but %"PRIu64" are needed\n",
+               outlen, (uint64_t)width * rows);
+        av_free(buf);
+        return AVERROR_INVALIDDATA;
+    }
     src = buf;
     for (line = 0; line < lines; line++) {
         if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]