Hello community, here is the log from the commit of package gdk-pixbuf for openSUSE:Factory checked in at 2016-09-05 21:15:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gdk-pixbuf (Old) and /work/SRC/openSUSE:Factory/.gdk-pixbuf.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gdk-pixbuf" Changes: -------- --- /work/SRC/openSUSE:Factory/gdk-pixbuf/gdk-pixbuf.changes 2016-08-17 12:01:11.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.gdk-pixbuf.new/gdk-pixbuf.changes 2016-09-05 21:15:17.000000000 +0200 @@ -1,0 +2,10 @@ +Tue Aug 30 18:39:06 UTC 2016 - [email protected] + +- 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 + +------------------------------------------------------------------- New: ---- gdk-pixbuf-bgo768484-ico-set-errors.patch gdk-pixbuf-bgo768688-bmp-overflow.patch gdk-pixbuf-bgo769170-ico-headers.patch gdk-pixbuf-bgo769738-bmp-overflow.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gdk-pixbuf.spec ++++++ --- /var/tmp/diff_new_pack.4GbxHq/_old 2016-09-05 21:15:18.000000000 +0200 +++ /var/tmp/diff_new_pack.4GbxHq/_new 2016-09-05 21:15:18.000000000 +0200 @@ -30,6 +30,14 @@ Source1: macros.gdk-pixbuf Source2: README.SUSE Source99: baselibs.conf +# PATCH-FIX-UPSTREAM gdk-pixbuf-bgo768688-bmp-overflow.patch bgo#768688 [email protected] -- fix a bmp overflow. +Patch0: gdk-pixbuf-bgo768688-bmp-overflow.patch +# PATCh-FIX-UPSTREAM gdk-pixbuf-bgo768484-ico-set-errors.patch bgo#768484 [email protected] -- 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 [email protected] -- 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 [email protected] -- 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 @@ %prep %setup -q translation-update-upstream +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %if "%_lib" == "lib64" cp -a %{S:2} . %endif ++++++ gdk-pixbuf-bgo768484-ico-set-errors.patch ++++++ >From 0cff83e985fba5350695c00ed1ac30fc31ec5960 Mon Sep 17 00:00:00 2001 From: Hanno Boeck <[email protected]> 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) { ++++++ gdk-pixbuf-bgo768688-bmp-overflow.patch ++++++ >From b69009f2a2de151103ed87e9594615ba0fe72daf Mon Sep 17 00:00:00 2001 From: Tobias Mueller <[email protected]> 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: ++++++ gdk-pixbuf-bgo769170-ico-headers.patch ++++++ >From 88af50a864195da1a4f7bda5f02539704fbda599 Mon Sep 17 00:00:00 2001 From: Matthias Clasen <[email protected]> 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 <[email protected]> --- 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;I<IconCount;I++) { + int width; + int height; + int x_hot; + int y_hot; + int data_size; + int data_offset; + + width = Ptr[0]; + height = Ptr[1]; + x_hot = (Ptr[5] << 8) + Ptr[4]; + y_hot = (Ptr[7] << 8) + Ptr[6]; + data_size = (Ptr[11] << 24) + (Ptr[10] << 16) + (Ptr[9] << 8) + (Ptr[8]); + data_offset = (Ptr[15] << 24) + (Ptr[14] << 16) + (Ptr[13] << 8) + (Ptr[12]); + DEBUG(g_print ("Image %d: %d x %d\n\tPalette: %d\n", I, width, height, {tr[2]); + if (imgtype == 2) + g_print ("\tHotspot: %d x %d\n", x_hot, y_hot); + else + g_print ("\tColor planes: %d\n\tBits per pixel: %d\n", x_hot, y_hot); + g_print ("\tSize: %d\n\tOffset: %d\n", data_size, data_offset);) + entry = g_new0 (struct ico_direntry_data, 1); - entry->ImageScore = (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, ++++++ gdk-pixbuf-bgo769738-bmp-overflow.patch ++++++ >From 779429ce34e439c01d257444fe9d6739e72a2024 Mon Sep 17 00:00:00 2001 From: Tobias Mueller <[email protected]> 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;
