new file mode 100644
@@ -0,0 +1,115 @@
+From aa77ef38c17ab2fc1b41bec09fb973c6a386641d Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <ctruta@gmail.com>
+Date: Wed, 23 Sep 2026 18:30:11 +0300
+Subject: [PATCH] fix: Clear stale zstream pointers when releasing the inflate
+ stream
+
+The zstream buffer pointers and counters are all cleared on acquisition
+in `png_inflate_claim`, but only `next_in` and `avail_in` were cleared
+on release in `png_read_finish_IDAT`, and none were cleared on release
+in the chunk decompression paths.
+
+If `png_read_end` is called before row reading starts, the IDAT stream
+is never claimed. Previously, a leftover non-zero `avail_in` caused the
+refill in `png_read_IDAT_data` to be skipped, and inflation continued
+through a stale `next_in` into an input buffer that may since have been
+deallocated.
+
+Introduce the function `png_inflate_detach_buffers` to clear the
+pointers and the counters of zstream input and output buffers on both
+acquisition and release. Although clearing `next_out` and `avail_out`
+is not currently necessary at any call site, it makes release mirror
+acquisition at a negligible cost paid once for each zlib stream.
+
+This is a cherry-pick of commit 6c7783b151377f591c83955e23da50991ad1a600
+from branch 'libpng18'.
+
+Reported-by: Ze Sheng <OwenSanzas@users.noreply.github.com>
+Reported-by: JasonHonKL <JasonHonKL@users.noreply.github.com>
+
+CVE: CVE-2026-46675
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/aa77ef38c17ab2fc1b41bec09fb973c6a386641d]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ pngrutil.c | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/pngrutil.c b/pngrutil.c
+index 551395168..482f0ae8d 100644
+--- a/pngrutil.c
++++ b/pngrutil.c
+@@ -332,6 +332,18 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
+ }
+ #endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
+
++/* Detach the zstream from the input and output buffers left by
++ * the current or a previous owner, and possibly deallocated since.
++ */
++static void
++png_inflate_detach_buffers(png_structrp png_ptr)
++{
++ png_ptr->zstream.next_in = NULL;
++ png_ptr->zstream.avail_in = 0;
++ png_ptr->zstream.next_out = NULL;
++ png_ptr->zstream.avail_out = 0;
++}
++
+ /* png_inflate_claim: claim the zstream for some nefarious purpose that involves
+ * decompression. Returns Z_OK on success, else a zlib error code. It checks
+ * the owner but, in final release builds, just issues a warning if some other
+@@ -392,13 +404,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+
+ #endif /* ZLIB_VERNUM >= 0x1240 */
+
+- /* Set this for safety, just in case the previous owner left pointers to
+- * memory allocations.
+- */
+- png_ptr->zstream.next_in = NULL;
+- png_ptr->zstream.avail_in = 0;
+- png_ptr->zstream.next_out = NULL;
+- png_ptr->zstream.avail_out = 0;
++ png_inflate_detach_buffers(png_ptr);
+
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ {
+@@ -744,7 +750,8 @@ png_decompress_chunk(png_structrp png_ptr,
+ else if (ret == Z_OK)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+- /* Release the claimed stream */
++ /* Release the claimed stream. */
++ png_inflate_detach_buffers(png_ptr);
+ png_ptr->zowner = 0;
+ }
+
+@@ -1569,6 +1576,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+
+ if (errmsg == NULL)
+ {
++ png_inflate_detach_buffers(png_ptr);
+ png_ptr->zowner = 0;
+ return;
+ }
+@@ -1595,7 +1603,8 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+ else /* profile truncated */
+ errmsg = png_ptr->zstream.msg;
+
+- /* Release the stream */
++ /* Release the claimed stream. */
++ png_inflate_detach_buffers(png_ptr);
+ png_ptr->zowner = 0;
+ }
+
+@@ -4294,11 +4303,7 @@ png_read_finish_IDAT(png_structrp png_ptr)
+ */
+ if (png_ptr->zowner == png_IDAT)
+ {
+- /* Always do this; the pointers otherwise point into the read buffer. */
+- png_ptr->zstream.next_in = NULL;
+- png_ptr->zstream.avail_in = 0;
+-
+- /* Now we no longer own the zstream. */
++ png_inflate_detach_buffers(png_ptr);
+ png_ptr->zowner = 0;
+
+ /* The slightly weird semantics of the sequential IDAT reading is that we
@@ -32,6 +32,7 @@ SRC_URI = "${SOURCEFORGE_MIRROR}/project/${BPN}/${BPN}${LIBV}/${PV}/${BP}.tar.xz
file://CVE-2026-34757_p1.patch \
file://CVE-2026-34757_p2.patch \
file://CVE-2026-33416-05.patch \
+ file://CVE-2026-46675.patch \
"
SRC_URI[sha256sum] = "c919dbc11f4c03b05aba3f8884d8eb7adfe3572ad228af972bb60057bdb48450"