From 3bddf1548c274f4efaf113af871d87688dd605ab Mon Sep 17 00:00:00 2001 From: waugustus Date: Thu, 23 Apr 2026 17:05:53 +0800 Subject: [PATCH 1/2] pixarlog: fix heap-buffer-overflow in 8BITABGR decode with stride 3 (#824) --- libtiff/tif_pixarlog.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c index a4c932cb..447244d3 100644 --- a/libtiff/tif_pixarlog.c +++ b/libtiff/tif_pixarlog.c @@ -746,6 +746,19 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) 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) + { + tsize_t required = (tsize_t)td->td_imagewidth * 4; + if (occ < required) + { + TIFFErrorExt(tif->tif_clientdata, module, + "Output buffer too small for PixarLog ABGR data"); + memset(op, 0, (size_t)occ); + return (0); + } + } + (void) s; assert(sp != NULL); sp->stream.next_out = (unsigned char *) sp->tbuf; @@ -825,7 +838,10 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) case PIXARLOGDATAFMT_8BITABGR: horizontalAccumulate8abgr(up, llen, sp->stride, (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); + if (sp->stride == 3) + op += td->td_imagewidth * 4; + else + op += llen * sizeof(unsigned char); break; default: TIFFErrorExt(tif->tif_clientdata, tif->tif_name, -- 2.52.0 From c29a602200eb255f69587a35ef0c5a9f68c0ad8e Mon Sep 17 00:00:00 2001 From: waugustus Date: Thu, 7 May 2026 12:48:42 +0800 Subject: [PATCH 2/2] pixarlog: complete ABGR bounds check for multi-row strip decoding --- libtiff/tif_pixarlog.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c index 447244d3..993e1f33 100644 --- a/libtiff/tif_pixarlog.c +++ b/libtiff/tif_pixarlog.c @@ -750,6 +750,12 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) if (sp->user_datafmt == PIXARLOGDATAFMT_8BITABGR && sp->stride == 3) { tsize_t required = (tsize_t)td->td_imagewidth * 4; + tsize_t max_rows; + tsize_t max_nsamples; + + /* + * Ensure at least one expanded output row fits. + */ if (occ < required) { TIFFErrorExt(tif->tif_clientdata, module, @@ -757,6 +763,26 @@ PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_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) + { + TIFFWarningExt(tif->tif_clientdata, module, + "PixarLog ABGR decode truncated to avoid " + "output buffer overflow"); + nsamples = max_nsamples; + } } (void) s; -- 2.52.0