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;

Reply via email to