[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