From 6a528eb5fd0dd7f6de1c39d30de0e41473431c37 Mon Sep 17 00:00:00 2001
From: Cosmin Truta <ctruta@gmail.com>
Date: Sat, 8 Nov 2025 23:58:26 +0200
Subject: [PATCH] Fix a buffer overflow in `png_do_quantize`

Allocate the quantize_index array to PNG_MAX_PALETTE_LENGTH (256 bytes)
instead of num_palette bytes. This approach matches the allocation
pattern for `palette[]`, `trans_alpha[]` and `riffled_palette[]` which
were similarly oversized in libpng 1.2.1 to prevent buffer overflows
from malformed PNG files with out-of-range palette indices.

Out-of-range palette indices `index >= num_palette` will now read
identity-mapped values from the `quantize_index` array (where index N
maps to palette entry N). This prevents undefined behavior while
avoiding runtime bounds checking overhead in the performance-critical
pixel processing loop.

Reported-by: Samsung-PENTEST <Samsung-PENTEST@users.noreply.github.com>
Analyzed-by: degrigis <degrigis@users.noreply.github.com>

CVE: CVE-2025-64505
Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/6a528eb5fd0dd7f6de1c39d30de0e41473431c37]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
 pngrtran.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/pngrtran.c b/pngrtran.c
index 4632dd521..9c2475fde 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -441,14 +441,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
       int i;
 
       /* Initialize the array to index colors.
+       *
+       * Ensure quantize_index can fit 256 elements (PNG_MAX_PALETTE_LENGTH)
+       * rather than num_palette elements. This is to prevent buffer overflows
+       * caused by malformed PNG files with out-of-range palette indices.
        *
        * Be careful to avoid leaking memory. Applications are allowed to call
        * this function more than once per png_struct.
        */
       png_free(png_ptr, png_ptr->quantize_index);
       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
-          (png_alloc_size_t)num_palette);
-      for (i = 0; i < num_palette; i++)
+          PNG_MAX_PALETTE_LENGTH);
+      for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++)
          png_ptr->quantize_index[i] = (png_byte)i;
    }
 
