From 788a624d7387a758ffd5c7ab010f1870dea753a1 Mon Sep 17 00:00:00 2001 From: Cosmin Truta 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 CVE: CVE-2025-66293 Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/788a624d7387a758ffd5c7ab010f1870dea753a1] Signed-off-by: Peter Marko --- 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 @@ -3404,9 +3404,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); }