Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:libpng1.6
User: [email protected]
Usertags: pu
(Same as #1126331, but this time for bookworm)
Upstream has released a new upstream version fixing two CVEs:
- CVE-2026-22801 - Heap buffer over-read (Closes: #1125444
- CVE-2026-22695 - Heap buffer over-read (Closes: #1125443)
CVE-2026-22695 has been introduced by CVE-2025-65018, fixed in bookworm
via 1.6.39-2+deb12u1.
I've coordinated with the security team and we've settled on updating
the issues via o-s-p-u.
[ Tests ]
CVE-2026-22801 is covered by the upstream test-suite,
CVE-2026-22695's is quite a small fix, and upstream throughly analysed
the change, see https://github.com/pnggroup/libpng/issues/778.
(We're cherry-picking e4f7ad4, as suggested by upstream):
"Fixed in commit e4f7ad4, to be cherry-picked by downstream libpng
package maintainers.")
[ Checklist ]
[X] *all* changes are documented in the d/changelog
[X] I reviewed all changes and I approve them
[X] attach debdiff against the package in (old)stable
[X] the issue is verified as fixed in unstable
I'll upload the package after sending this bug.
--
tobi
diff -Nru libpng1.6-1.6.39/debian/changelog libpng1.6-1.6.39/debian/changelog
--- libpng1.6-1.6.39/debian/changelog 2025-12-06 11:15:39.000000000 +0100
+++ libpng1.6-1.6.39/debian/changelog 2026-01-24 14:15:14.000000000 +0100
@@ -1,3 +1,11 @@
+libpng1.6 (1.6.39-2+deb12u2) bookworm; urgency=medium
+
+ * Backporting fixes from 1.6.54 for oldstable:
+ - 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 14:15:14 +0100
+
libpng1.6 (1.6.39-2+deb12u1) bookworm-security; urgency=high
* Security upload targeting boowkorm.
diff -Nru libpng1.6-1.6.39/debian/patches/CVE-2026-22695.patch
libpng1.6-1.6.39/debian/patches/CVE-2026-22695.patch
--- libpng1.6-1.6.39/debian/patches/CVE-2026-22695.patch 1970-01-01
01:00:00.000000000 +0100
+++ libpng1.6-1.6.39/debian/patches/CVE-2026-22695.patch 2026-01-24
14:10:46.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
+@@ -22,6 +22,7 @@
+ * Mike Klein
+ * Pascal Massimino
+ * Paul Schmidt
++ * Petr Simecek
+ * Qiang Zhou
+ * Sam Bushell
+ * Samuel Williams
+--- a/pngread.c
++++ b/pngread.c
+@@ -3268,9 +3268,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. */
+@@ -3300,7 +3302,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.39/debian/patches/CVE-2026-22801.patch
libpng1.6-1.6.39/debian/patches/CVE-2026-22801.patch
--- libpng1.6-1.6.39/debian/patches/CVE-2026-22801.patch 1970-01-01
01:00:00.000000000 +0100
+++ libpng1.6-1.6.39/debian/patches/CVE-2026-22801.patch 2026-01-24
14:08:46.000000000 +0100
@@ -0,0 +1,155 @@
+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
+
+-# Copyright (c) 2018-2022 Cosmin Truta
++# Copyright (c) 2018-2026 Cosmin Truta
+ # Copyright (c) 2007,2009-2018 Glenn Randers-Pehrson
+ # Written by Christian Ehrlicher, 2007
+ # Revised by Roger Lowman, 2009-2010
+@@ -804,6 +804,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 png)
+
+--- 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,7 +1,7 @@
+
+ /* pngwrite.c - general routines to write a PNG file
+ *
+- * Copyright (c) 2018-2022 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.
+@@ -1632,7 +1632,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;
+@@ -1758,7 +1758,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 */
+ }
+
+@@ -1783,7 +1783,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;
+ }
+ }
+
+@@ -2102,7 +2102,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.39/debian/patches/series
libpng1.6-1.6.39/debian/patches/series
--- libpng1.6-1.6.39/debian/patches/series 2025-12-06 11:15:39.000000000
+0100
+++ libpng1.6-1.6.39/debian/patches/series 2026-01-24 14:02:48.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