From 7eea91dac65525fa6426e51b56327c5f885d15f5b2a555993f9330321f2cc163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Lie?= Date: Thu, 1 Sep 2016 09:33:46 +0000 Subject: [PATCH] Accepting request 424115 from home:zhangxiaofei:branches:GNOME:Factory - Add fixes for some crashes, taken from upstream git (bsc#988745 bsc#991450 CVE-2016-6352): gdk-pixbuf-bgo768688-bmp-overflow.patch gdk-pixbuf-bgo768484-ico-set-errors.patch gdk-pixbuf-bgo769738-bmp-overflow.patch gdk-pixbuf-bgo769170-ico-headers.patch OBS-URL: https://build.opensuse.org/request/show/424115 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/gdk-pixbuf?expand=0&rev=111 --- gdk-pixbuf-bgo768484-ico-set-errors.patch | 52 ++++++ gdk-pixbuf-bgo768688-bmp-overflow.patch | 56 ++++++ gdk-pixbuf-bgo769170-ico-headers.patch | 213 ++++++++++++++++++++++ gdk-pixbuf-bgo769738-bmp-overflow.patch | 57 ++++++ gdk-pixbuf.changes | 10 + gdk-pixbuf.spec | 12 ++ 6 files changed, 400 insertions(+) create mode 100644 gdk-pixbuf-bgo768484-ico-set-errors.patch create mode 100644 gdk-pixbuf-bgo768688-bmp-overflow.patch create mode 100644 gdk-pixbuf-bgo769170-ico-headers.patch create mode 100644 gdk-pixbuf-bgo769738-bmp-overflow.patch diff --git a/gdk-pixbuf-bgo768484-ico-set-errors.patch b/gdk-pixbuf-bgo768484-ico-set-errors.patch new file mode 100644 index 0000000..2eca03a --- /dev/null +++ b/gdk-pixbuf-bgo768484-ico-set-errors.patch @@ -0,0 +1,52 @@ +From 0cff83e985fba5350695c00ed1ac30fc31ec5960 Mon Sep 17 00:00:00 2001 +From: Hanno Boeck +Date: Wed, 6 Jul 2016 13:05:00 +0000 +Subject: [PATCH] ico: Always set errors + +When the ico header turn out to be bad, always set an +error when we fail. Otherwise, applications will get +confused. + +This commit also adds an example image with a bad ico header. + +https://bugzilla.gnome.org/show_bug.cgi?id=768484 +--- + gdk-pixbuf/io-ico.c | 14 ++++++++++++-- + tests/test-images/randomly-modified/bad-header.ico | Bin 0 -> 6 bytes + 2 files changed, 12 insertions(+), 2 deletions(-) + create mode 100644 tests/test-images/randomly-modified/bad-header.ico + +diff --git a/gdk-pixbuf/io-ico.c b/gdk-pixbuf/io-ico.c +index 86714af..82d3e4e 100644 +--- a/gdk-pixbuf/io-ico.c ++++ b/gdk-pixbuf/io-ico.c +@@ -258,8 +258,13 @@ static void DecodeHeader(guchar *Data, gint Bytes, + State->HeaderBuf = tmp; + State->BytesInHeaderBuf = State->HeaderSize; + } +- if (Bytes < State->HeaderSize) ++ if (Bytes < State->HeaderSize) { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Not enough bytes for header")); + return; ++ } + + /* Now iterate through the ICONDIRENTRY structures, and sort them by + * which one we think is "best" (essentially the largest) */ +@@ -399,8 +404,13 @@ static void DecodeHeader(guchar *Data, gint Bytes, + State->HeaderBuf = tmp; + State->BytesInHeaderBuf = State->HeaderSize; + } +- if (Bytes < State->HeaderSize) ++ if (Bytes < State->HeaderSize) { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Not enough bytes for header")); + return; ++ } + + /* Negative heights mean top-down pixel-order */ + if (State->Header.height < 0) { diff --git a/gdk-pixbuf-bgo768688-bmp-overflow.patch b/gdk-pixbuf-bgo768688-bmp-overflow.patch new file mode 100644 index 0000000..fabb833 --- /dev/null +++ b/gdk-pixbuf-bgo768688-bmp-overflow.patch @@ -0,0 +1,56 @@ +From b69009f2a2de151103ed87e9594615ba0fe72daf Mon Sep 17 00:00:00 2001 +From: Tobias Mueller +Date: Mon, 11 Jul 2016 17:01:00 +0000 +Subject: [PATCH] bmp: Fix an integer overflow in DecodeColormap + +Return an error if n_colors * samples overflows. + +This commit also adds a reproducer that will cause +pixbuf-randomly-modified to crash in the absence of +the patch. + +https://bugzilla.gnome.org/show_bug.cgi?id=768688 +--- + gdk-pixbuf/io-bmp.c | 15 ++++++++++++--- + tests/test-images/randomly-modified/decodecolormap.bmp | Bin 0 -> 118 bytes + 2 files changed, 12 insertions(+), 3 deletions(-) + create mode 100644 tests/test-images/randomly-modified/decodecolormap.bmp + +diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c +index f412997..748ebae 100644 +--- a/gdk-pixbuf/io-bmp.c ++++ b/gdk-pixbuf/io-bmp.c +@@ -518,12 +518,16 @@ static gboolean DecodeColormap (guchar *buff, + { + gint i; + gint samples; ++ guint newbuffersize; + + g_assert (State->read_state == READ_STATE_PALETTE); + + samples = (State->Header.size == 12 ? 3 : 4); +- if (State->BufferSize < State->Header.n_colors * samples) { +- State->BufferSize = State->Header.n_colors * samples; ++ newbuffersize = State->Header.n_colors * samples; ++ if (newbuffersize / samples != State->Header.n_colors) /* Integer overflow check */ ++ return FALSE; ++ if (State->BufferSize < newbuffersize) { ++ State->BufferSize = newbuffersize; + if (!grow_buffer (State, error)) + return FALSE; + return TRUE; +@@ -1247,8 +1251,13 @@ gdk_pixbuf__bmp_image_load_increment(gpointer data, + break; + + case READ_STATE_PALETTE: +- if (!DecodeColormap (context->buff, context, error)) ++ if (!DecodeColormap (context->buff, context, error)) { ++ g_set_error (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Error while decoding colormap")); + return FALSE; ++ } + break; + + case READ_STATE_BITMASKS: diff --git a/gdk-pixbuf-bgo769170-ico-headers.patch b/gdk-pixbuf-bgo769170-ico-headers.patch new file mode 100644 index 0000000..36f4d14 --- /dev/null +++ b/gdk-pixbuf-bgo769170-ico-headers.patch @@ -0,0 +1,213 @@ +From 88af50a864195da1a4f7bda5f02539704fbda599 Mon Sep 17 00:00:00 2001 +From: Matthias Clasen +Date: Wed, 3 Aug 2016 12:40:48 -0400 +Subject: [PATCH] ico: Be more careful when parsing headers + +There is some redundancy between the ico directory and the +bitmap image header. If the two disagree on the icon dimensions, +just toss the image, instead of risking crashes or OOM later. Also +add some more debug spew that helped in tracking this down, and +make error messages more unique. + +The commit also includes a test image that has an example of +this discrepancy and triggers the early exit. + +https://bugzilla.gnome.org/show_bug.cgi?id=769170 + +Backported by Mike Gorse +--- +diff -urp gdk-pixbuf-2.34.0.orig/gdk-pixbuf/io-ico.c gdk-pixbuf-2.34.0/gdk-pixbuf/io-ico.c +--- gdk-pixbuf-2.34.0.orig/gdk-pixbuf/io-ico.c 2016-08-30 13:57:44.715146613 -0500 ++++ gdk-pixbuf-2.34.0/gdk-pixbuf/io-ico.c 2016-08-30 15:17:40.887044723 -0500 +@@ -23,6 +23,8 @@ + */ + + #undef DUMPBIH ++#define DEBUG(s) ++ + /* + + Icons are just like BMP's, except for the header. +@@ -75,14 +77,14 @@ struct BitmapInfoHeader { + }; + + #ifdef DUMPBIH +-/* ++/* + + DumpBIH printf's the values in a BitmapInfoHeader to the screen, for + debugging purposes. + + */ + static void DumpBIH(unsigned char *BIH) +-{ ++{ + printf("biSize = %i \n", + (int)(BIH[3] << 24) + (BIH[2] << 16) + (BIH[1] << 8) + (BIH[0])); + printf("biWidth = %i \n", +@@ -125,6 +127,8 @@ struct headerpair { + /* Score the various parts of the icon */ + struct ico_direntry_data { + gint ImageScore; ++ gint width; ++ gint height; + gint DIBoffset; + gint x_hot; + gint y_hot; +@@ -241,11 +245,12 @@ static void DecodeHeader(guchar *Data, g + return; + } + +- + IconCount = (Data[5] << 8) + (Data[4]); + + State->HeaderSize = 6 + IconCount*16; + ++ DEBUG(g_print ("Image type: %d (%s)\nImage count: %d\n", imgtype, imgtype == 2 ? "cursor" : "icon", IconCount)); ++ + if (State->HeaderSize>State->BytesInHeaderBuf) { + guchar *tmp=g_try_realloc(State->HeaderBuf,State->HeaderSize); + if (!tmp) { +@@ -259,10 +264,6 @@ static void DecodeHeader(guchar *Data, g + State->BytesInHeaderBuf = State->HeaderSize; + } + if (Bytes < State->HeaderSize) { +- g_set_error_literal (error, +- GDK_PIXBUF_ERROR, +- GDK_PIXBUF_ERROR_CORRUPT_IMAGE, +- _("Not enough bytes for header")); + return; + } + +@@ -272,17 +273,37 @@ static void DecodeHeader(guchar *Data, g + State->entries = 0; + Ptr = Data + 6; + for (I=0;IImageScore = (Ptr[11] << 24) + (Ptr[10] << 16) + (Ptr[9] << 8) + (Ptr[8]); +- if (entry->ImageScore == 0) +- entry->ImageScore = 256; +- entry->x_hot = (Ptr[5] << 8) + Ptr[4]; +- entry->y_hot = (Ptr[7] << 8) + Ptr[6]; +- entry->DIBoffset = (Ptr[15]<<24)+(Ptr[14]<<16)+ +- (Ptr[13]<<8) + (Ptr[12]); ++ entry->ImageScore = data_size; ++ ++ entry->width = width ? width : 256; ++ entry->height = height ? height : 256; ++ entry->x_hot = x_hot; ++ entry->y_hot = y_hot; ++ entry->DIBoffset = data_offset; + State->entries = g_list_insert_sorted (State->entries, entry, compare_direntry_scores); + Ptr += 16; +- } ++ } + + /* Now go through and find one we can parse */ + entry = NULL; +@@ -351,9 +372,9 @@ static void DecodeHeader(guchar *Data, g + + #ifdef DUMPBIH + DumpBIH(BIH); +-#endif ++#endif + /* Add the palette to the headersize */ +- ++ + State->Header.width = + (int)(BIH[7] << 24) + (BIH[6] << 16) + (BIH[5] << 8) + (BIH[4]); + if (State->Header.width == 0) +@@ -364,12 +385,28 @@ static void DecodeHeader(guchar *Data, g + /* /2 because the BIH height includes the transparency mask */ + if (State->Header.height == 0) + State->Header.height = 256; ++ ++ /* Negative heights mean top-down pixel-order */ ++ if (State->Header.height < 0) { ++ State->Header.height = -State->Header.height; ++ State->Header.Negative = 1; ++ } ++ if (State->Header.width < 0) { ++ State->Header.width = -State->Header.width; ++ } ++ ++ if (State->Header.width != entry->width || ++ State->Header.height != entry->height) { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("Invalid header in icon")); ++ return; ++ } ++ + State->Header.depth = (BIH[15] << 8) + (BIH[14]); ++ State->Type = State->Header.depth; + +- State->Type = State->Header.depth; +- if (State->Lines>=State->Header.height) +- State->Type = 1; /* The transparency mask is 1 bpp */ +- + /* Determine the palette size. If the header indicates 0, it + is actually the maximum for the bpp. You have to love the + guys who made the spec. */ +@@ -405,24 +442,9 @@ static void DecodeHeader(guchar *Data, g + State->BytesInHeaderBuf = State->HeaderSize; + } + if (Bytes < State->HeaderSize) { +- g_set_error_literal (error, +- GDK_PIXBUF_ERROR, +- GDK_PIXBUF_ERROR_CORRUPT_IMAGE, +- _("Not enough bytes for header")); + return; + } + +- /* Negative heights mean top-down pixel-order */ +- if (State->Header.height < 0) { +- State->Header.height = -State->Header.height; +- State->Header.Negative = 1; +- } +- if (State->Header.width < 0) { +- State->Header.width = -State->Header.width; +- } +- g_assert (State->Header.width > 0); +- g_assert (State->Header.height > 0); +- + if (State->Type == 32) + State->LineWidth = State->Header.width * 4; + else if (State->Type == 24) +@@ -465,7 +487,6 @@ static void DecodeHeader(guchar *Data, g + + + if (State->pixbuf == NULL) { +-#if 1 + if (State->size_func) { + gint width = State->Header.width; + gint height = State->Header.height; +@@ -476,7 +497,6 @@ static void DecodeHeader(guchar *Data, g + return; + } + } +-#endif + + State->pixbuf = + gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, diff --git a/gdk-pixbuf-bgo769738-bmp-overflow.patch b/gdk-pixbuf-bgo769738-bmp-overflow.patch new file mode 100644 index 0000000..fe40970 --- /dev/null +++ b/gdk-pixbuf-bgo769738-bmp-overflow.patch @@ -0,0 +1,57 @@ +From 779429ce34e439c01d257444fe9d6739e72a2024 Mon Sep 17 00:00:00 2001 +From: Tobias Mueller +Date: Tue, 12 Jul 2016 15:20:00 +0000 +Subject: [PATCH] bmp: Detect integer overflow of the line width + +Instead of risking crashes or OOM, return an error if +we detect integer overflow. + +The commit also includes a test image that triggers +this overflow when used with pixbuf-read. + +https://bugzilla.gnome.org/show_bug.cgi?id=768738 +--- + gdk-pixbuf/io-bmp.c | 21 ++++++++++++--------- + .../randomly-modified/bmp-line-overflow.bmp | Bin 0 -> 74 bytes + 2 files changed, 12 insertions(+), 9 deletions(-) + create mode 100644 tests/test-images/randomly-modified/bmp-line-overflow.bmp + +diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c +index 748ebae..08e3c76 100644 +--- a/gdk-pixbuf/io-bmp.c ++++ b/gdk-pixbuf/io-bmp.c +@@ -254,6 +254,7 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, + GError **error) + { + gint clrUsed; ++ guint bytesPerPixel; + + /* First check for the two first bytes content. A sane + BMP file must start with bytes 0x42 0x4D. */ +@@ -380,15 +381,17 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, + return FALSE; + } + +- if (State->Type == 32) +- State->LineWidth = State->Header.width * 4; +- else if (State->Type == 24) +- State->LineWidth = State->Header.width * 3; +- else if (State->Type == 16) +- State->LineWidth = State->Header.width * 2; +- else if (State->Type == 8) +- State->LineWidth = State->Header.width * 1; +- else if (State->Type == 4) ++ if ((State->Type >= 8) && (State->Type <= 32) && (State->Type % 8 == 0)) { ++ bytesPerPixel = State->Type / 8; ++ State->LineWidth = State->Header.width * bytesPerPixel; ++ if (State->Header.width != State->LineWidth / bytesPerPixel) { ++ g_set_error_literal (error, ++ GDK_PIXBUF_ERROR, ++ GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ++ _("BMP image width too large")); ++ return FALSE; ++ } ++ } else if (State->Type == 4) + State->LineWidth = (State->Header.width + 1) / 2; + else if (State->Type == 1) { + State->LineWidth = State->Header.width / 8; diff --git a/gdk-pixbuf.changes b/gdk-pixbuf.changes index d306cc9..52cdef9 100644 --- a/gdk-pixbuf.changes +++ b/gdk-pixbuf.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Tue Aug 30 18:39:06 UTC 2016 - mgorse@suse.com + +- Add fixes for some crashes, taken from upstream git (bsc#988745 + bsc#991450 CVE-2016-6352): + gdk-pixbuf-bgo768688-bmp-overflow.patch + gdk-pixbuf-bgo768484-ico-set-errors.patch + gdk-pixbuf-bgo769738-bmp-overflow.patch + gdk-pixbuf-bgo769170-ico-headers.patch + ------------------------------------------------------------------- Wed Apr 13 10:35:15 UTC 2016 - idonmez@suse.com diff --git a/gdk-pixbuf.spec b/gdk-pixbuf.spec index 6815a1d..4112fea 100644 --- a/gdk-pixbuf.spec +++ b/gdk-pixbuf.spec @@ -30,6 +30,14 @@ Source: http://download.gnome.org/sources/gdk-pixbuf/2.34/%{name}-%{vers Source1: macros.gdk-pixbuf Source2: README.SUSE Source99: baselibs.conf +# PATCH-FIX-UPSTREAM gdk-pixbuf-bgo768688-bmp-overflow.patch bgo#768688 mgorse@suse.com -- fix a bmp overflow. +Patch0: gdk-pixbuf-bgo768688-bmp-overflow.patch +# PATCh-FIX-UPSTREAM gdk-pixbuf-bgo768484-ico-set-errors.patch bgo#768484 mgorse@suse.com -- ico: always set errors. +Patch1: gdk-pixbuf-bgo768484-ico-set-errors.patch +# PATCH-FIX-UPSTREAM gdk-pixbuf-bgo769738-bmp-overflow.patch bsc#988745 bgo#769738 mgorse@suse.com -- fix another bmp overflow. +Patch2: gdk-pixbuf-bgo769738-bmp-overflow.patch +# PATCh-FIX-UPSTREAM gdk-pixbuf-bgo769170-ico-headers.patch bsc#991450 bgo#769170 CVE-2016-6352 mgorse@suse.com -- be more careful when parsing ico headers. +Patch3: gdk-pixbuf-bgo769170-ico-headers.patch BuildRequires: libjasper-devel BuildRequires: libjpeg-devel BuildRequires: libtiff-devel @@ -98,6 +106,10 @@ This package contains development files for gdk-pixbuf. %prep %setup -q translation-update-upstream +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %if "%_lib" == "lib64" cp -a %{S:2} . %endif