[packages/gd] Rel 10. Fix CVE-2026-9672 (GIF LZW uninitialised reads) and GHSA-xxr2-j7hw-3698. Add GD-2.3 memory-s

arekm arekm at pld-linux.org
Thu Oct 22 09:26:46 CEST 2026


commit a20c455d4c282458015f4c7f0835052467d9296f
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Thu Oct 22 09:26:24 2026 +0200

    Rel 10. Fix CVE-2026-9672 (GIF LZW uninitialised reads) and GHSA-xxr2-j7hw-3698.
    Add GD-2.3 memory-safety fixes: gdImageColorTransparent (#785), rotate 180 (#810), gdImageClone (#855).

 gd-clone-polyints.patch  | 22 ++++++++++++++++++++++
 gd-gif-lzw-init.patch    | 31 +++++++++++++++++++++++++++++++
 gd-rotate180-uaf.patch   | 13 +++++++++++++
 gd-tiff-overflow.patch   | 15 +++++++++++++++
 gd-transparent-oob.patch | 15 +++++++++++++++
 gd.spec                  | 12 +++++++++++-
 6 files changed, 107 insertions(+), 1 deletion(-)
---
diff --git a/gd.spec b/gd.spec
index 19d24b7..7ac5e4f 100644
--- a/gd.spec
+++ b/gd.spec
@@ -18,7 +18,7 @@ Summary(pl.UTF-8):	Biblioteka do tworzenia grafiki w formacie PNG, JPEG
 Summary(pt_BR.UTF-8):	Biblioteca para manipulação de imagens
 Name:		gd
 Version:	2.3.3
-Release:	9
+Release:	10
 License:	BSD-like
 Group:		Libraries
 #Source0Download: https://github.com/libgd/libgd/releases
@@ -29,6 +29,11 @@ Patch1:		%{name}-loop.patch
 Patch2:		api-breakage.patch
 Patch3:		%{name}-avif.patch
 Patch4:		%{name}-heif.patch
+Patch5:		%{name}-gif-lzw-init.patch
+Patch6:		%{name}-tiff-overflow.patch
+Patch7:		%{name}-transparent-oob.patch
+Patch8:		%{name}-rotate180-uaf.patch
+Patch9:		%{name}-clone-polyints.patch
 URL:		https://libgd.github.io/
 BuildRequires:	autoconf >= 2.54
 BuildRequires:	automake
@@ -177,6 +182,11 @@ para uso pelos programas que usam a libgd.
 %patch -P2 -p1
 %patch -P3 -p1
 %patch -P4 -p1
+%patch -P5 -p1
+%patch -P6 -p1
+%patch -P7 -p1
+%patch -P8 -p1
+%patch -P9 -p1
 
 %build
 %{__libtoolize}
diff --git a/gd-clone-polyints.patch b/gd-clone-polyints.patch
new file mode 100644
index 0000000..77727a0
--- /dev/null
+++ b/gd-clone-polyints.patch
@@ -0,0 +1,22 @@
+# gdImageClone() writes to dst->polyInts that was never allocated after a polygon fill
+# https://github.com/libgd/libgd/commit/cb47e0882a (#855), plus the allocation check upstream lacks
+--- a/src/gd.c
++++ b/src/gd.c
+@@ -2918,10 +2918,13 @@
+ 		dst->tileColorMap[i] = src->tileColorMap[i];
+ 	}
+ 
+-	if (src->polyAllocated > 0) {
+-		dst->polyAllocated = src->polyAllocated;
+-		for (i = 0; i < src->polyAllocated; i++) {
+-			dst->polyInts[i] = src->polyInts[i];
++	if (src->polyAllocated > 0 && overflow2(sizeof(int), src->polyAllocated) == 0) {
++		dst->polyInts = gdMalloc (sizeof (int) * src->polyAllocated);
++		if (dst->polyInts) {
++			dst->polyAllocated = src->polyAllocated;
++			for (i = 0; i < src->polyAllocated; i++) {
++				dst->polyInts[i] = src->polyInts[i];
++			}
+ 		}
+ 	}
+ 
diff --git a/gd-gif-lzw-init.patch b/gd-gif-lzw-init.patch
new file mode 100644
index 0000000..33402c2
--- /dev/null
+++ b/gd-gif-lzw-init.patch
@@ -0,0 +1,31 @@
+# CVE-2026-9672: LZW decoder reads uninitialised table[1][] and decodes past the end code
+# https://github.com/php/php-src/commit/b590f0380fda26ed180874a0255f0be078434315
+--- a/src/gd_gif_in.c
++++ b/src/gd_gif_in.c
+@@ -530,7 +530,7 @@
+ 		}
+ 
+ 		for(; i < (1 << MAX_LWZ_BITS); ++i) {
+-			sd->table[0][i] = sd->table[1][0] = 0;
++			sd->table[0][i] = sd->table[1][i] = 0;
+ 		}
+ 
+ 		sd->sp = sd->stack;
+@@ -585,6 +585,8 @@
+ 			if((count != 0) || (max_count < 0)) {
+ 				return -2;
+ 			}
++
++			return -2;
+ 		}
+ 
+ 		incode = code;
+@@ -665,7 +667,7 @@
+ 	unsigned char c;
+ 	int xpos = 0, ypos = 0, pass = 0;
+ 	int v, i;
+-	LZW_STATIC_DATA sd;
++	LZW_STATIC_DATA sd = {0};
+ 
+ 	/* Initialize the Compression routines */
+ 	if(!ReadOK(fd, &c, 1)) {
diff --git a/gd-rotate180-uaf.patch b/gd-rotate180-uaf.patch
new file mode 100644
index 0000000..18cb706
--- /dev/null
+++ b/gd-rotate180-uaf.patch
@@ -0,0 +1,13 @@
+# gdImageRotateInterpolated() destroys the caller's palette image instead of its clone at 180 degrees, then rotates it
+# https://github.com/libgd/libgd/commit/3a9d9a892b (#810)
+--- a/src/gd_interpolation.c
++++ b/src/gd_interpolation.c
+@@ -1864,7 +1864,7 @@
+ 
+ 		case -18000:
+ 		case  18000:
+-			if (src_cloned) gdImageDestroy(src);
++			if (src_cloned) gdImageDestroy(src_tc);
+ 			return gdImageRotate180(src, 0);
+ 
+ 		case  -9000:
diff --git a/gd-tiff-overflow.patch b/gd-tiff-overflow.patch
new file mode 100644
index 0000000..9aff3a2
--- /dev/null
+++ b/gd-tiff-overflow.patch
@@ -0,0 +1,15 @@
+# GHSA-xxr2-j7hw-3698: 4 * width * height wraps in createFromTiffRgba() where calloc() does not check it
+# https://github.com/libgd/libgd/commit/22d1379e64
+--- a/src/gd_tiff.c
++++ b/src/gd_tiff.c
+@@ -765,6 +765,10 @@
+ 	uint32_t rgba;
+ 	int success;
+ 
++	if (overflow2(width, height) || overflow2(width * height, sizeof(uint32_t))) {
++		return GD_FAILURE;
++	}
++
+ 	buffer = (uint32_t *) gdCalloc(sizeof(uint32_t), width * height);
+ 	if (!buffer) {
+ 		return GD_FAILURE;
diff --git a/gd-transparent-oob.patch b/gd-transparent-oob.patch
new file mode 100644
index 0000000..0cb07ba
--- /dev/null
+++ b/gd-transparent-oob.patch
@@ -0,0 +1,15 @@
+# gdImageColorTransparent() writes im->alpha[-1] on the first call, reached from every GIF with a transparent colour
+# https://github.com/libgd/libgd/commit/e050c86948 (#785)
+--- a/src/gd.c
++++ b/src/gd.c
+@@ -919,7 +919,9 @@
+ 	if (color >= gdMaxColors) {
+ 		return;
+ 	}
+-	im->alpha[im->transparent] = gdAlphaOpaque;
++	if (im->transparent != -1) {
++		im->alpha[im->transparent] = gdAlphaOpaque;
++	}
+ 	im->alpha[color] = gdAlphaTransparent;
+ 	im->transparent = color;
+ }
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/gd.git/commitdiff/a20c455d4c282458015f4c7f0835052467d9296f



More information about the pld-cvs-commit mailing list