[packages/gd] - rel 5; fixes from FC

arekm arekm at pld-linux.org
Sat Feb 1 21:54:18 CET 2020


commit 75d12200fc7c08c2c4dce64af5fc98daf6c078c9
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Sat Feb 1 21:54:05 2020 +0100

    - rel 5; fixes from FC

 gd-2.1.0-multilib.patch                   |  33 ++++
 gd-2.2.5-heap-based-buffer-overflow.patch |  28 +++
 gd-2.2.5-null-pointer.patch               |  74 ++++++++
 gd-2.2.5-potential-double-free.patch      | 283 ++++++++++++++++++++++++++++++
 gd-2.2.5-upstream.patch                   |  62 +++++++
 gd.spec                                   |   9 +-
 6 files changed, 488 insertions(+), 1 deletion(-)
---
diff --git a/gd.spec b/gd.spec
index 017fae1..e0474f9 100644
--- a/gd.spec
+++ b/gd.spec
@@ -15,7 +15,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.2.5
-Release:	4
+Release:	5
 License:	BSD-like
 Group:		Libraries
 #Source0Download: https://github.com/libgd/libgd/releases
@@ -28,6 +28,10 @@ Patch4:		0004-Fix-OOB-read-due-to-crafted-GD-GD2-images.patch
 Patch5:		0005-Fix-tiff_invalid_read-check.patch
 Patch6:		bmp-check-return-value-in-gdImageBmpPtr.patch
 Patch7:		Fix-420-Potential-infinite-loop-in-gdImageCreateFrom.patch
+Patch8:		gd-2.2.5-heap-based-buffer-overflow.patch
+Patch9:		gd-2.2.5-null-pointer.patch
+Patch10:	gd-2.2.5-potential-double-free.patch
+Patch11:	gd-2.2.5-upstream.patch
 URL:		https://libgd.github.io/
 BuildRequires:	autoconf >= 2.54
 BuildRequires:	automake
@@ -170,6 +174,9 @@ para uso pelos programas que usam a libgd.
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
 
 # hack to avoid inclusion of -s in --ldflags
 %{__sed} -i -e 's, at LDFLAGS@,,g' config/gdlib-config.in
diff --git a/gd-2.1.0-multilib.patch b/gd-2.1.0-multilib.patch
new file mode 100644
index 0000000..c4fdc63
--- /dev/null
+++ b/gd-2.1.0-multilib.patch
@@ -0,0 +1,33 @@
+diff -up gd-2.1.0/config/gdlib-config.in.multilib gd-2.1.0/config/gdlib-config.in
+--- gd-2.1.0/config/gdlib-config.in.multilib	2013-04-21 16:58:17.820010758 +0200
++++ gd-2.1.0/config/gdlib-config.in	2013-04-21 16:59:27.896317922 +0200
+@@ -7,9 +7,10 @@
+ # installation directories
+ prefix=@prefix@
+ exec_prefix=@exec_prefix@
+-libdir=@libdir@
++libdir=`pkg-config gdlib --variable=libdir`
+ includedir=@includedir@
+ bindir=@bindir@
++ldflags=`pkg-config gdlib --variable=ldflags`
+ 
+ usage()
+ {
+@@ -68,7 +69,7 @@ while test $# -gt 0; do
+ 	echo @GDLIB_REVISION@
+ 	;;
+     --ldflags)
+-	echo @LDFLAGS@
++	echo $ldflags
+ 	;;
+     --libs)
+ 	echo -lgd @LIBS@ @LIBICONV@
+@@ -83,7 +84,7 @@ while test $# -gt 0; do
+ 	echo "GD library  @VERSION@"
+ 	echo "includedir: $includedir"
+ 	echo "cflags:     -I at includedir@"
+-	echo "ldflags:    @LDFLAGS@"
++	echo "ldflags:    $ldflags"
+ 	echo "libs:       @LIBS@ @LIBICONV@"
+ 	echo "libdir:     $libdir"
+ 	echo "features:   @FEATURES@"
diff --git a/gd-2.2.5-heap-based-buffer-overflow.patch b/gd-2.2.5-heap-based-buffer-overflow.patch
new file mode 100644
index 0000000..ae795d0
--- /dev/null
+++ b/gd-2.2.5-heap-based-buffer-overflow.patch
@@ -0,0 +1,28 @@
+From 98b2e94e62d873acbcc6d968f1f97af9749fe021 Mon Sep 17 00:00:00 2001
+From: Ondrej Dubaj <odubaj at redhat.com>
+Date: Tue, 4 Jun 2019 10:54:45 +0200
+Subject: [PATCH] heap based buffer overflow in
+ gd_color_match.c:gdImageColorMatch() in libgd as used in imagecolormatch()
+
+---
+ src/gd_color_match.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/gd_color_match.c b/src/gd_color_match.c
+index f0842b6..a94a841 100755
+--- a/src/gd_color_match.c
++++ b/src/gd_color_match.c
+@@ -31,8 +31,8 @@ BGD_DECLARE(int) gdImageColorMatch (gdImagePtr im1, gdImagePtr im2)
+ 		return -4; /* At least 1 color must be allocated */
+ 	}
+ 
+-	buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * im2->colorsTotal);
+-	memset (buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );
++	buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * gdMaxColors);
++	memset (buf, 0, sizeof(unsigned long) * 5 * gdMaxColors );
+ 
+ 	for (x=0; x < im1->sx; x++) {
+ 		for( y=0; y<im1->sy; y++ ) {
+-- 
+2.17.1
+
diff --git a/gd-2.2.5-null-pointer.patch b/gd-2.2.5-null-pointer.patch
new file mode 100644
index 0000000..afa18d9
--- /dev/null
+++ b/gd-2.2.5-null-pointer.patch
@@ -0,0 +1,74 @@
+From a93eac0e843148dc2d631c3ba80af17e9c8c860f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?F=C3=A1bio=20Cabral=20Pacheco?= <fcabralpacheco at gmail.com>
+Date: Fri, 20 Dec 2019 12:03:33 -0300
+Subject: [PATCH] Fix potential NULL pointer dereference in gdImageClone()
+
+---
+ src/gd.c                          |  9 +--------
+ tests/gdimageclone/style.c        | 30 ++++++++++++++++++++++++++++++
+ 5 files changed, 35 insertions(+), 9 deletions(-)
+ create mode 100644 tests/gdimageclone/style.c
+
+diff --git a/src/gd.c b/src/gd.c
+index 592a0286..d564d1f9 100644
+--- a/src/gd.c
++++ b/src/gd.c
+@@ -2865,14 +2865,6 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) {
+ 		}
+ 	}
+ 
+-	if (src->styleLength > 0) {
+-		dst->styleLength = src->styleLength;
+-		dst->stylePos    = src->stylePos;
+-		for (i = 0; i < src->styleLength; i++) {
+-			dst->style[i] = src->style[i];
+-		}
+-	}
+-
+ 	dst->interlace   = src->interlace;
+ 
+ 	dst->alphaBlendingFlag = src->alphaBlendingFlag;
+@@ -2907,6 +2899,7 @@ BGD_DECLARE(gdImagePtr) gdImageClone (gdImagePtr src) {
+ 
+ 	if (src->style) {
+ 		gdImageSetStyle(dst, src->style, src->styleLength);
++		dst->stylePos = src->stylePos;
+ 	}
+ 
+ 	for (i = 0; i < gdMaxColors; i++) {
+diff --git a/tests/gdimageclone/style.c b/tests/gdimageclone/style.c
+new file mode 100644
+index 00000000..c2b246ed
+--- /dev/null
++++ b/tests/gdimageclone/style.c
+@@ -0,0 +1,30 @@
++/**
++ * Cloning an image should exactly reproduce all style related data
++ */
++
++
++#include <string.h>
++#include "gd.h"
++#include "gdtest.h"
++
++
++int main()
++{
++    gdImagePtr im, clone;
++    int style[] = {0, 0, 0};
++
++    im = gdImageCreate(8, 8);
++    gdImageSetStyle(im, style, sizeof(style)/sizeof(style[0]));
++
++    clone = gdImageClone(im);
++    gdTestAssert(clone != NULL);
++
++    gdTestAssert(clone->styleLength == im->styleLength);
++    gdTestAssert(clone->stylePos == im->stylePos);
++    gdTestAssert(!memcmp(clone->style, im->style, sizeof(style)/sizeof(style[0])));
++
++    gdImageDestroy(clone);
++    gdImageDestroy(im);
++
++    return gdNumFailures();
++}
diff --git a/gd-2.2.5-potential-double-free.patch b/gd-2.2.5-potential-double-free.patch
new file mode 100644
index 0000000..788a068
--- /dev/null
+++ b/gd-2.2.5-potential-double-free.patch
@@ -0,0 +1,283 @@
+From 4d9d8368d08c3a2be3ea4193b9314fffeddace52 Mon Sep 17 00:00:00 2001
+From: Ondrej Dubaj <odubaj at redhat.com>
+Date: Tue, 4 Jun 2019 13:38:41 +0200
+Subject: [PATCH] Potential double-free in gdImage*Ptr()
+
+Whenever `gdImage*Ptr()` calls `gdImage*Ctx()` and the latter fails, we
+must not call `gdDPExtractData()`; otherwise a double-free would
+happen.  Since `gdImage*Ctx()` are void functions, and we can't change
+that for BC reasons, we're introducing static helpers which are used
+internally.
+
+We're adding a regression test for `gdImageJpegPtr()`, but not for
+`gdImageGifPtr()` and `gdImageWbmpPtr()` since we don't know how to
+trigger failure of the respective `gdImage*Ctx()` calls.
+
+This potential security issue has been reported by Solmaz Salimi (aka.
+Rooney).
+---
+ src/gd_gif_out.c                  | 19 +++++++++++++++----
+ src/gd_jpeg.c                     | 20 ++++++++++++++++----
+ src/gd_wbmp.c                     | 21 ++++++++++++++++++---
+ tests/jpeg/CMakeLists.txt         |  1 +
+ tests/jpeg/Makemodule.am          |  3 ++-
+ tests/jpeg/jpeg_ptr_double_free.c | 31 +++++++++++++++++++++++++++++++
+ 6 files changed, 83 insertions(+), 12 deletions(-)
+ create mode 100644 tests/jpeg/jpeg_ptr_double_free.c
+
+diff --git a/src/gd_gif_out.c b/src/gd_gif_out.c
+index 6fe707d..4a05c09 100755
+--- a/src/gd_gif_out.c
++++ b/src/gd_gif_out.c
+@@ -99,7 +99,7 @@ static void char_init(GifCtx *ctx);
+ static void char_out(int c, GifCtx *ctx);
+ static void flush_char(GifCtx *ctx);
+ 
+-
++static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out);
+ 
+ 
+ /*
+@@ -131,8 +131,11 @@ BGD_DECLARE(void *) gdImageGifPtr(gdImagePtr im, int *size)
+ 	void *rv;
+ 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
+ 	if (out == NULL) return NULL;
+-	gdImageGifCtx(im, out);
+-	rv = gdDPExtractData(out, size);
++	if (!_gdImageGifCtx(im, out)) {
++        rv = gdDPExtractData(out, size);
++    } else {
++        rv = NULL;
++    }
+ 	out->gd_free(out);
+ 	return rv;
+ }
+@@ -220,6 +223,12 @@ BGD_DECLARE(void) gdImageGif(gdImagePtr im, FILE *outFile)
+ 
+ */
+ BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
++{
++    _gdImageGifCtx(im, out);
++}
++
++/* returns 0 on success, 1 on failure */
++static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
+ {
+ 	gdImagePtr pim = 0, tim = im;
+ 	int interlace, BitsPerPixel;
+@@ -231,7 +240,7 @@ BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
+ 		based temporary image. */
+ 		pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
+ 		if(!pim) {
+-			return;
++			return 1;
+ 		}
+ 		tim = pim;
+ 	}
+@@ -247,6 +256,8 @@ BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
+ 		/* Destroy palette based temporary image. */
+ 		gdImageDestroy(	pim);
+ 	}
++
++    return 0;
+ }
+ 
+ 
+diff --git a/src/gd_jpeg.c b/src/gd_jpeg.c
+index 271ef46..bd8fc27 100755
+--- a/src/gd_jpeg.c
++++ b/src/gd_jpeg.c
+@@ -123,6 +123,8 @@ static void fatal_jpeg_error(j_common_ptr cinfo)
+ 	exit(99);
+ }
+ 
++static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality);
++
+ /*
+  * Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality
+  * QUALITY.  If QUALITY is in the range 0-100, increasing values
+@@ -237,8 +239,11 @@ BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality)
+ 	void *rv;
+ 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
+ 	if (out == NULL) return NULL;
+-	gdImageJpegCtx(im, out, quality);
+-	rv = gdDPExtractData(out, size);
++	if (!_gdImageJpegCtx(im, out, quality)) {
++		rv = gdDPExtractData(out, size);
++	} else {
++		rv = NULL;
++	}
+ 	out->gd_free(out);
+ 	return rv;
+ }
+@@ -259,6 +264,12 @@ void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile);
+ 
+ */
+ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
++{
++	_gdImageJpegCtx(im, outfile, quality);
++}
++
++/* returns 0 on success, 1 on failure */
++static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
+ {
+ 	struct jpeg_compress_struct cinfo;
+ 	struct jpeg_error_mgr jerr;
+@@ -293,7 +304,7 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
+ 		if(row) {
+ 			gdFree(row);
+ 		}
+-		return;
++		return 1;
+ 	}
+ 
+ 	cinfo.err->emit_message = jpeg_emit_message;
+@@ -334,7 +345,7 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
+ 	if(row == 0) {
+ 		gd_error("gd-jpeg: error: unable to allocate JPEG row structure: gdCalloc returns NULL\n");
+ 		jpeg_destroy_compress(&cinfo);
+-		return;
++		return 1;
+ 	}
+ 
+ 	rowptr[0] = row;
+@@ -411,6 +422,7 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
+ 	jpeg_finish_compress(&cinfo);
+ 	jpeg_destroy_compress(&cinfo);
+ 	gdFree(row);
++	return 0;
+ }
+ 
+ 
+diff --git a/src/gd_wbmp.c b/src/gd_wbmp.c
+index 0028273..341ff6e 100755
+--- a/src/gd_wbmp.c
++++ b/src/gd_wbmp.c
+@@ -88,6 +88,8 @@ int gd_getin(void *in)
+ 	return (gdGetC((gdIOCtx *)in));
+ }
+ 
++static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out);
++
+ /*
+ 	Function: gdImageWBMPCtx
+ 
+@@ -100,6 +102,12 @@ int gd_getin(void *in)
+ 		out   - the stream where to write
+ */
+ BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
++{
++	_gdImageWBMPCtx(image, fg, out);
++}
++
++/* returns 0 on success, 1 on failure */
++static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
+ {
+ 	int x, y, pos;
+ 	Wbmp *wbmp;
+@@ -107,7 +115,7 @@ BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
+ 	/* create the WBMP */
+ 	if((wbmp = createwbmp(gdImageSX(image), gdImageSY(image), WBMP_WHITE)) == NULL) {
+ 		gd_error("Could not create WBMP\n");
+-		return;
++		return 1;
+ 	}
+ 
+ 	/* fill up the WBMP structure */
+@@ -123,11 +131,15 @@ BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
+ 
+ 	/* write the WBMP to a gd file descriptor */
+ 	if(writewbmp(wbmp, &gd_putout, out)) {
++		freewbmp(wbmp);
+ 		gd_error("Could not save WBMP\n");
++		return 1;
+ 	}
+ 
+ 	/* des submitted this bugfix: gdFree the memory. */
+ 	freewbmp(wbmp);
++
++	return 0;
+ }
+ 
+ /*
+@@ -271,8 +283,11 @@ BGD_DECLARE(void *) gdImageWBMPPtr(gdImagePtr im, int *size, int fg)
+ 	void *rv;
+ 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
+ 	if (out == NULL) return NULL;
+-	gdImageWBMPCtx(im, fg, out);
+-	rv = gdDPExtractData(out, size);
++	if (!_gdImageWBMPCtx(im, fg, out)) {
++		rv = gdDPExtractData(out, size);
++	} else {
++		rv = NULL;
++	}
+ 	out->gd_free(out);
+ 	return rv;
+ }
+diff --git a/tests/jpeg/CMakeLists.txt b/tests/jpeg/CMakeLists.txt
+index 19964b0..a8d8162 100755
+--- a/tests/jpeg/CMakeLists.txt
++++ b/tests/jpeg/CMakeLists.txt
+@@ -2,6 +2,7 @@ IF(JPEG_FOUND)
+ LIST(APPEND TESTS_FILES
+ 	jpeg_empty_file
+ 	jpeg_im2im
++	jpeg_ptr_double_free
+ 	jpeg_null
+ )
+ 
+diff --git a/tests/jpeg/Makemodule.am b/tests/jpeg/Makemodule.am
+index 7e5d317..b89e169 100755
+--- a/tests/jpeg/Makemodule.am
++++ b/tests/jpeg/Makemodule.am
+@@ -2,7 +2,8 @@ if HAVE_LIBJPEG
+ libgd_test_programs += \
+ 	jpeg/jpeg_empty_file \
+ 	jpeg/jpeg_im2im \
+-	jpeg/jpeg_null
++	jpeg/jpeg_null \
++	jpeg/jpeg_ptr_double_free
+ 
+ if HAVE_LIBPNG
+ libgd_test_programs += \
+diff --git a/tests/jpeg/jpeg_ptr_double_free.c b/tests/jpeg/jpeg_ptr_double_free.c
+new file mode 100644
+index 0000000..c80aeb6
+--- /dev/null
++++ b/tests/jpeg/jpeg_ptr_double_free.c
+@@ -0,0 +1,31 @@
++/**
++ * Test that failure to convert to JPEG returns NULL
++ *
++ * We are creating an image, set its width to zero, and pass this image to
++ * `gdImageJpegPtr()` which is supposed to fail, and as such should return NULL.
++ *
++ * See also <https://github.com/libgd/libgd/issues/381>
++ */
++
++
++#include "gd.h"
++#include "gdtest.h"
++
++
++int main()
++{
++    gdImagePtr src, dst;
++    int size;
++
++    src = gdImageCreateTrueColor(1, 10);
++    gdTestAssert(src != NULL);
++
++    src->sx = 0; /* this hack forces gdImageJpegPtr() to fail */
++
++    dst = gdImageJpegPtr(src, &size, 0);
++    gdTestAssert(dst == NULL);
++
++    gdImageDestroy(src);
++
++    return gdNumFailures();
++}
+\ No newline at end of file
+-- 
+2.17.1
+
diff --git a/gd-2.2.5-upstream.patch b/gd-2.2.5-upstream.patch
new file mode 100644
index 0000000..0bc1bcb
--- /dev/null
+++ b/gd-2.2.5-upstream.patch
@@ -0,0 +1,62 @@
+From a11f47475e6443b7f32d21f2271f28f417e2ac04 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69 at gmx.de>
+Date: Wed, 29 Nov 2017 19:37:38 +0100
+Subject: [PATCH] Fix #420: Potential infinite loop in gdImageCreateFromGifCtx
+
+Due to a signedness confusion in `GetCode_` a corrupt GIF file can
+trigger an infinite loop.  Furthermore we make sure that a GIF without
+any palette entries is treated as invalid *after* open palette entries
+have been removed.
+
+CVE-2018-5711
+
+See also https://bugs.php.net/bug.php?id=75571.
+---
+ src/gd_gif_in.c             |  12 ++++++------
+ tests/gif/.gitignore        |   1 +
+ tests/gif/CMakeLists.txt    |   1 +
+ tests/gif/Makemodule.am     |   2 ++
+ tests/gif/php_bug_75571.c   |  28 ++++++++++++++++++++++++++++
+ tests/gif/php_bug_75571.gif | Bin 0 -> 1731 bytes
+ 6 files changed, 38 insertions(+), 6 deletions(-)
+ create mode 100644 tests/gif/php_bug_75571.c
+ create mode 100644 tests/gif/php_bug_75571.gif
+
+diff --git a/src/gd_gif_in.c b/src/gd_gif_in.c
+index daf26e79..0a8bd717 100644
+--- a/src/gd_gif_in.c
++++ b/src/gd_gif_in.c
+@@ -335,11 +335,6 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
+ 		return 0;
+ 	}
+ 
+-	if(!im->colorsTotal) {
+-		gdImageDestroy(im);
+-		return 0;
+-	}
+-
+ 	/* Check for open colors at the end, so
+ 	 * we can reduce colorsTotal and ultimately
+ 	 * BitsPerPixel */
+@@ -351,6 +346,11 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
+ 		}
+ 	}
+ 
++	if(!im->colorsTotal) {
++		gdImageDestroy(im);
++		return 0;
++	}
++
+ 	return im;
+ }
+ 
+@@ -447,7 +447,7 @@ static int
+ GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
+ {
+ 	int i, j, ret;
+-	unsigned char count;
++	int count;
+ 
+ 	if(flag) {
+ 		scd->curbit = 0;
+ 
================================================================

---- gitweb:

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



More information about the pld-cvs-commit mailing list