Hi,

I'm sending new debdiff, with your suggestions. Also I pushed to salsa.

Thanks for your review!

On 2026-10-15 11:42, Sylvain Beucler wrote:
> Hi,
> 
> On 15/10/2026 04:25, Emmanuel Arias wrote:
> > On 2026-10-08 14:30, Sylvain Beucler wrote:
> > > On 06/10/2026 21:43, Emmanuel Arias wrote:
> > > > I've worked in tiff for bookworm. Please, could you review the patches?
> > > > 
> > > > The patches are here:
> > > >     
> > > > https://salsa.debian.org/lts-team/packages/tiff/-/tree/debian/bookworm?pow_referer=&ref_type=heads
> > > 
> > > Please provide a proper debdiff, because reviewing each commit on Salsa is
> > > not practical.
> > 
> > Attaching
> CVE-2024-13978: you only added 1 patch out of 2, why is that?

Added the second one
> 
> CVE-2026-18495: I don't think we need all the compilation warning fixes,
> just those related to the CVE.

I modified the patch.

> 
> Please drop the Bug-Debian-Security and Bug-Freexian-Security which only
> repeat default tracker links and aren't informative (in particular the
> freexian one while this isn't ELTS).

Ready, I left those that patch name is not CVE-*.patch I backported
those from trixie and I leave as they are.

> 
> For Salsa-CI, maybe fix debian/watch or add an allow_failure for
> 'test-uscan', which makes the CI FAIL, which is confusing.

Ready.

> 
> I'm not sure which of your debdiff or the current salsa Git repo is the more
> up-to-date. One has .gitlab-ci.yml, the other has salsa-ci.yml (the
> repository should probably be moved salsa-ci.yml, with the LTS CI template.)
> In any case, please sync the debdiff you send for review and the Git repo
> where you run salsa-ci.

Sorry for that, now they are sync.

> 
> 
> > > CVE-2026-36849 is marked <ignored> in trixie, maybe check with the 
> > > security
> > > team and/or maintainer if it's a good idea to fix it.
> > 
> > Contacted, thanks!
> 
> (So, who did you contact and how?)

I sent an email to the maintainer first, to know the opinion but I
didn't receive any reply yet.

> 
> I see that the CVE-2026-36849 patch adds a symbol, maybe that's why it was
> marked <ignored>, as it's always a delicate change especially after the
> bookworm freeze. It also changes a structure. And it's a large patch. Did
> you perform specific testing?
> 
> Your symbol update seems to be wrong, you mark version 4.5.0 while this is
> something you're adding after the bookworm release, in 4.5.0-6+deb12u5 and
> not before.

I modify a little bit here to make the function private.

> 
> 
> > > What kind of testing did you do?
> > > We have some notes from the maintainer at
> > > https://lts-team.pages.debian.net/wiki/TestSuites/tiff.html , did you 
> > > check
> > > them?
> > > There are many reverse dependencies for this package so thorough testing 
> > > is
> > > needed.
> > 
> > I uploaded it to debusine [0]. But I trying to reproduce the Test
> > Suites you mentioned.
> > 
> > [0] https://debusine.debian.net/debian/developers/work-request/1426324/
> 
> The tiff package doesn't have autopkgtest and is marked as skipped, so
> autopkgtest/debusine won't be enough here.
> 
> libgd2, an important package, has all its tests failing here, but I can't
> find the reference test results for comparison. Did you investigate what's
> happening?

That's pending for me

> 
> Try to reproduce individual issues when there's a reproducer, in particular
> for CVE-2026-52490 where you hand-picked the patch chunks; test if our
> version fails without the patch and doesn't fail anymore with the patch.

I couldn't do that yet, I test it with the bank you mentioned (some of
those images not all)


> 
> 
> For now I don't have a lot of confidence in this update, please
> address/clarify these points.
> 
> Cheers!
> Sylvain Beucler
> Debian LTS Team
> 

-- 
cheers,
        Emmanuel Arias

 ⢀⣴⠾⠻⢶⣦⠀
 ⣾⠁⢠⠒⠀⣿⡁  [email protected]
 ⢿⡄⠘⠷⠚⠋⠀  OpenPGP: 13796755BBC72BB8ABE2AEB5 FA9DEC5DE11C63F1
 ⠈⠳⣄
diff -Nru tiff-4.5.0/debian/changelog tiff-4.5.0/debian/changelog
--- tiff-4.5.0/debian/changelog 2026-04-07 14:22:16.000000000 -0300
+++ tiff-4.5.0/debian/changelog 2026-09-22 20:02:07.000000000 -0300
@@ -1,3 +1,28 @@
+tiff (4.5.0-6+deb12u5) bookworm-security; urgency=high
+
+  * Non-maintainer upload by the LTS Team.
+  * CVE-2024-13978: Affected by this vulnerability is the function
+    t2p_read_tiff_init of the file tools/tiff2pdf.c of the component fax2ps.
+    The manipulation leads to null pointer dereference. The attack needs to be
+    approached locally. The complexity of an attack is rather high. The
+    exploitation appears to be difficult.
+  * Address heap-based buffer overflow in pixarlog (CVE-2026-12912)
+    (Closes: #1141320)
+    - pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3
+    - pixarlog: add comment explaining 4-byte advance in ABGR decode
+    - pixarlog: complete ABGR bounds check for multi-row strip decoding
+    - pixarlog: error out on invalid ABGR output buffer sizes
+  * CVE-2026-52490: Integer overflow in the tiffcrop -S subdivision count
+    computation, which could lead to out-of-bounds access (Closes: #1147247)
+  * CVE-2026-18495: fix heap-based buffer overflow caused by
+    truncation of 64-bit StripByteCounts values in crafted BigTIFF files.
+  * CVE-2026-36849: denial of service via large SamplesPerPixel tag
+    (Closes: #1140300).
+  * d/salsa-ci.yml: Enable salsa-ci.
+    - Add test-uscan allow to fail.
+
+ -- Emmanuel Arias <[email protected]>  Tue, 22 Sep 2026 20:02:07 -0300
+
 tiff (4.5.0-6+deb12u4) bookworm-security; urgency=medium
 
   * CVE-2026-4775 (Closes: #1132632)
diff -Nru tiff-4.5.0/debian/patches/CVE-2024-13978_1.patch 
tiff-4.5.0/debian/patches/CVE-2024-13978_1.patch
--- tiff-4.5.0/debian/patches/CVE-2024-13978_1.patch    1969-12-31 
21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/patches/CVE-2024-13978_1.patch    2026-09-22 
20:02:07.000000000 -0300
@@ -0,0 +1,39 @@
+From: Lee Howard <[email protected]>
+Date: Sat, 5 Oct 2024 09:45:30 -0700
+Subject: Check TIFFTAG_TILELENGTH and TIFFTAGTILEWIDTH for valid input,
+ addresses issue #650
+
+Origin: backport, 
https://gitlab.com/libtiff/libtiff/-/commit/2ebfffb0e8836bfb1cd7d85c059cd285c59761a4
+---
+ tools/tiff2pdf.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
+index 1dbdc87..6feb0cd 100644
+--- a/tools/tiff2pdf.c
++++ b/tools/tiff2pdf.c
+@@ -1337,8 +1337,24 @@ void t2p_read_tiff_init(T2P *t2p, TIFF *input)
+             t2p->pdf_xrefcount += (t2p->tiff_tiles[i].tiles_tilecount - 1) * 
2;
+             TIFFGetField(input, TIFFTAG_TILEWIDTH,
+                          &(t2p->tiff_tiles[i].tiles_tilewidth));
++            if (t2p->tiff_tiles[i].tiles_tilewidth < 1)
++            {
++                TIFFError(TIFF2PDF_MODULE, "Invalid tile width (%d), %s",
++                    t2p->tiff_tiles[i].tiles_tilewidth,
++                    TIFFFileName(input));
++                t2p->t2p_error = T2P_ERR_ERROR;
++                return;
++            }
+             TIFFGetField(input, TIFFTAG_TILELENGTH,
+                          &(t2p->tiff_tiles[i].tiles_tilelength));
++            if (t2p->tiff_tiles[i].tiles_tilelength < 1)
++            {
++                TIFFError(TIFF2PDF_MODULE, "Invalid tile length (%d), %s",
++                    t2p->tiff_tiles[i].tiles_tilelength,
++                    TIFFFileName(input));
++                t2p->t2p_error = T2P_ERR_ERROR;
++                return;
++            }
+             t2p->tiff_tiles[i].tiles_tiles = (T2P_TILE *)_TIFFmalloc(
+                 TIFFSafeMultiply(tmsize_t, t2p->tiff_tiles[i].tiles_tilecount,
+                                  sizeof(T2P_TILE)));
diff -Nru tiff-4.5.0/debian/patches/CVE-2024-13978_2.patch 
tiff-4.5.0/debian/patches/CVE-2024-13978_2.patch
--- tiff-4.5.0/debian/patches/CVE-2024-13978_2.patch    1969-12-31 
21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/patches/CVE-2024-13978_2.patch    2026-09-22 
20:02:07.000000000 -0300
@@ -0,0 +1,61 @@
+From: Lee Howard <[email protected]>
+Date: Fri, 27 Sep 2024 11:21:57 -0700
+Subject: [PATCH] Fix issue #649 in fax2ps caused by regression in commit
+ 
https://gitlab.com/libtiff/libtiff/-/commit/28c38d648b64a66c3218778c4745225fe3e3a06d
+ where TIFFTAG_FAXFILLFUNC is being used rather than an output buffer.
+
+Origin: backport, 
https://gitlab.com/libtiff/libtiff/-/commit/7be20ccaab97455f192de0ac561ceda7cd9e12d1
+---
+ libtiff/tif_read.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/libtiff/tif_read.c
++++ b/libtiff/tif_read.c
+@@ -464,6 +464,12 @@ int TIFFReadScanline(TIFF *tif, void *bu
+         if (e)
+             (*tif->tif_postdecode)(tif, (uint8_t *)buf, 
tif->tif_scanlinesize);
+     }
++    else
++    {
++      /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
++        if (buf)
++          memset(buf, 0, (size_t)tif->tif_scanlinesize);
++    }
+     return (e > 0 ? 1 : -1);
+ }
+ 
+@@ -544,7 +550,13 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif,
+     if ((size != (tmsize_t)(-1)) && (size < stripsize))
+         stripsize = size;
+     if (!TIFFFillStrip(tif, strip))
++    {
++        /* The output buf may be NULL, in particular if TIFFTAG_FAXFILLFUNC
++           is being used. Thus, memset must be conditional on buf not NULL. */
++        if (buf)
++            memset(buf, 0, (size_t)stripsize);
+         return ((tmsize_t)(-1));
++    }
+     if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
+         return ((tmsize_t)(-1));
+     (*tif->tif_postdecode)(tif, buf, stripsize);
+@@ -1550,6 +1560,10 @@ int TIFFReadFromUserBuffer(TIFF *tif, ui
+                                     (uint16_t)(strile / 
td->td_stripsperimage)))
+         {
+             ret = 0;
++            /* See related TIFFReadEncodedStrip comment. */
++            if (outbuf)
++                memset(outbuf, 0, (size_t)outsize);
++
+         }
+     }
+     else
+@@ -1565,6 +1579,9 @@ int TIFFReadFromUserBuffer(TIFF *tif, ui
+                                      (uint16_t)(strile / stripsperplane)))
+         {
+             ret = 0;
++          /* See related TIFFReadEncodedStrip comment. */
++            if (outbuf)
++                memset(outbuf, 0, (size_t)outsize);
+         }
+     }
+     if (ret)
diff -Nru tiff-4.5.0/debian/patches/CVE-2026-18495.patch 
tiff-4.5.0/debian/patches/CVE-2026-18495.patch
--- tiff-4.5.0/debian/patches/CVE-2026-18495.patch      1969-12-31 
21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/patches/CVE-2026-18495.patch      2026-09-22 
20:02:07.000000000 -0300
@@ -0,0 +1,37 @@
+From: Su Laus <[email protected]>
+Date: Tue, 3 Jun 2025 17:47:49 +0000
+Subject: [PATCH] tiff2pdf: avoid truncation of 64-bit StripByteCounts
+
+Use a 64-bit variable for max_striplength in t2p_readwrite_pdf_image()
+so that large StripByteCounts values from BigTIFF files are not
+truncated, which led to an undersized buffer allocation and a
+heap-based buffer overflow in TIFFReadRawStrip().
+
+This is a minimal backport of the upstream commit, keeping only the
+change relevant to the CVE (the rest are compiler warning fixes).
+
+Origin: backport, 
https://gitlab.com/libtiff/libtiff/-/commit/67fd283d276f09db54dc39b9ef7b979d4b45c4b1
+---
+ tools/tiff2pdf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/tools/tiff2pdf.c
++++ b/tools/tiff2pdf.c
+@@ -2499,7 +2499,7 @@ tsize_t t2p_readwrite_pdf_image(T2P *t2p
+     uint64_t *sbc;
+     unsigned char *stripbuffer;
+     tsize_t striplength = 0;
+-    uint32_t max_striplength = 0;
++    uint64_t max_striplength = 0;
+ #endif /* ifdef JPEG_SUPPORT */
+ 
+     /* Fail if prior error (in particular, can't trust tiff_datasize) */
+@@ -2746,7 +2746,7 @@ tsize_t t2p_readwrite_pdf_image(T2P *t2p
+             if (stripbuffer == NULL)
+             {
+                 TIFFError(TIFF2PDF_MODULE,
+-                          "Can't allocate %" PRId32
++                          "Can't allocate %" PRIu64
+                           " bytes of memory for t2p_readwrite_pdf_image, %s",
+                           max_striplength, TIFFFileName(input));
+                 _TIFFfree(buffer);
diff -Nru tiff-4.5.0/debian/patches/CVE-2026-36849.patch 
tiff-4.5.0/debian/patches/CVE-2026-36849.patch
--- tiff-4.5.0/debian/patches/CVE-2026-36849.patch      1969-12-31 
21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/patches/CVE-2026-36849.patch      2026-09-22 
20:02:07.000000000 -0300
@@ -0,0 +1,561 @@
+From: Even Rouault <[email protected]>
+Date: Tue, 21 Apr 2026 19:52:02 +0200
+Subject: Add TIFFGetMaxCompressionRatio() and use it in
+ _TIFFReadEncoded[Tile|Strip)AndAllocBuffer()
+
+```rst
+
+.. c:function:: uint64_t TIFFGetMaxCompressionRatio(TIFF *tif);
+
+Description
+-----------
+
+:c:func:`TIFFGetMaxCompressionRatio` returns the maximum compression ratio
+for the current codec, which is typically achieved for a uncompressed buffer
+with all bytes at zero.
+
+This function can be used to determine if the compressed size of a strip or 
tile
+is realistic compared to the expected uncompressed size, to prevent some
+denial-of-service scenarios.
+
+Depending on the codec, it may take into account the strip or tile size,
+number of samples per pixel, etc.
+
+Some codecs don't implement that method, or only for a subset of 
configurations,
+and may return 0 when the maximum compression ratio is unknown.
+
+Return values
+-------------
+
+0 is returned if no maximum compression ratio is known.
+1 is returned when there is no compression.
+Values strictly bigger than 1 are returned when a maximum compression ratio is
+known.
+```
+
+Fixes #781
+
+Origin: backport, 
https://gitlab.com/libtiff/libtiff/-/commit/eedba405d3695b52faae65994c5904f228eca0bf
+         
https://gitlab.com/libtiff/libtiff/-/commit/9986ca806dd157cfb3124f7d7af3bc6ffe13cb72
+
+Backport notes for Debian stable:
+ - TIFFGetMaxCompressionRatio() is not exported: it is renamed to the
+   internal _TIFFGetMaxCompressionRatio() and declared in tiffiop.h, so
+   no new public API/ABI symbol is added. Documentation hunks dropped.
+ - Include the upstream follow-up adding the ZSTD callback, which restores
+   the ZSTD tile allocation guard removed by the main commit.
+---
+ libtiff/tif_compress.c | 22 ++++++++++++++++++++++
+ libtiff/tif_fax3.c     | 34 ++++++++++++++++++++++++++++++++++
+ libtiff/tif_jpeg.c     | 25 +++++++++++++++++++++++++
+ libtiff/tif_lerc.c     | 11 +++++++++++
+ libtiff/tif_lzma.c     | 13 +++++++++++++
+ libtiff/tif_lzw.c      | 12 ++++++++++++
+ libtiff/tif_packbits.c |  7 +++++++
+ libtiff/tif_pixarlog.c | 11 +++++++++++
+ libtiff/tif_read.c     | 37 ++++++++++++++++++++++++-------------
+ libtiff/tif_webp.c     |  9 +++++++++
+ libtiff/tif_zip.c      |  8 ++++++++
+ libtiff/tif_zstd.c     |  9 +++++++++
+ libtiff/tiffiop.h      |  6 +++++-
+ 13 files changed, 190 insertions(+), 14 deletions(-)
+
+diff --git a/libtiff/tif_compress.c b/libtiff/tif_compress.c
+index c6e17d3..192f522 100644
+--- a/libtiff/tif_compress.c
++++ b/libtiff/tif_compress.c
+@@ -139,6 +139,18 @@ static int _TIFFtrue(TIFF *tif)
+ }
+ static void _TIFFvoid(TIFF *tif) { (void)tif; }
+ 
++static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    return 0; /* unknown */
++}
++
++static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif)
++{
++    (void)tif;
++    return 1; /* no compression */
++}
++
+ void _TIFFSetDefaultCompressionState(TIFF *tif)
+ {
+     tif->tif_fixuptags = _TIFFNoFixupTags;
+@@ -160,6 +172,7 @@ void _TIFFSetDefaultCompressionState(TIFF *tif)
+     tif->tif_cleanup = _TIFFvoid;
+     tif->tif_defstripsize = _TIFFDefaultStripSize;
+     tif->tif_deftilesize = _TIFFDefaultTileSize;
++    tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio;
+     tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
+ }
+ 
+@@ -168,6 +181,8 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
+     const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
+ 
+     _TIFFSetDefaultCompressionState(tif);
++    if (scheme == COMPRESSION_NONE)
++        tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne;
+     /*
+      * Don't treat an unknown compression scheme as an error.
+      * This permits applications to open files with data that
+@@ -177,6 +192,13 @@ int TIFFSetCompressionScheme(TIFF *tif, int scheme)
+     return (c ? (*c->init)(tif, scheme) : 1);
+ }
+ 
++uint64_t _TIFFGetMaxCompressionRatio(TIFF *tif)
++{
++    if (tif->tif_getmaxcompressionratio)
++        return tif->tif_getmaxcompressionratio(tif);
++    return 0;
++}
++
+ /*
+  * Other compression schemes may be registered.  Registered
+  * schemes can also override the builtin versions provided
+diff --git a/libtiff/tif_fax3.c b/libtiff/tif_fax3.c
+index 9d66fc0..ab06641 100644
+--- a/libtiff/tif_fax3.c
++++ b/libtiff/tif_fax3.c
+@@ -1398,6 +1398,18 @@ static void Fax3PrintDir(TIFF *tif, FILE *fd, long 
flags)
+         (*sp->printdir)(tif, fd, flags);
+ }
+ 
++static uint64_t Fax3GetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* 1024x1024: 36 */
++    /* 4096x4096: 100 */
++    /* 16383x16383: 163 */
++    /* 65536x65536: 200 */
++    /* 200000x200000: 208 */
++
++    return 250;
++}
++
+ static int InitCCITTFax3(TIFF *tif)
+ {
+     static const char module[] = "InitCCITTFax3";
+@@ -1462,6 +1474,7 @@ static int InitCCITTFax3(TIFF *tif)
+     tif->tif_encodetile = Fax3Encode;
+     tif->tif_close = Fax3Close;
+     tif->tif_cleanup = Fax3Cleanup;
++    tif->tif_getmaxcompressionratio = Fax3GetMaxCompressionRatio;
+ 
+     return (1);
+ }
+@@ -1606,6 +1619,12 @@ static int Fax4PostEncode(TIFF *tif)
+     return (1);
+ }
+ 
++static uint64_t Fax4GetMaxCompressionRatio(TIFF *tif)
++{
++    return isTiled(tif) ? tif->tif_dir.td_tilewidth
++                        : tif->tif_dir.td_imagewidth;
++}
++
+ int TIFFInitCCITTFax4(TIFF *tif, int scheme)
+ {
+     (void)scheme;
+@@ -1628,6 +1647,7 @@ int TIFFInitCCITTFax4(TIFF *tif, int scheme)
+         tif->tif_encodestrip = Fax4Encode;
+         tif->tif_encodetile = Fax4Encode;
+         tif->tif_postencode = Fax4PostEncode;
++        tif->tif_getmaxcompressionratio = Fax4GetMaxCompressionRatio;
+         /*
+          * Suppress RTC at the end of each strip.
+          */
+@@ -1697,6 +1717,18 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, 
tmsize_t occ, uint16_t s)
+     return (1);
+ }
+ 
++static uint64_t Fax3RLEGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* 1024x1024: 43 */
++    /* 4096x4096: 128 */
++    /* 16383x16383: 171 */
++    /* 65536x65536: 205 */
++    /* 200000x200000: 211 */
++
++    return 250;
++}
++
+ int TIFFInitCCITTRLE(TIFF *tif, int scheme)
+ {
+     (void)scheme;
+@@ -1705,6 +1737,7 @@ int TIFFInitCCITTRLE(TIFF *tif, int scheme)
+         tif->tif_decoderow = Fax3DecodeRLE;
+         tif->tif_decodestrip = Fax3DecodeRLE;
+         tif->tif_decodetile = Fax3DecodeRLE;
++        tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
+         /*
+          * Suppress RTC+EOLs when encoding and byte-align data.
+          */
+@@ -1723,6 +1756,7 @@ int TIFFInitCCITTRLEW(TIFF *tif, int scheme)
+         tif->tif_decoderow = Fax3DecodeRLE;
+         tif->tif_decodestrip = Fax3DecodeRLE;
+         tif->tif_decodetile = Fax3DecodeRLE;
++        tif->tif_getmaxcompressionratio = Fax3RLEGetMaxCompressionRatio;
+         /*
+          * Suppress RTC+EOLs when encoding and word-align data.
+          */
+diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c
+index 250144f..5f62ccd 100644
+--- a/libtiff/tif_jpeg.c
++++ b/libtiff/tif_jpeg.c
+@@ -2777,6 +2777,30 @@ static int JPEGInitializeLibJPEG(TIFF *tif, int 
decompress)
+     return 1;
+ }
+ 
++static uint64_t JPEGGetMaxCompressionRatio(TIFF *tif)
++{
++    JPEGState *sp = JState(tif);
++    if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) &&
++        (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
++        (tif->tif_dir.td_samplesperpixel == 3))
++    {
++        if (sp->h_sampling == 2 && sp->v_sampling == 2)
++        {
++            if (tif->tif_dir.td_bitspersample == 12)
++                return 768;
++            else
++                return 512;
++        }
++
++        return 0; /* unknown */
++    }
++
++    if (tif->tif_dir.td_bitspersample == 12)
++        return 384;
++    else
++        return 256;
++}
++
+ /* Common to tif_jpeg.c and tif_jpeg_12.c */
+ static void TIFFInitJPEGCommon(TIFF *tif)
+ {
+@@ -2813,6 +2837,7 @@ static void TIFFInitJPEGCommon(TIFF *tif)
+     tif->tif_encoderow = JPEGEncode;
+     tif->tif_encodestrip = JPEGEncode;
+     tif->tif_encodetile = JPEGEncode;
++    tif->tif_getmaxcompressionratio = JPEGGetMaxCompressionRatio;
+     tif->tif_cleanup = JPEGCleanup;
+ 
+     tif->tif_defstripsize = JPEGDefaultStripSize;
+diff --git a/libtiff/tif_lerc.c b/libtiff/tif_lerc.c
+index 99de713..0262a73 100644
+--- a/libtiff/tif_lerc.c
++++ b/libtiff/tif_lerc.c
+@@ -1140,6 +1140,16 @@ static int LERCVGetField(TIFF *tif, uint32_t tag, 
va_list ap)
+     return 1;
+ }
+ 
++static uint64_t LERCGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++
++    /* LERC compression ratio can grow to several millions */
++    /* eg. 5703725 for Lerc deflate on 16383x16383 array */
++    /* or 3829644 for regular Lerc */
++    return 0;
++}
++
+ int TIFFInitLERC(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitLERC";
+@@ -1188,6 +1198,7 @@ int TIFFInitLERC(TIFF *tif, int scheme)
+     tif->tif_encoderow = LERCEncode;
+     tif->tif_encodestrip = LERCEncode;
+     tif->tif_encodetile = LERCEncode;
++    tif->tif_getmaxcompressionratio = LERCGetMaxCompressionRatio;
+     tif->tif_cleanup = LERCCleanup;
+ 
+     /* Default values for codec-specific fields */
+diff --git a/libtiff/tif_lzma.c b/libtiff/tif_lzma.c
+index 4cfd5e8..951529c 100644
+--- a/libtiff/tif_lzma.c
++++ b/libtiff/tif_lzma.c
+@@ -433,6 +433,17 @@ static const TIFFField lzmaFields[] = {
+      "LZMA2 Compression Preset", NULL},
+ };
+ 
++static uint64_t LZMAGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* 1024x1024: 3800 */
++    /* 4096x4096: 6534 */
++    /* 16383x16383: 6846 */
++    /* 65536x65536: 6874 */
++
++    return 7000;
++}
++
+ int TIFFInitLZMA(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitLZMA";
+@@ -508,6 +519,8 @@ int TIFFInitLZMA(TIFF *tif, int scheme)
+     tif->tif_encodestrip = LZMAEncode;
+     tif->tif_encodetile = LZMAEncode;
+     tif->tif_cleanup = LZMACleanup;
++    tif->tif_getmaxcompressionratio = LZMAGetMaxCompressionRatio;
++
+     /*
+      * Setup predictor setup.
+      */
+diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c
+index d631fa1..eab6dc3 100644
+--- a/libtiff/tif_lzw.c
++++ b/libtiff/tif_lzw.c
+@@ -1393,6 +1393,17 @@ static void LZWCleanup(TIFF *tif)
+     _TIFFSetDefaultCompressionState(tif);
+ }
+ 
++static uint64_t LZWGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* 1024x1024: 562 */
++    /* 4096x4096: 1243 */
++    /* 16383x16383: 1353 */
++    /* 65536x65536: 1362 */
++
++    return 1400;
++}
++
+ int TIFFInitLZW(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitLZW";
+@@ -1424,6 +1435,7 @@ int TIFFInitLZW(TIFF *tif, int scheme)
+     tif->tif_encoderow = LZWEncode;
+     tif->tif_encodestrip = LZWEncode;
+     tif->tif_encodetile = LZWEncode;
++    tif->tif_getmaxcompressionratio = LZWGetMaxCompressionRatio;
+     tif->tif_cleanup = LZWCleanup;
+     /*
+      * Setup predictor setup.
+diff --git a/libtiff/tif_packbits.c b/libtiff/tif_packbits.c
+index 62849f8..706ed6a 100644
+--- a/libtiff/tif_packbits.c
++++ b/libtiff/tif_packbits.c
+@@ -307,6 +307,12 @@ static int PackBitsDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+     return (1);
+ }
+ 
++static uint64_t PackBitsGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    return 64;
++}
++
+ int TIFFInitPackBits(TIFF *tif, int scheme)
+ {
+     (void)scheme;
+@@ -318,6 +324,7 @@ int TIFFInitPackBits(TIFF *tif, int scheme)
+     tif->tif_encoderow = PackBitsEncode;
+     tif->tif_encodestrip = PackBitsEncodeChunk;
+     tif->tif_encodetile = PackBitsEncodeChunk;
++    tif->tif_getmaxcompressionratio = PackBitsGetMaxCompressionRatio;
+     return (1);
+ }
+ #endif /* PACKBITS_SUPPORT */
+diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
+index fde985a..eef6f49 100644
+--- a/libtiff/tif_pixarlog.c
++++ b/libtiff/tif_pixarlog.c
+@@ -1648,6 +1648,16 @@ static const TIFFField pixarlogFields[] = {
+     {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
+      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
+ 
++static uint64_t PixarLogGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* cf https://zlib.net/zlib_tech.html */
++    const uint64_t MAX_DEFLATE_RATIO = 1032;
++
++    /* security margin as I don't understand what this codec does */
++    return MAX_DEFLATE_RATIO * (uint64_t)4;
++}
++
+ int TIFFInitPixarLog(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitPixarLog";
+@@ -1695,6 +1705,7 @@ int TIFFInitPixarLog(TIFF *tif, int scheme)
+     tif->tif_encodetile = PixarLogEncode;
+     tif->tif_close = PixarLogClose;
+     tif->tif_cleanup = PixarLogCleanup;
++    tif->tif_getmaxcompressionratio = PixarLogGetMaxCompressionRatio;
+ 
+     /* Override SetField so we can handle our private pseudo-tag */
+     sp->vgetparent = tif->tif_tagmethods.vgetfield;
+diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
+index 70201db..d4da5b4 100644
+--- a/libtiff/tif_read.c
++++ b/libtiff/tif_read.c
+@@ -591,13 +591,31 @@ tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, 
uint32_t strip,
+     if (!TIFFFillStrip(tif, strip))
+         return ((tmsize_t)(-1));
+ 
+-    *buf = _TIFFmallocExt(tif, bufsizetoalloc);
++    /* Sanity checks to avoid excessive memory allocation */
++    /* Max compression ratio experimentally determined. Might be fragile...
++     * Only apply this heuristics to situations where the memory allocation
++     * would be big, to avoid breaking nominal use cases.
++     */
++    const uint64_t maxCompressionRatio = _TIFFGetMaxCompressionRatio(tif);
++    if (maxCompressionRatio > 0 && bufsizetoalloc > 100 * 1000 * 1000 &&
++        (uint64_t)tif->tif_rawdatasize <
++            (uint64_t)this_stripsize / maxCompressionRatio)
++    {
++        TIFFErrorExtR(tif, TIFFFileName(tif),
++                      "Likely invalid strip byte count for strip %u. "
++                      "Uncompressed strip size is %" PRIu64 ", "
++                      "compressed one is %" PRIu64,
++                      strip, (uint64_t)this_stripsize,
++                      (uint64_t)tif->tif_rawdatasize);
++        return ((tmsize_t)(-1));
++    }
++
++    *buf = _TIFFcallocExt(tif, 1, bufsizetoalloc);
+     if (*buf == NULL)
+     {
+         TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
+         return ((tmsize_t)(-1));
+     }
+-    _TIFFmemset(*buf, 0, bufsizetoalloc);
+ 
+     if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
+         return ((tmsize_t)(-1));
+@@ -1054,17 +1072,10 @@ tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, 
uint32_t tile,
+          * Only apply this heuristics to situations where the memory 
allocation
+          * would be big, to avoid breaking nominal use cases.
+          */
+-        const int maxCompressionRatio =
+-            td->td_compression == COMPRESSION_ZSTD ? 33000
+-            : td->td_compression == COMPRESSION_JXL
+-                ?
+-                /* Evaluated on a 8000x8000 tile */
+-                25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
+-                             ? td->td_samplesperpixel
+-                             : 1)
+-                : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
+-        if (bufsizetoalloc > 100 * 1000 * 1000 &&
+-            tif->tif_rawdatasize < tilesize / maxCompressionRatio)
++        const uint64_t maxCompressionRatio = _TIFFGetMaxCompressionRatio(tif);
++        if (maxCompressionRatio > 0 && bufsizetoalloc > 100 * 1000 * 1000 &&
++            (uint64_t)tif->tif_rawdatasize <
++                (uint64_t)tilesize / maxCompressionRatio)
+         {
+             TIFFErrorExtR(tif, TIFFFileName(tif),
+                           "Likely invalid tile byte count for tile %u. "
+diff --git a/libtiff/tif_webp.c b/libtiff/tif_webp.c
+index 07db7cc..f66d739 100644
+--- a/libtiff/tif_webp.c
++++ b/libtiff/tif_webp.c
+@@ -728,6 +728,14 @@ static const TIFFField TWebPFields[] = {
+      NULL},
+ };
+ 
++static uint64_t TWebPGetMaxCompressionRatio(TIFF *tif)
++{
++    /* lossy compression: */
++    /* return (tif->tif_dir.td_samplesperpixel == 4) ? 2199 : 1685; */
++    /* lossless compression: */
++    return (tif->tif_dir.td_samplesperpixel == 4) ? 104194 : 78146;
++}
++
+ int TIFFInitWebP(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitWebP";
+@@ -790,6 +798,7 @@ int TIFFInitWebP(TIFF *tif, int scheme)
+     tif->tif_encodestrip = TWebPEncode;
+     tif->tif_encodetile = TWebPEncode;
+     tif->tif_cleanup = TWebPCleanup;
++    tif->tif_getmaxcompressionratio = TWebPGetMaxCompressionRatio;
+ 
+     return 1;
+ bad:
+diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c
+index fcf5100..0467417 100644
+--- a/libtiff/tif_zip.c
++++ b/libtiff/tif_zip.c
+@@ -653,6 +653,13 @@ static const TIFFField zipFields[] = {
+      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
+ };
+ 
++static uint64_t ZIPGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* cf https://zlib.net/zlib_tech.html */
++    return 1032;
++}
++
+ int TIFFInitZIP(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitZIP";
+@@ -719,6 +726,7 @@ int TIFFInitZIP(TIFF *tif, int scheme)
+     tif->tif_encodestrip = ZIPEncode;
+     tif->tif_encodetile = ZIPEncode;
+     tif->tif_cleanup = ZIPCleanup;
++    tif->tif_getmaxcompressionratio = ZIPGetMaxCompressionRatio;
+     /*
+      * Setup predictor setup.
+      */
+diff --git a/libtiff/tif_zstd.c b/libtiff/tif_zstd.c
+index 6469931..6fc8fef 100644
+--- a/libtiff/tif_zstd.c
++++ b/libtiff/tif_zstd.c
+@@ -366,6 +366,14 @@ static const TIFFField ZSTDFields[] = {
+      NULL},
+ };
+ 
++static uint64_t ZSTDGetMaxCompressionRatio(TIFF *tif)
++{
++    (void)tif;
++    /* Value from the issue #479 tile allocation guard that previously lived
++     * in _TIFFReadEncodedTileAndAllocBuffer(). */
++    return 33000;
++}
++
+ int TIFFInitZSTD(TIFF *tif, int scheme)
+ {
+     static const char module[] = "TIFFInitZSTD";
+@@ -424,6 +432,7 @@ int TIFFInitZSTD(TIFF *tif, int scheme)
+     tif->tif_encodestrip = ZSTDEncode;
+     tif->tif_encodetile = ZSTDEncode;
+     tif->tif_cleanup = ZSTDCleanup;
++    tif->tif_getmaxcompressionratio = ZSTDGetMaxCompressionRatio;
+     /*
+      * Setup predictor setup.
+      */
+diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
+index 791881a..039624a 100644
+--- a/libtiff/tiffiop.h
++++ b/libtiff/tiffiop.h
+@@ -94,6 +94,7 @@ typedef int (*TIFFSeekMethod)(TIFF *, uint32_t);
+ typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size);
+ typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t);
+ typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *);
++typedef uint64_t (*TIFFGetMaxCompressionRatioMethod)(TIFF *);
+ 
+ struct TIFFOffsetAndDirNumber
+ {
+@@ -195,7 +196,9 @@ struct tiff
+     TIFFVoidMethod tif_cleanup;       /* cleanup state routine */
+     TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */
+     TIFFTileMethod tif_deftilesize;   /* calculate/constrain tile size */
+-    uint8_t *tif_data;                /* compression scheme private data */
++    /* returns maximum compression ratio for current compression method */
++    TIFFGetMaxCompressionRatioMethod tif_getmaxcompressionratio;
++    uint8_t *tif_data; /* compression scheme private data */
+     /* input/output buffering */
+     tmsize_t tif_scanlinesize;  /* # of bytes in a scanline */
+     tmsize_t tif_scanlineskew;  /* scanline skew for reading strips */
+@@ -396,6 +399,7 @@ extern "C"
+     extern int TIFFFlushData1(TIFF *tif);
+     extern int TIFFDefaultDirectory(TIFF *tif);
+     extern void _TIFFSetDefaultCompressionState(TIFF *tif);
++    extern uint64_t _TIFFGetMaxCompressionRatio(TIFF *tif);
+     extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t,
+                                  void *);
+     extern int TIFFSetCompressionScheme(TIFF *tif, int scheme);
diff -Nru tiff-4.5.0/debian/patches/CVE-2026-52490.patch 
tiff-4.5.0/debian/patches/CVE-2026-52490.patch
--- tiff-4.5.0/debian/patches/CVE-2026-52490.patch      1969-12-31 
21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/patches/CVE-2026-52490.patch      2026-09-22 
20:02:07.000000000 -0300
@@ -0,0 +1,133 @@
+From: waugustus <[email protected]>
+Date: Fri, 12 Jun 2026 15:40:11 +0800
+Subject: Harden integer size and offset calculations in libtiff, tools, and
+ contrib
+
+Backport only the tiffcrop -S subdivision count hardening, which is the
+part addressing CVE-2026-52490. The row/column zero and division based
+MAX_SECTIONS guards come from the earlier upstream commits e12d1cf7 and
+2f0509b0, which this change builds on. _TIFFCastUInt64ToUInt32() does not
+exist in 4.5.0, so the uint64_t product is checked against UINT32_MAX
+directly instead.
+
+Origin: backport, 
https://gitlab.com/libtiff/libtiff/-/commit/b04e935cb6242f22cc8b63c99a372cf3ea825e4e
+Bug-Debian: https://bugs.debian.org/1147247
+---
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -459,6 +459,7 @@ struct pagedef
+     uint16_t res_unit;   /* resolution unit for output image */
+     unsigned int rows;   /* number of section rows */
+     unsigned int cols;   /* number of section cols */
++    uint32_t total_sections;
+     unsigned int orient; /* portrait, landscape, seascape, auto */
+ };
+ 
+@@ -2392,13 +2393,30 @@ void process_command_opts(int argc, char
+                     page->cols = atoi(optarg);
+                     page->rows = atoi(optarg);
+                 }
+-                if ((page->cols * page->rows) > MAX_SECTIONS)
++                if ((page->cols == 0) || (page->rows == 0))
++                {
++                    TIFFError("Invalid subdivisions",
++                              "Rows and columns must be non-zero");
++                    exit(EXIT_FAILURE);
++                }
++
++                if (page->cols > (MAX_SECTIONS / page->rows))
+                 {
+                     TIFFError(
+                         "Limit for subdivisions, ie rows x columns, exceeded",
+                         "%d", MAX_SECTIONS);
+                     exit(EXIT_FAILURE);
+                 }
++                {
++                    uint64_t total_sections64 =
++                        (uint64_t)page->cols * (uint64_t)page->rows;
++                    if (total_sections64 == 0 || total_sections64 > 
UINT32_MAX)
++                    {
++                        TIFFError("No subdivisions", "%u", 0U);
++                        exit(EXIT_FAILURE);
++                    }
++                    page->total_sections = (uint32_t)total_sections64;
++                }
+                 page->mode |= PAGE_MODE_ROWSCOLS;
+                 break;
+             case 'U': /* units for measurements and offsets */
+@@ -5710,6 +5728,7 @@ static void initPageSetup(struct pagedef
+     page->vmargin = 0.0;
+     page->rows = 0;
+     page->cols = 0;
++    page->total_sections = 0;
+     page->orient = ORIENTATION_NONE;
+ 
+     for (i = 0; i < MAX_SECTIONS; i++)
+@@ -6698,13 +6717,23 @@ static int computeOutputPixelOffsets(str
+ 
+     line_bytes = TIFFhowmany8(owidth * image->spp * image->bps);
+ 
+-    if ((orows * ocols) > MAX_SECTIONS)
++    if ((orows == 0) || (ocols == 0) || (ocols > (MAX_SECTIONS / orows)))
+     {
+         TIFFError("computeOutputPixelOffsets",
+                   "Rows and Columns exceed maximum sections\nIncrease "
+                   "resolution or reduce sections");
+         return (-1);
+     }
++    {
++        uint64_t total_sections64 = (uint64_t)orows * (uint64_t)ocols;
++        if (total_sections64 == 0 || total_sections64 > UINT32_MAX)
++        {
++            TIFFError("computeOutputPixelOffsets",
++                      "Integer overflow computing subdivision count");
++            return (-1);
++        }
++        page->total_sections = (uint32_t)total_sections64;
++    }
+ 
+     /* build the list of offsets for each output section */
+     for (k = 0, i = 0; i < orows; i++)
+@@ -6725,7 +6754,7 @@ static int computeOutputPixelOffsets(str
+             sections[k].y2 = y2;
+             sections[k].buffsize = line_bytes * olength;
+             sections[k].position = k + 1;
+-            sections[k].total = orows * ocols;
++            sections[k].total = (int)page->total_sections;
+         }
+     }
+     return (0);
+@@ -8046,10 +8075,32 @@ static int writeImageSections(TIFF *in,
+     uint32_t i, k, width, length, sectsize;
+     unsigned char *sect_buff = *sect_buff_ptr;
+ 
++    if ((page->cols == 0) || (page->rows == 0))
++    {
++        TIFFError("Invalid subdivisions", "Rows and columns must be 
non-zero");
++        return (-1);
++    }
++
++    if (page->cols > (MAX_SECTIONS / page->rows))
++    {
++        TIFFError("writeImageSections",
++                  "Rows and Columns exceed maximum sections\n"
++                  "Increase resolution or reduce sections");
++        return (-1);
++    }
++    if (page->total_sections == 0)
++    {
++        uint64_t total_sections64 =
++            (uint64_t)page->cols * (uint64_t)page->rows;
++        if (total_sections64 == 0 || total_sections64 > UINT32_MAX)
++            return (-1);
++        page->total_sections = (uint32_t)total_sections64;
++    }
++
+     hres = page->hres;
+     vres = page->vres;
+ 
+-    k = page->cols * page->rows;
++    k = page->total_sections;
+     if ((k < 1) || (k > MAX_SECTIONS))
+     {
+         TIFFError("writeImageSections",
diff -Nru 
tiff-4.5.0/debian/patches/pixarlog-add-comment-explaining-4-byte-advance-in-AB.patch
 
tiff-4.5.0/debian/patches/pixarlog-add-comment-explaining-4-byte-advance-in-AB.patch
--- 
tiff-4.5.0/debian/patches/pixarlog-add-comment-explaining-4-byte-advance-in-AB.patch
        1969-12-31 21:00:00.000000000 -0300
+++ 
tiff-4.5.0/debian/patches/pixarlog-add-comment-explaining-4-byte-advance-in-AB.patch
        2026-09-22 20:02:07.000000000 -0300
@@ -0,0 +1,29 @@
+From: waugustus <[email protected]>
+Date: Fri, 24 Apr 2026 09:16:55 +0800
+Subject: pixarlog: add comment explaining 4-byte advance in ABGR decode
+Origin: 
https://gitlab.com/libtiff/libtiff/-/commit/51fa6dfe93f20da0d38f079fbc61c7c960bcbc16
+Bug: https://gitlab.com/libtiff/libtiff/-/merge_requests/873
+Bug-Debian: https://bugs.debian.org/1141320
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12912
+
+---
+ libtiff/tif_pixarlog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
+index 18466144522a..8efd92737bd0 100644
+--- a/libtiff/tif_pixarlog.c
++++ b/libtiff/tif_pixarlog.c
+@@ -1004,6 +1004,9 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+             case PIXARLOGDATAFMT_8BITABGR:
+                 horizontalAccumulate8abgr(up, llen, sp->stride,
+                                           (unsigned char *)op, sp->ToLinear8);
++
++                /* For stride == 3 (RGB), horizontalAccumulate8abgr expands 
to 4
++                 * bytes/pixel (ABGR) */
+                 if (sp->stride == 3)
+                     op += (unsigned long)td->td_imagewidth * 4;
+                 else
+-- 
+2.53.0
+
diff -Nru 
tiff-4.5.0/debian/patches/pixarlog-complete-ABGR-bounds-check-for-multi-row-st.patch
 
tiff-4.5.0/debian/patches/pixarlog-complete-ABGR-bounds-check-for-multi-row-st.patch
--- 
tiff-4.5.0/debian/patches/pixarlog-complete-ABGR-bounds-check-for-multi-row-st.patch
        1969-12-31 21:00:00.000000000 -0300
+++ 
tiff-4.5.0/debian/patches/pixarlog-complete-ABGR-bounds-check-for-multi-row-st.patch
        2026-09-22 20:02:07.000000000 -0300
@@ -0,0 +1,59 @@
+From: waugustus <[email protected]>
+Date: Thu, 7 May 2026 12:48:42 +0800
+Subject: pixarlog: complete ABGR bounds check for multi-row strip decoding
+Origin: 
https://gitlab.com/libtiff/libtiff/-/commit/f9bda11bf2fc819b971517582666d56f18b1bc3f
+Bug: https://gitlab.com/libtiff/libtiff/-/merge_requests/883
+Bug-Debian: https://bugs.debian.org/1141320
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12912
+
+---
+ libtiff/tif_pixarlog.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
+index f35f3fb01588..a6f62f18b3b7 100644
+--- a/libtiff/tif_pixarlog.c
++++ b/libtiff/tif_pixarlog.c
+@@ -880,6 +880,12 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+     if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3)
+     {
+         tmsize_t required = (tmsize_t)td->td_imagewidth * 4;
++        tmsize_t max_rows;
++        tmsize_t max_nsamples;
++
++        /*
++         * Ensure at least one expanded output row fits.
++         */
+         if (occ < required)
+         {
+             TIFFErrorExtR(tif, module,
+@@ -887,6 +893,26 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+             memset(op, 0, (size_t)occ);
+             return (0);
+         }
++
++        /*
++         * PixarLogDecode() may process multiple rows per call
++         * (e.g. strip decoding). Limit nsamples so the total
++         * output written by the loop below never exceeds occ.
++         */
++        max_rows = occ / required;
++        max_nsamples = max_rows * llen;
++
++        /*
++         * Truncate excess rows to preserve as much decoded data
++         * as possible while avoiding output buffer overflow.
++         */
++        if (nsamples > max_nsamples)
++        {
++            TIFFWarningExtR(tif, module,
++                            "PixarLog ABGR decode truncated to avoid "
++                            "output buffer overflow");
++            nsamples = max_nsamples;
++        }
+     }
+ 
+     (void)s;
+-- 
+2.53.0
+
diff -Nru 
tiff-4.5.0/debian/patches/pixarlog-error-out-on-invalid-ABGR-output-buffer-siz.patch
 
tiff-4.5.0/debian/patches/pixarlog-error-out-on-invalid-ABGR-output-buffer-siz.patch
--- 
tiff-4.5.0/debian/patches/pixarlog-error-out-on-invalid-ABGR-output-buffer-siz.patch
        1969-12-31 21:00:00.000000000 -0300
+++ 
tiff-4.5.0/debian/patches/pixarlog-error-out-on-invalid-ABGR-output-buffer-siz.patch
        2026-09-22 20:02:07.000000000 -0300
@@ -0,0 +1,60 @@
+From: waugustus <[email protected]>
+Date: Thu, 7 May 2026 16:22:27 +0800
+Subject: pixarlog: error out on invalid ABGR output buffer sizes
+Origin: 
https://gitlab.com/libtiff/libtiff/-/commit/90601d9a23382d98f3695ec14441145c37a77574
+Bug: https://gitlab.com/libtiff/libtiff/-/merge_requests/883
+Bug-Debian: https://bugs.debian.org/1141320
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12912
+
+---
+ libtiff/tif_pixarlog.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
+index a6f62f18b3b7..fa267dfbff20 100644
+--- a/libtiff/tif_pixarlog.c
++++ b/libtiff/tif_pixarlog.c
+@@ -894,6 +894,19 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+             return (0);
+         }
+ 
++        /*
++         * The caller-provided output buffer size must represent a whole
++         * number of expanded ABGR scanlines.
++         */
++        if (occ % required)
++        {
++            TIFFErrorExtR(
++                tif, module,
++                "Fractional scanline not supported for PixarLog ABGR data");
++            memset(op, 0, (size_t)occ);
++            return (0);
++        }
++
+         /*
+          * PixarLogDecode() may process multiple rows per call
+          * (e.g. strip decoding). Limit nsamples so the total
+@@ -902,16 +915,12 @@ static int PixarLogDecode(TIFF *tif, uint8_t *op, 
tmsize_t occ, uint16_t s)
+         max_rows = occ / required;
+         max_nsamples = max_rows * llen;
+ 
+-        /*
+-         * Truncate excess rows to preserve as much decoded data
+-         * as possible while avoiding output buffer overflow.
+-         */
+         if (nsamples > max_nsamples)
+         {
+-            TIFFWarningExtR(tif, module,
+-                            "PixarLog ABGR decode truncated to avoid "
+-                            "output buffer overflow");
+-            nsamples = max_nsamples;
++            TIFFErrorExtR(tif, module,
++                          "Output buffer too small for PixarLog ABGR data");
++            memset(op, 0, (size_t)occ);
++            return (0);
+         }
+     }
+ 
+-- 
+2.53.0
+
diff -Nru 
tiff-4.5.0/debian/patches/pixarlog-fix-heap-buffer-overflow-in-8BITABGR-decode.patch
 
tiff-4.5.0/debian/patches/pixarlog-fix-heap-buffer-overflow-in-8BITABGR-decode.patch
--- 
tiff-4.5.0/debian/patches/pixarlog-fix-heap-buffer-overflow-in-8BITABGR-decode.patch
        1969-12-31 21:00:00.000000000 -0300
+++ 
tiff-4.5.0/debian/patches/pixarlog-fix-heap-buffer-overflow-in-8BITABGR-decode.patch
        2026-09-22 20:02:07.000000000 -0300
@@ -0,0 +1,47 @@
+From: waugustus <[email protected]>
+Date: Thu, 23 Apr 2026 17:05:53 +0800
+Subject: pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3
+ (#824)
+Origin: 
https://gitlab.com/libtiff/libtiff/-/commit/ba2b04b114c5dd945107ccc613cedfcca3af73bb
+Bug: https://gitlab.com/libtiff/libtiff/-/merge_requests/873
+Bug-Debian: https://bugs.debian.org/1141320
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12912
+
+---
+ libtiff/tif_pixarlog.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/libtiff/tif_pixarlog.c
++++ b/libtiff/tif_pixarlog.c
+@@ -865,6 +865,19 @@ static int PixarLogDecode(TIFF *tif, uin
+ 
+     llen = sp->stride * td->td_imagewidth;
+ 
++    /* Fix: ABGR with stride=3 expands 3 samples to 4 output bytes per pixel 
*/
++    if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3)
++    {
++        tmsize_t required = (tmsize_t)td->td_imagewidth * 4;
++        if (occ < required)
++        {
++            TIFFErrorExtR(tif, module,
++                          "Output buffer too small for PixarLog ABGR data");
++            memset(op, 0, (size_t)occ);
++            return (0);
++        }
++    }
++
+     (void)s;
+     assert(sp != NULL);
+ 
+@@ -978,7 +991,10 @@ static int PixarLogDecode(TIFF *tif, uin
+             case PIXARLOGDATAFMT_8BITABGR:
+                 horizontalAccumulate8abgr(up, llen, sp->stride,
+                                           (unsigned char *)op, sp->ToLinear8);
+-                op += llen * sizeof(unsigned char);
++                if (sp->stride == 3)
++                    op += (unsigned long)td->td_imagewidth * 4;
++                else
++                    op += (unsigned long)llen * sizeof(unsigned char);
+                 break;
+             default:
+                 TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" 
PRIu16,
diff -Nru tiff-4.5.0/debian/patches/series tiff-4.5.0/debian/patches/series
--- tiff-4.5.0/debian/patches/series    2026-04-07 14:22:16.000000000 -0300
+++ tiff-4.5.0/debian/patches/series    2026-09-22 20:02:07.000000000 -0300
@@ -20,3 +20,12 @@
 CVE-2024-7006.patch
 CVE-2025-9900.patch
 CVE-2026-4775.patch
+CVE-2024-13978_1.patch
+CVE-2024-13978_2.patch
+pixarlog-fix-heap-buffer-overflow-in-8BITABGR-decode.patch
+pixarlog-add-comment-explaining-4-byte-advance-in-AB.patch
+pixarlog-complete-ABGR-bounds-check-for-multi-row-st.patch
+pixarlog-error-out-on-invalid-ABGR-output-buffer-siz.patch
+CVE-2026-52490.patch
+CVE-2026-18495.patch
+CVE-2026-36849.patch
diff -Nru tiff-4.5.0/debian/salsa-ci.yml tiff-4.5.0/debian/salsa-ci.yml
--- tiff-4.5.0/debian/salsa-ci.yml      1969-12-31 21:00:00.000000000 -0300
+++ tiff-4.5.0/debian/salsa-ci.yml      2026-09-22 20:02:07.000000000 -0300
@@ -0,0 +1,5 @@
+include:
+  - https://salsa.debian.org/lts-team/pipeline/raw/master/recipes/bookworm.yml
+
+test-uscan:
+  allow_failure: true

Attachment: signature.asc
Description: PGP signature

Reply via email to