new file mode 100644
@@ -0,0 +1,60 @@
+From 788a624d7387a758ffd5c7ab010f1870dea753a1 Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <ctruta@gmail.com>
+Date: Sat, 29 Nov 2025 00:39:16 +0200
+Subject: [PATCH] Fix an out-of-bounds read in `png_image_read_composite`
+
+Add a defensive bounds check before calling PNG_sRGB_FROM_LINEAR to
+prevent reading up to 506 entries (1012 bytes) past `png_sRGB_base[]`.
+
+For palette images with gamma, `png_init_read_transformations`
+clears PNG_COMPOSE after compositing on the palette, but it leaves
+PNG_FLAG_OPTIMIZE_ALPHA set. The simplified API then calls
+`png_image_read_composite` with sRGB data (not linear premultiplied),
+causing the index to reach 1017. (The maximum valid index is 511.)
+
+NOTE:
+This is a defensive fix that addresses the security issue (out-of-bounds
+read) but *NOT* the correctness issue (wrong output). When the clamp
+triggers, the affected pixels are clamped to white instead of the
+correct composited color. Valid PNG images may render incorrectly with
+the simplified API.
+
+TODO:
+We already know the root cause is a flag synchronization error.
+For palette images with gamma, `png_init_read_transformations`
+clears PNG_COMPOSE but leaves PNG_FLAG_OPTIMIZE_ALPHA set, causing
+`png_image_read_composite` to misinterpret sRGB data as linear
+premultiplied. However, we have yet to implement an architectural fix
+that requires coordinating the simplified API with the transformation
+pipeline.
+
+Reported-by: flyfish101 <flyfish101@users.noreply.github.com>
+
+CVE: CVE-2025-66293
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/788a624d7387a758ffd5c7ab010f1870dea753a1]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ pngread.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/pngread.c b/pngread.c
+index 79917daaa..ab62edd9d 100644
+--- a/pngread.c
++++ b/pngread.c
+@@ -3406,9 +3406,14 @@ png_image_read_composite(png_voidp argument)
+ component += (255-alpha)*png_sRGB_table[outrow[c]];
+
+ /* So 'component' is scaled by 255*65535 and is
+- * therefore appropriate for the sRGB to linear
+- * conversion table.
++ * therefore appropriate for the sRGB-to-linear
++ * conversion table. Clamp to the valid range
++ * as a defensive measure against an internal
++ * libpng bug where the data is sRGB rather than
++ * linear premultiplied.
+ */
++ if (component > 255*65535)
++ component = 255*65535;
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
new file mode 100644
@@ -0,0 +1,125 @@
+From a05a48b756de63e3234ea6b3b938b8f5f862484a Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <ctruta@gmail.com>
+Date: Mon, 1 Dec 2025 22:31:54 +0200
+Subject: [PATCH] Finalize the fix for out-of-bounds read in
+ `png_image_read_composite`
+
+Following up on commit 788a624d7387a758ffd5c7ab010f1870dea753a1.
+
+The previous commit added a defensive bounds check to address the
+security issue (out-of-bounds read), but noted that the correctness
+issue remained: when the clamp triggered, the affected pixels were
+clamped to white instead of the correct composited color.
+
+This commit addresses the correctness issue by fixing the flag
+synchronization error identified in the previous commit's TODO:
+
+1. In `png_init_read_transformations`:
+ Clear PNG_FLAG_OPTIMIZE_ALPHA when clearing PNG_COMPOSE for palette
+ images. This correctly signals that the data is sRGB, not linear
+ premultiplied.
+
+2. In `png_image_read_composite`:
+ Check PNG_FLAG_OPTIMIZE_ALPHA and use the appropriate composition
+ formula. When set, use the existing linear composition. When cleared
+ (palette composition already done), use sRGB composition to match
+ what was done to the palette.
+
+Retain the previous clamp to the valid range as belt-and-suspenders
+protection against any other unforeseen cases.
+
+CVE: CVE-2025-66293
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/a05a48b756de63e3234ea6b3b938b8f5f862484a]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ pngread.c | 56 ++++++++++++++++++++++++++++++++++++------------------
+ pngrtran.c | 1 +
+ 2 files changed, 39 insertions(+), 18 deletions(-)
+
+diff --git a/pngread.c b/pngread.c
+index ab62edd9d..f8ca2b7e3 100644
+--- a/pngread.c
++++ b/pngread.c
+@@ -3340,6 +3340,7 @@ png_image_read_composite(png_voidp argument)
+ ptrdiff_t step_row = display->row_bytes;
+ unsigned int channels =
+ (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
++ int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+ int pass;
+
+ for (pass = 0; pass < passes; ++pass)
+@@ -3396,25 +3397,44 @@ png_image_read_composite(png_voidp argument)
+
+ if (alpha < 255) /* else just use component */
+ {
+- /* This is PNG_OPTIMIZED_ALPHA, the component value
+- * is a linear 8-bit value. Combine this with the
+- * current outrow[c] value which is sRGB encoded.
+- * Arithmetic here is 16-bits to preserve the output
+- * values correctly.
+- */
+- component *= 257*255; /* =65535 */
+- component += (255-alpha)*png_sRGB_table[outrow[c]];
++ if (optimize_alpha != 0)
++ {
++ /* This is PNG_OPTIMIZED_ALPHA, the component value
++ * is a linear 8-bit value. Combine this with the
++ * current outrow[c] value which is sRGB encoded.
++ * Arithmetic here is 16-bits to preserve the output
++ * values correctly.
++ */
++ component *= 257*255; /* =65535 */
++ component += (255-alpha)*png_sRGB_table[outrow[c]];
+
+- /* So 'component' is scaled by 255*65535 and is
+- * therefore appropriate for the sRGB-to-linear
+- * conversion table. Clamp to the valid range
+- * as a defensive measure against an internal
+- * libpng bug where the data is sRGB rather than
+- * linear premultiplied.
+- */
+- if (component > 255*65535)
+- component = 255*65535;
+- component = PNG_sRGB_FROM_LINEAR(component);
++ /* Clamp to the valid range to defend against
++ * unforeseen cases where the data might be sRGB
++ * instead of linear premultiplied.
++ * (Belt-and-suspenders for GitHub Issue #764.)
++ */
++ if (component > 255*65535)
++ component = 255*65535;
++
++ /* So 'component' is scaled by 255*65535 and is
++ * therefore appropriate for the sRGB-to-linear
++ * conversion table.
++ */
++ component = PNG_sRGB_FROM_LINEAR(component);
++ }
++ else
++ {
++ /* Compositing was already done on the palette
++ * entries. The data is sRGB premultiplied on black.
++ * Composite with the background in sRGB space.
++ * This is not gamma-correct, but matches what was
++ * done to the palette.
++ */
++ png_uint_32 background = outrow[c];
++ component += ((255-alpha) * background + 127) / 255;
++ if (component > 255)
++ component = 255;
++ }
+ }
+
+ outrow[c] = (png_byte)component;
+diff --git a/pngrtran.c b/pngrtran.c
+index 2f5202255..507d11381 100644
+--- a/pngrtran.c
++++ b/pngrtran.c
+@@ -1760,6 +1760,7 @@ png_init_read_transformations(png_structrp png_ptr)
+ * transformations elsewhere.
+ */
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
++ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ } /* color_type == PNG_COLOR_TYPE_PALETTE */
+
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
@@ -19,6 +19,8 @@ SRC_URI = "${SOURCEFORGE_MIRROR}/project/${BPN}/${BPN}${LIBV}/${PV}/${BP}.tar.xz
file://CVE-2025-64720.patch \
file://CVE-2025-65018-01.patch \
file://CVE-2025-65018-02.patch \
+ file://CVE-2025-66293-01.patch \
+ file://CVE-2025-66293-02.patch \
"
SRC_URI[sha256sum] = "c919dbc11f4c03b05aba3f8884d8eb7adfe3572ad228af972bb60057bdb48450"