diff -Nru libgd2-2.2.5/debian/changelog libgd2-2.2.5/debian/changelog --- libgd2-2.2.5/debian/changelog 2017-10-22 09:14:32.000000000 +0000 +++ libgd2-2.2.5/debian/changelog 2019-02-27 19:31:55.000000000 +0000 @@ -1,3 +1,31 @@ +libgd2 (2.2.5-4ubuntu0.3) bionic-security; urgency=medium + + * SECURITY UPDATE: buffer overflow in gdImageColorMatch + - debian/patches/CVE-2019-6977.patch: use gdMaxColors in + src/gd_color_match.c. + - CVE-2019-6977 + * SECURITY UPDATE: double-free in gdImage*Ptr() functions + - debian/patches/CVE-2019-6978.patch: properly handle failure in + src/gd_gif_out.c, src/gd_jpeg.c, src/gd_wbmp.c, add test to + tests/jpeg/CMakeLists.txt, tests/jpeg/Makemodule.am, + tests/jpeg/jpeg_ptr_double_free.c. + - CVE-2019-6978 + + -- Marc Deslauriers Wed, 27 Feb 2019 14:31:55 -0500 + +libgd2 (2.2.5-4ubuntu0.2) bionic-security; urgency=medium + + * SECURITY UPDATE: Double free + - debian/patches/CVE-2018-1000222.patch: fix in + src/gd_bmp.c. + - CVE-2018-1000222 + * SECURITY UPDATE: Infinite loop + - debian/patches/CVE-2018-5711.patch: fix in + src/gd_gif_in.c. + - CVE-2018-5711 + + -- Leonidas S. Barbosa Thu, 23 Aug 2018 12:15:43 -0300 + libgd2 (2.2.5-4) unstable; urgency=medium [ Jiří Paleček ] diff -Nru libgd2-2.2.5/debian/control libgd2-2.2.5/debian/control --- libgd2-2.2.5/debian/control 2017-10-22 09:14:32.000000000 +0000 +++ libgd2-2.2.5/debian/control 2018-08-23 15:15:43.000000000 +0000 @@ -1,7 +1,8 @@ Source: libgd2 Section: graphics Priority: optional -Maintainer: GD team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: GD team Uploaders: Ondřej Surý Build-Depends: autotools-dev, debhelper (>= 9), diff -Nru libgd2-2.2.5/debian/patches/CVE-2018-1000222.patch libgd2-2.2.5/debian/patches/CVE-2018-1000222.patch --- libgd2-2.2.5/debian/patches/CVE-2018-1000222.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgd2-2.2.5/debian/patches/CVE-2018-1000222.patch 2018-08-23 15:15:36.000000000 +0000 @@ -0,0 +1,73 @@ +From ac16bdf2d41724b5a65255d4c28fb0ec46bc42f5 Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Sat, 14 Jul 2018 13:54:08 -0400 +Subject: [PATCH] bmp: check return value in gdImageBmpPtr + +Closes #447. +--- + src/gd_bmp.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/src/gd_bmp.c b/src/gd_bmp.c +index bde0b9d3..78f40d9a 100644 +--- a/src/gd_bmp.c ++++ b/src/gd_bmp.c +@@ -47,6 +47,8 @@ static int bmp_read_4bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp + static int bmp_read_8bit(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info, bmp_hdr_t *header); + static int bmp_read_rle(gdImagePtr im, gdIOCtxPtr infile, bmp_info_t *info); + ++static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression); ++ + #define BMP_DEBUG(s) + + static int gdBMPPutWord(gdIOCtx *out, int w) +@@ -87,8 +89,10 @@ BGD_DECLARE(void *) gdImageBmpPtr(gdImagePtr im, int *size, int compression) + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + if (out == NULL) return NULL; +- gdImageBmpCtx(im, out, compression); +- rv = gdDPExtractData(out, size); ++ if (!_gdImageBmpCtx(im, out, compression)) ++ rv = gdDPExtractData(out, size); ++ else ++ rv = NULL; + out->gd_free(out); + return rv; + } +@@ -141,6 +145,11 @@ BGD_DECLARE(void) gdImageBmp(gdImagePtr im, FILE *outFile, int compression) + compression - whether to apply RLE or not. + */ + BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) ++{ ++ _gdImageBmpCtx(im, out, compression); ++} ++ ++static int _gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) + { + int bitmap_size = 0, info_size, total_size, padding; + int i, row, xpos, pixel; +@@ -148,6 +157,7 @@ BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) + unsigned char *uncompressed_row = NULL, *uncompressed_row_start = NULL; + FILE *tmpfile_for_compression = NULL; + gdIOCtxPtr out_original = NULL; ++ int ret = 1; + + /* No compression if its true colour or we don't support seek */ + if (im->trueColor) { +@@ -325,6 +335,7 @@ BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) + out_original = NULL; + } + ++ ret = 0; + cleanup: + if (tmpfile_for_compression) { + #ifdef _WIN32 +@@ -338,7 +349,7 @@ BGD_DECLARE(void) gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression) + if (out_original) { + out_original->gd_free(out_original); + } +- return; ++ return ret; + } + + static int compress_row(unsigned char *row, int length) diff -Nru libgd2-2.2.5/debian/patches/CVE-2018-5711.patch libgd2-2.2.5/debian/patches/CVE-2018-5711.patch --- libgd2-2.2.5/debian/patches/CVE-2018-5711.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgd2-2.2.5/debian/patches/CVE-2018-5711.patch 2018-08-23 15:15:43.000000000 +0000 @@ -0,0 +1,49 @@ +From 3b50e238b2d7ec2a3d46aa428694e02479477b7a Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 29 Nov 2017 18:52:33 +0100 +Subject: [PATCH 1/1] Fixed bug #75571: 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. + +(cherry picked from commit 8d6e9588671136837533fe3785657c31c5b52767) +Index: libgd2-2.2.5/src/gd_gif_in.c +=================================================================== +--- libgd2-2.2.5.orig/src/gd_gif_in.c ++++ libgd2-2.2.5/src/gd_gif_in.c +@@ -334,12 +334,6 @@ terminated: + if(!im) { + 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 +345,10 @@ terminated: + } + } + ++ if(!im->colorsTotal) { ++ gdImageDestroy(im); ++ return 0; ++ } + return im; + } + +@@ -447,7 +445,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; diff -Nru libgd2-2.2.5/debian/patches/CVE-2019-6977.patch libgd2-2.2.5/debian/patches/CVE-2019-6977.patch --- libgd2-2.2.5/debian/patches/CVE-2019-6977.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgd2-2.2.5/debian/patches/CVE-2019-6977.patch 2019-02-27 19:31:47.000000000 +0000 @@ -0,0 +1,35 @@ +Ported from php patch: + +From a15af81b5f0058e020eda0f109f51a3c863f5212 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Sun, 30 Dec 2018 13:59:26 +0100 +Subject: [PATCH] Fix #77270: imagecolormatch Out Of Bounds Write on Heap + +At least some of the image reading functions may return images which +use color indexes greater than or equal to im->colorsTotal. We cater +to this by always using a buffer size which is sufficient for +`gdMaxColors` in `gdImageColorMatch()`. + +(cherry picked from commit 7a12dad4dd6c370835b13afae214b240082c7538) +--- + NEWS | 1 + + ext/gd/libgd/gd_color_match.c | 4 ++-- + ext/gd/tests/bug77270.phpt | 18 ++++++++++++++++++ + 3 files changed, 21 insertions(+), 2 deletions(-) + create mode 100644 ext/gd/tests/bug77270.phpt + +Index: libgd2-2.2.5/src/gd_color_match.c +=================================================================== +--- libgd2-2.2.5.orig/src/gd_color_match.c 2019-02-27 14:23:57.353567356 -0500 ++++ libgd2-2.2.5/src/gd_color_match.c 2019-02-27 14:24:44.957697903 -0500 +@@ -31,8 +31,8 @@ BGD_DECLARE(int) gdImageColorMatch (gdIm + 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; ysy; y++ ) { diff -Nru libgd2-2.2.5/debian/patches/CVE-2019-6978.patch libgd2-2.2.5/debian/patches/CVE-2019-6978.patch --- libgd2-2.2.5/debian/patches/CVE-2019-6978.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgd2-2.2.5/debian/patches/CVE-2019-6978.patch 2019-02-27 19:31:50.000000000 +0000 @@ -0,0 +1,279 @@ +Backport of: + +From 553702980ae89c83f2d6e254d62cf82e204956d0 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Thu, 17 Jan 2019 11:54:55 +0100 +Subject: [PATCH] Fix #492: 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 | 18 +++++++++++++++--- + src/gd_jpeg.c | 20 ++++++++++++++++---- + src/gd_wbmp.c | 21 ++++++++++++++++++--- + tests/jpeg/.gitignore | 1 + + tests/jpeg/CMakeLists.txt | 1 + + tests/jpeg/Makemodule.am | 3 ++- + tests/jpeg/jpeg_ptr_double_free.c | 31 +++++++++++++++++++++++++++++++ + 7 files changed, 84 insertions(+), 11 deletions(-) + create mode 100644 tests/jpeg/jpeg_ptr_double_free.c + +Index: libgd2-2.2.5/src/gd_gif_out.c +=================================================================== +--- libgd2-2.2.5.orig/src/gd_gif_out.c 2019-02-27 14:26:01.517908081 -0500 ++++ libgd2-2.2.5/src/gd_gif_out.c 2019-02-27 14:26:01.517908081 -0500 +@@ -99,6 +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 +132,11 @@ BGD_DECLARE(void *) gdImageGifPtr(gdImag + 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; + } +@@ -221,6 +225,12 @@ BGD_DECLARE(void) gdImageGif(gdImagePtr + */ + 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; + interlace = im->interlace; +@@ -231,7 +241,7 @@ BGD_DECLARE(void) gdImageGifCtx(gdImageP + based temporary image. */ + pim = gdImageCreatePaletteFromTrueColor(im, 1, 256); + if(!pim) { +- return; ++ return 1; + } + tim = pim; + } +@@ -247,6 +257,8 @@ BGD_DECLARE(void) gdImageGifCtx(gdImageP + /* Destroy palette based temporary image. */ + gdImageDestroy( pim); + } ++ ++ return 0; + } + + +Index: libgd2-2.2.5/src/gd_jpeg.c +=================================================================== +--- libgd2-2.2.5.orig/src/gd_jpeg.c 2019-02-27 14:26:01.517908081 -0500 ++++ libgd2-2.2.5/src/gd_jpeg.c 2019-02-27 14:26:01.517908081 -0500 +@@ -123,6 +123,8 @@ static void fatal_jpeg_error(j_common_pt + 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(gdIma + 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; + } +@@ -260,6 +265,12 @@ void jpeg_gdIOCtx_dest(j_compress_ptr ci + */ + 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; + int i, j, jidx; +@@ -293,7 +304,7 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImage + if(row) { + gdFree(row); + } +- return; ++ return 1; + } + + cinfo.err->emit_message = jpeg_emit_message; +@@ -334,7 +345,7 @@ BGD_DECLARE(void) gdImageJpegCtx(gdImage + 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(gdImage + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + gdFree(row); ++ return 0; + } + + +Index: libgd2-2.2.5/src/gd_wbmp.c +=================================================================== +--- libgd2-2.2.5.orig/src/gd_wbmp.c 2019-02-27 14:26:01.517908081 -0500 ++++ libgd2-2.2.5/src/gd_wbmp.c 2019-02-27 14:26:01.517908081 -0500 +@@ -88,6 +88,8 @@ int gd_getin(void *in) + return (gdGetC((gdIOCtx *)in)); + } + ++static int _gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out); ++ + /* + Function: gdImageWBMPCtx + +@@ -101,13 +103,19 @@ int gd_getin(void *in) + */ + 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; + + /* 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(gdImage + + /* 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(gdIma + 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; + } +Index: libgd2-2.2.5/tests/jpeg/CMakeLists.txt +=================================================================== +--- libgd2-2.2.5.orig/tests/jpeg/CMakeLists.txt 2019-02-27 14:26:01.517908081 -0500 ++++ libgd2-2.2.5/tests/jpeg/CMakeLists.txt 2019-02-27 14:26:01.517908081 -0500 +@@ -2,6 +2,7 @@ IF(JPEG_FOUND) + LIST(APPEND TESTS_FILES + jpeg_empty_file + jpeg_im2im ++ jpeg_ptr_double_free + jpeg_null + ) + +Index: libgd2-2.2.5/tests/jpeg/Makemodule.am +=================================================================== +--- libgd2-2.2.5.orig/tests/jpeg/Makemodule.am 2019-02-27 14:26:01.517908081 -0500 ++++ libgd2-2.2.5/tests/jpeg/Makemodule.am 2019-02-27 14:26:01.517908081 -0500 +@@ -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 += \ +Index: libgd2-2.2.5/tests/jpeg/jpeg_ptr_double_free.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ libgd2-2.2.5/tests/jpeg/jpeg_ptr_double_free.c 2019-02-27 14:26:01.517908081 -0500 +@@ -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 ++ */ ++ ++ ++#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(); ++} diff -Nru libgd2-2.2.5/debian/patches/series libgd2-2.2.5/debian/patches/series --- libgd2-2.2.5/debian/patches/series 2017-10-22 09:14:32.000000000 +0000 +++ libgd2-2.2.5/debian/patches/series 2019-02-27 19:31:50.000000000 +0000 @@ -5,3 +5,7 @@ 0005-Disable-failing-test-that-breaks-some-builds.patch 0006-Disable-gdimagerotate-bug00067-because-it-FTBFS-on-i.patch tests-make-a-little-change-for-autopkgtest.patch +CVE-2018-1000222.patch +CVE-2018-5711.patch +CVE-2019-6977.patch +CVE-2019-6978.patch