Package: release.debian.org
Followup-For: Bug #1126331

Debdiff…
diff -Nru libpng1.6-1.6.48/debian/changelog libpng1.6-1.6.48/debian/changelog
--- libpng1.6-1.6.48/debian/changelog   2025-12-06 11:10:16.000000000 +0100
+++ libpng1.6-1.6.48/debian/changelog   2026-01-24 09:32:42.000000000 +0100
@@ -1,3 +1,11 @@
+libpng1.6 (1.6.48-1+deb13u2) trixie; urgency=medium
+
+  * Backporting fixes from 1.6.54 for stable:
+    - CVE-2026-22801 - Heap buffer over-read (Closes: #1125444
+    - CVE-2026-22695 - Heap buffer over-read (Closes: #1125443)
+
+ -- Tobias Frost <[email protected]>  Sat, 24 Jan 2026 09:32:42 +0100
+
 libpng1.6 (1.6.48-1+deb13u1) trixie-security; urgency=high
 
   * Security upload targeting trixie.
diff -Nru libpng1.6-1.6.48/debian/patches/CVE-2026-22695.patch 
libpng1.6-1.6.48/debian/patches/CVE-2026-22695.patch
--- libpng1.6-1.6.48/debian/patches/CVE-2026-22695.patch        1970-01-01 
01:00:00.000000000 +0100
+++ libpng1.6-1.6.48/debian/patches/CVE-2026-22695.patch        2026-01-24 
09:32:42.000000000 +0100
@@ -0,0 +1,78 @@
+Description: CVE-2026-22695 - heap buffer over-read 
+ From 1.6.51 to 1.6.53, there is a heap buffer over-read in the libpng
+ simplified API function png_image_finish_read when processing
+ interlaced 16-bit PNGs with 8-bit output format and non-minimal row
+ stride. This is a regression introduced by the fix for CVE-2025-65018.
+Origin: 
https://github.com/pnggroup/libpng/commit/e4f7ad4ea2a471776c81dda4846b7691925d9786
+Bug: https://github.com/pnggroup/libpng/security/advisories/GHSA-mmq5-27w3-rxpp
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1125443
+
+From e4f7ad4ea2a471776c81dda4846b7691925d9786 Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <[email protected]>
+Date: Fri, 9 Jan 2026 20:51:53 +0200
+Subject: [PATCH] Fix a heap buffer over-read in `png_image_read_direct_scaled`
+
+Fix a regression from commit 218612ddd6b17944e21eda56caf8b4bf7779d1ea.
+
+The function `png_image_read_direct_scaled`, introduced by the fix for
+CVE-2025-65018, copies transformed row data from an intermediate buffer
+(`local_row`) to the user's output buffer. The copy incorrectly used
+`row_bytes` (the caller's stride) as the size parameter to memcpy, even
+though `local_row` is only `png_get_rowbytes()` bytes long.
+
+This causes a heap buffer over-read when:
+
+1. The caller provides a padded stride (e.g., for memory alignment):
+   memcpy reads past the end of `local_row` by `stride - row_width`
+   bytes.
+
+2. The caller provides a negative stride (for bottom-up layouts):
+   casting ptrdiff_t to size_t produces ~2^64, causing memcpy to
+   attempt reading exabytes, resulting in an immediate crash.
+
+The fix consists in using the size of the row buffer for the copy and
+using the stride for pointer advancement only.
+
+Reported-by: Petr Simecek <[email protected]>
+Analyzed-by: Stanislav Fort
+Analyzed-by: Pavel Kohout
+Co-authored-by: Petr Simecek <[email protected]>
+Signed-off-by: Cosmin Truta <[email protected]>
+---
+ AUTHORS   | 1 +
+ pngread.c | 4 +++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -25,6 +25,7 @@
+  * Mike Klein
+  * Pascal Massimino
+  * Paul Schmidt
++ * Petr Simecek
+  * Philippe Antoine
+  * Qiang Zhou
+  * Sam Bushell
+--- a/pngread.c
++++ b/pngread.c
+@@ -3131,9 +3131,11 @@
+        argument);
+    png_imagep image = display->image;
+    png_structrp png_ptr = image->opaque->png_ptr;
++   png_inforp info_ptr = image->opaque->info_ptr;
+    png_bytep local_row = png_voidcast(png_bytep, display->local_row);
+    png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+    ptrdiff_t row_bytes = display->row_bytes;
++   size_t copy_bytes = png_get_rowbytes(png_ptr, info_ptr);
+    int passes;
+ 
+    /* Handle interlacing. */
+@@ -3163,7 +3165,7 @@
+          png_read_row(png_ptr, local_row, NULL);
+ 
+          /* Copy from local_row to user buffer. */
+-         memcpy(output_row, local_row, (size_t)row_bytes);
++         memcpy(output_row, local_row, copy_bytes);
+          output_row += row_bytes;
+       }
+    }
diff -Nru libpng1.6-1.6.48/debian/patches/CVE-2026-22801.patch 
libpng1.6-1.6.48/debian/patches/CVE-2026-22801.patch
--- libpng1.6-1.6.48/debian/patches/CVE-2026-22801.patch        1970-01-01 
01:00:00.000000000 +0100
+++ libpng1.6-1.6.48/debian/patches/CVE-2026-22801.patch        2026-01-24 
09:32:42.000000000 +0100
@@ -0,0 +1,154 @@
+Description: CVE-2026-22801 - heap buffer over-read on negative row stride
+Bug: https://github.com/pnggroup/libpng/security/advisories/GHSA-vgjq-8cw5-ggw8
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1125444
+Origin: 
https://github.com/pnggroup/libpng/commit/cf155de014fc6c5cb199dd681dd5c8fb70429072
+
+From cf155de014fc6c5cb199dd681dd5c8fb70429072 Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <[email protected]>
+Date: Sat, 10 Jan 2026 15:20:18 +0200
+Subject: [PATCH] fix: Remove incorrect truncation casts from
+ `png_write_image_*`
+
+The type of the row stride (`display->row_bytes`) is ptrdiff_t. Casting
+to png_uint_16 before division will truncate large strides, causing
+incorrect pointer arithmetic for images exceeding 65535 bytes per row.
+For bottom-up images (negative stride), the truncation also corrupts
+the sign, advancing the row pointer forward instead of backward.
+
+Remove the erroneous casts and let the compiler handle the pointer
+arithmetic correctly. Also replace `sizeof (png_uint_16)` with 2.
+
+Add regression test via `pngstest --stride-extra N` where N > 32767
+triggers the affected code paths.
+
+A NOTE ABOUT HISTORY:
+The original code in libpng 1.5.6 (2011) had no such casts. They were
+introduced in libpng 1.6.26 (2016), likely to silence compiler warnings
+on 16-bit systems where the cast would be a no-op. On 32/64-bit systems
+the cast truncates the strides above 65535 and corrupts the negative
+strides.
+---
+ CMakeLists.txt              |  9 ++++++++-
+ contrib/libtests/pngstest.c | 29 ++++++++++++++++++++++++++++-
+ pngwrite.c                  | 10 +++++-----
+ tests/pngstest-large-stride |  8 ++++++++
+ 4 files changed, 49 insertions(+), 7 deletions(-)
+ create mode 100755 tests/pngstest-large-stride
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,6 +1,6 @@
+ # CMakeLists.txt - CMake lists for libpng
+ #
+-# Copyright (c) 2018-2025 Cosmin Truta
++# Copyright (c) 2018-2026 Cosmin Truta
+ # Copyright (c) 2007-2018 Glenn Randers-Pehrson
+ # Originally written by Christian Ehrlicher, 2007
+ #
+@@ -895,6 +895,13 @@
+     endforeach()
+   endforeach()
+ 
++  # Regression test:
++  # Use stride_extra > 32767 to trigger row_bytes > 65535 for linear images.
++  png_add_test(NAME pngstest-large-stride
++               COMMAND pngstest
++               OPTIONS --stride-extra 33000 --tmpfile "large-stride-" --log
++               FILES 
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/rgb-alpha-16-linear.png")
++
+   add_executable(pngunknown ${pngunknown_sources})
+   target_link_libraries(pngunknown
+                         PRIVATE png_shared)
+--- a/contrib/libtests/pngstest.c
++++ b/contrib/libtests/pngstest.c
+@@ -3571,6 +3571,33 @@
+          opts |= NO_RESEED;
+       else if (strcmp(arg, "--fault-gbg-warning") == 0)
+          opts |= GBG_ERROR;
++      else if (strcmp(arg, "--stride-extra") == 0)
++      {
++         if (c+1 < argc)
++         {
++            char *ep;
++            unsigned long val = strtoul(argv[++c], &ep, 0);
++
++            if (ep > argv[c] && *ep == 0 && val <= 65535)
++               stride_extra = (int)val;
++
++            else
++            {
++               fflush(stdout);
++               fprintf(stderr, "%s: bad argument for --stride-extra: %s\n",
++                  argv[0], argv[c]);
++               exit(99);
++            }
++         }
++
++         else
++         {
++            fflush(stdout);
++            fprintf(stderr, "%s: missing argument for --stride-extra\n",
++               argv[0]);
++            exit(99);
++         }
++      }
+       else if (strcmp(arg, "--tmpfile") == 0)
+       {
+          if (c+1 < argc)
+--- a/pngwrite.c
++++ b/pngwrite.c
+@@ -1,6 +1,6 @@
+ /* pngwrite.c - general routines to write a PNG file
+  *
+- * Copyright (c) 2018-2025 Cosmin Truta
++ * Copyright (c) 2018-2026 Cosmin Truta
+  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+  * Copyright (c) 1996-1997 Andreas Dilger
+  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+@@ -1676,7 +1676,7 @@
+       }
+ 
+       png_write_row(png_ptr, png_voidcast(png_const_bytep, 
display->local_row));
+-      input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
++      input_row += display->row_bytes / 2;
+    }
+ 
+    return 1;
+@@ -1802,7 +1802,7 @@
+ 
+          png_write_row(png_ptr, png_voidcast(png_const_bytep,
+              display->local_row));
+-         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
++         input_row += display->row_bytes / 2;
+       } /* while y */
+    }
+ 
+@@ -1827,7 +1827,7 @@
+          }
+ 
+          png_write_row(png_ptr, output_row);
+-         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
++         input_row += display->row_bytes / 2;
+       }
+    }
+ 
+@@ -2146,7 +2146,7 @@
+       ptrdiff_t row_bytes = display->row_stride;
+ 
+       if (linear != 0)
+-         row_bytes *= (sizeof (png_uint_16));
++         row_bytes *= 2;
+ 
+       if (row_bytes < 0)
+          row += (image->height-1) * (-row_bytes);
+--- /dev/null
++++ b/tests/pngstest-large-stride
+@@ -0,0 +1,8 @@
++#!/bin/sh
++
++# Regression test:
++# Use stride_extra > 32767 to trigger row_bytes > 65535 for linear images.
++exec ./pngstest \
++     --stride-extra 33000 \
++     --tmpfile "large-stride-" \
++     --log "${srcdir}/contrib/testpngs/rgb-alpha-16-linear.png"
diff -Nru libpng1.6-1.6.48/debian/patches/series 
libpng1.6-1.6.48/debian/patches/series
--- libpng1.6-1.6.48/debian/patches/series      2025-12-06 11:10:16.000000000 
+0100
+++ libpng1.6-1.6.48/debian/patches/series      2026-01-24 09:32:42.000000000 
+0100
@@ -7,3 +7,5 @@
 CVE-2025-65018-part2.patch
 CVE-2025-66293-part1.patch
 CVE-2025-66293-part2.patch
+CVE-2026-22801.patch
+CVE-2026-22695.patch

Reply via email to