x11-libs/gdk-pixbuf: more DoS fixes (CVE-2015-4491)
authorAlexandre Rostovtsev <tetromino@gentoo.org>
Tue, 1 Sep 2015 04:28:13 +0000 (00:28 -0400)
committerAlexandre Rostovtsev <tetromino@gentoo.org>
Tue, 1 Sep 2015 05:15:38 +0000 (01:15 -0400)
Really fix the overflows this time.

Gentoo-Bug: 556314
Upstream-Bug-url: https://bugzilla.gnome.org/show_bug.cgi?id=752297
Upstream-Bug-url: https://bugzilla.gnome.org/show_bug.cgi?id=753908
Upstream-Bug-url: https://bugzilla.gnome.org/show_bug.cgi?id=734556
Upstream-Bug-url: https://bugzilla.gnome.org/show_bug.cgi?id=753569
Package-Manager: portage-2.2.20.1

x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.1-pixops-no-scaling.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.5-pixops-overflow.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-alpha-overflow-rebased.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-jpeg-overflow.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-gcc-optimizer.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-overflow-rebased.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-variable-type.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-png-overflow.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-rotate-overflow.patch [new file with mode: 0644]
x11-libs/gdk-pixbuf/gdk-pixbuf-2.30.8-r2.ebuild [new file with mode: 0644]

diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.1-pixops-no-scaling.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.1-pixops-no-scaling.patch
new file mode 100644 (file)
index 0000000..a8587fc
--- /dev/null
@@ -0,0 +1,129 @@
+From cc5fce6315dcc1127a3e2106223305ff763be815 Mon Sep 17 00:00:00 2001
+From: Hans Petter Jansson <hpj@copyleft.no>
+Date: Thu, 10 Nov 2005 19:13:00 +0000
+Subject: [PATCH] pixops: Special-case compositing/copying with no scaling
+
+When there is no scaling involved, make gdk_pixbuf_composite_color()
+faster by avoiding the scaling code path.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=80927
+---
+ gdk-pixbuf/pixops/pixops.c | 95 +++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 90 insertions(+), 5 deletions(-)
+
+diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
+index 993223e..29a1c14 100644
+--- a/gdk-pixbuf/pixops/pixops.c
++++ b/gdk-pixbuf/pixops/pixops.c
+@@ -421,6 +421,86 @@ pixops_composite_nearest (guchar        *dest_buf,
+ }
+ static void
++pixops_composite_nearest_noscale (guchar        *dest_buf,
++                                int            render_x0,
++                                int            render_y0,
++                                int            render_x1,
++                                int            render_y1,
++                                int            dest_rowstride,
++                                int            dest_channels,
++                                gboolean       dest_has_alpha,
++                                const guchar  *src_buf,
++                                int            src_width,
++                                int            src_height,
++                                int            src_rowstride,
++                                int            src_channels,
++                                gboolean       src_has_alpha,
++                                int            overall_alpha)
++{
++  int i, j;
++  int x;
++
++  for (i = 0; i < (render_y1 - render_y0); i++)
++    {
++      const guchar *src  = src_buf + (i + render_y0) * src_rowstride;
++      guchar       *dest = dest_buf + i * dest_rowstride;
++
++      x = render_x0 * src_channels;
++
++      for (j=0; j < (render_x1 - render_x0); j++)
++      {
++        const guchar *p = src + x;
++        unsigned int  a0;
++
++        if (src_has_alpha)
++          a0 = (p[3] * overall_alpha) / 0xff;
++        else
++          a0 = overall_alpha;
++
++        switch (a0)
++          {
++          case 0:
++            break;
++          case 255:
++            dest[0] = p[0];
++            dest[1] = p[1];
++            dest[2] = p[2];
++            if (dest_has_alpha)
++              dest[3] = 0xff;
++            break;
++          default:
++            if (dest_has_alpha)
++              {
++                unsigned int w0 = 0xff * a0;
++                unsigned int w1 = (0xff - a0) * dest[3];
++                unsigned int w = w0 + w1;
++
++                dest[0] = (w0 * p[0] + w1 * dest[0]) / w;
++                dest[1] = (w0 * p[1] + w1 * dest[1]) / w;
++                dest[2] = (w0 * p[2] + w1 * dest[2]) / w;
++                dest[3] = w / 0xff;
++              }
++            else
++              {
++                unsigned int a1 = 0xff - a0;
++                unsigned int tmp;
++
++                tmp = a0 * p[0] + a1 * dest[0] + 0x80;
++                dest[0] = (tmp + (tmp >> 8)) >> 8;
++                tmp = a0 * p[1] + a1 * dest[1] + 0x80;
++                dest[1] = (tmp + (tmp >> 8)) >> 8;
++                tmp = a0 * p[2] + a1 * dest[2] + 0x80;
++                dest[2] = (tmp + (tmp >> 8)) >> 8;
++              }
++            break;
++          }
++        dest += dest_channels;
++        x += src_channels;
++      }
++    }
++}
++
++static void
+ pixops_composite_color_nearest (guchar        *dest_buf,
+                               int            render_x0,
+                               int            render_y0,
+@@ -1781,11 +1861,16 @@ _pixops_composite_real (guchar          *dest_buf,
+   if (interp_type == PIXOPS_INTERP_NEAREST)
+     {
+-      pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1,
+-                              render_y1, dest_rowstride, dest_channels,
+-                              dest_has_alpha, src_buf, src_width, src_height,
+-                              src_rowstride, src_channels, src_has_alpha,
+-                              scale_x, scale_y, overall_alpha);
++      if (scale_x == 1.0 && scale_y == 1.0)
++      pixops_composite_nearest_noscale (dest_buf, render_x0, render_y0, render_x1, render_y1,
++                                        dest_rowstride, dest_channels, dest_has_alpha,
++                                        src_buf, src_width, src_height, src_rowstride, src_channels,
++                                        src_has_alpha, overall_alpha);
++      else
++      pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1,
++                                dest_rowstride, dest_channels, dest_has_alpha,
++                                src_buf, src_width, src_height, src_rowstride, src_channels,
++                                src_has_alpha, scale_x, scale_y, overall_alpha);
+       return;
+     }
+   
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.5-pixops-overflow.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.5-pixops-overflow.patch
new file mode 100644 (file)
index 0000000..6f28dfd
--- /dev/null
@@ -0,0 +1,38 @@
+From 8dba67cb4f38d62a47757741ad41e3f245b4a32a Mon Sep 17 00:00:00 2001
+From: Benjamin Otte <otte@redhat.com>
+Date: Mon, 17 Aug 2015 18:52:47 +0200
+Subject: [PATCH] pixops: Fix oversight for CVE-2015-4491
+
+The n_x variable could be made large enough to overflow, too.
+
+Also included are various testcases for this vulnerability:
+- The original exploit (adapted for the testsuite)
+- Causing overflow by making both X and Y variables large
+- Causing overflow using only the X variable
+- Causing overflow using only the Y variable
+
+https://bugzilla.gnome.org/show_bug.cgi?id=752297
+---
+ gdk-pixbuf/pixops/pixops.c    |   6 ++-
+ 1 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
+index ce51745..7f2cbff 100644
+--- a/gdk-pixbuf/pixops/pixops.c
++++ b/gdk-pixbuf/pixops/pixops.c
+@@ -1275,7 +1275,11 @@ make_filter_table (PixopsFilter *filter)
+   gsize n_weights;
+   int *weights;
+-  n_weights = SUBSAMPLE * SUBSAMPLE * n_x * n_y;
++  n_weights = SUBSAMPLE * SUBSAMPLE * n_x;
++  if (n_weights / (SUBSAMPLE * SUBSAMPLE) != n_x)
++    return NULL; /* overflow, bail */
++
++  n_weights *= n_y;
+   if (n_weights / (SUBSAMPLE * SUBSAMPLE * n_x) != n_y)
+     return NULL; /* overflow, bail */
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-alpha-overflow-rebased.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-alpha-overflow-rebased.patch
new file mode 100644 (file)
index 0000000..647dd59
--- /dev/null
@@ -0,0 +1,79 @@
+From 2937faff06629e224f113a9af73eba59f65c3845 Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Mon, 24 Aug 2015 15:20:08 -0400
+Subject: [PATCH] Avoid integer overflow in gdk_pixbuf_add_alpha
+
+Same as before: don't do ptr = base + y * rowstride if y and
+rowstride are integers.
+
+This should fix http://bugzilla.gnome/org/753569
+---
+ gdk-pixbuf/gdk-pixbuf-util.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/gdk-pixbuf/gdk-pixbuf-util.c b/gdk-pixbuf/gdk-pixbuf-util.c
+index 6fbaa8e..6eea4c3 100644
+--- a/gdk-pixbuf/gdk-pixbuf-util.c
++++ b/gdk-pixbuf/gdk-pixbuf-util.c
+@@ -65,12 +65,18 @@ gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
+ {
+       GdkPixbuf *new_pixbuf;
+       int x, y;
++      const guint8 *src_pixels;
++      guint8 *ret_pixels;
++      const guchar *src;
++      guchar *dest;
+       g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+       g_return_val_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB, NULL);
+       g_return_val_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4, NULL);
+       g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL);
++      src_pixels = pixbuf->pixels;
++
+       if (pixbuf->has_alpha) {
+               new_pixbuf = gdk_pixbuf_copy (pixbuf);
+               if (!new_pixbuf)
+@@ -81,17 +87,18 @@ gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
+       } else {
+                 new_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, pixbuf->width, pixbuf->height);
+         }
+-        
++
+       if (!new_pixbuf)
+               return NULL;
+-      for (y = 0; y < pixbuf->height; y++) {
+-              guchar *src, *dest;
++      ret_pixels = new_pixbuf->pixels;
++
++      for (y = 0; y < pixbuf->height; y++, src_pixels += pixbuf->rowstride, ret_pixels += new_pixbuf->rowstride) {
+               guchar tr, tg, tb;
+-              src = pixbuf->pixels + y * pixbuf->rowstride;
+-              dest = new_pixbuf->pixels + y * new_pixbuf->rowstride;
+-                
++                src = src_pixels;
++                dest = ret_pixels;
++
+                 if (pixbuf->has_alpha) {
+                         /* Just subst color, we already copied everything else */
+                         for (x = 0; x < pixbuf->width; x++) {
+@@ -100,12 +107,12 @@ gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf,
+                                 src += 4;
+                                 dest += 4;
+                         }
+-                } else {                        
++                } else {
+                         for (x = 0; x < pixbuf->width; x++) {
+                                 tr = *dest++ = *src++;
+                                 tg = *dest++ = *src++;
+                                 tb = *dest++ = *src++;
+-                                
++
+                                 if (substitute_color && tr == r && tg == g && tb == b)
+                                         *dest++ = 0;
+                                 else
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-jpeg-overflow.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-jpeg-overflow.patch
new file mode 100644 (file)
index 0000000..ebec196
--- /dev/null
@@ -0,0 +1,35 @@
+From fde8d1d12a32740770253e97ddc9602654e16865 Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Mon, 24 Aug 2015 15:48:51 -0400
+Subject: [PATCH] jpeg: Fix some integer overflows
+
+Similar to the previous commit.
+---
+ gdk-pixbuf/io-jpeg.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
+index fa6bec1..eb48aed 100644
+--- a/gdk-pixbuf/io-jpeg.c
++++ b/gdk-pixbuf/io-jpeg.c
+@@ -886,7 +886,7 @@ gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
+                         return FALSE;
+                 }
+-                context->dptr += nlines * context->pixbuf->rowstride;
++                context->dptr += (gsize)nlines * context->pixbuf->rowstride;
+                 /* send updated signal */
+               if (context->updated_func)
+@@ -1494,7 +1494,7 @@ real_save_jpeg (GdkPixbuf          *pixbuf,
+        while (cinfo.next_scanline < cinfo.image_height) {
+                /* convert scanline from ARGB to RGB packed */
+                for (j = 0; j < w; j++)
+-                       memcpy (&(buf[j*3]), &(ptr[i*rowstride + j*n_channels]), 3);
++                       memcpy (&(buf[j*3]), &(ptr[(gsize)i*rowstride + j*n_channels]), 3);
+                /* write scanline */
+                jbuf = (JSAMPROW *)(&buf);
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-gcc-optimizer.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-gcc-optimizer.patch
new file mode 100644 (file)
index 0000000..bd957b7
--- /dev/null
@@ -0,0 +1,46 @@
+From dd4b061c27dc0865c8f8987d294de6e04b321c18 Mon Sep 17 00:00:00 2001
+From: Benjamin Otte <otte@redhat.com>
+Date: Sat, 22 Aug 2015 23:06:23 +0200
+Subject: [PATCH] pixops: Be smarter than gcc's optimizer
+
+gcc realizes that the overflow checks aren't necessary. Why not?
+
+Well, if an int overflows, the behavior is undefined. And turning on
+-fomit-instructions is valid behavior in an undefined situation.
+---
+ gdk-pixbuf/pixops/pixops.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
+index b7951c7..5564a40 100644
+--- a/gdk-pixbuf/pixops/pixops.c
++++ b/gdk-pixbuf/pixops/pixops.c
+@@ -1272,18 +1272,17 @@ make_filter_table (PixopsFilter *filter)
+   int i_offset, j_offset;
+   int n_x = filter->x.n;
+   int n_y = filter->y.n;
+-  int n_weights;
+   int *weights;
+-  n_weights = SUBSAMPLE * SUBSAMPLE * n_x;
+-  if (n_weights / (SUBSAMPLE * SUBSAMPLE) != n_x)
+-    return NULL; /* overflow, bail */
++  /* check n_x doesn't overflow */
++  if (G_MAXINT / (SUBSAMPLE * SUBSAMPLE) < n_x)
++    return NULL;
+-  n_weights *= n_y;
+-  if (n_weights / (SUBSAMPLE * SUBSAMPLE * n_x) != n_y)
+-    return NULL; /* overflow, bail */
++  /* check n_y doesn't overflow */
++  if (G_MAXINT / (SUBSAMPLE * SUBSAMPLE * n_x) < n_y)
++    return NULL;
+-  weights = g_try_new (int, n_weights);
++  weights = g_try_new (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y);
+   if (!weights)
+     return NULL; /* overflow, bail */
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-overflow-rebased.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-overflow-rebased.patch
new file mode 100644 (file)
index 0000000..cb94784
--- /dev/null
@@ -0,0 +1,162 @@
+From 6df428ba24d8f244d08c4a205053e26b28cee0a9 Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Mon, 24 Aug 2015 14:44:50 -0400
+Subject: [PATCH] Fix some more integer overflows
+
+The scaling code had a similar problem to the one fixed in the
+previous commit: Expressions like ptr = base + y * rowstride are
+prone to overflow if y and rowstride are (possibly large) integers.
+---
+ gdk-pixbuf/pixops/pixops.c | 44 ++++++++++++++++++++++----------------------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
+index 993223e..33aa32e 100644
+--- a/gdk-pixbuf/pixops/pixops.c
++++ b/gdk-pixbuf/pixops/pixops.c
+@@ -304,8 +304,8 @@ pixops_scale_nearest (guchar        *dest_buf,
+       guchar       *dest;
+       y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
+       y_pos = CLAMP (y_pos, 0, src_height - 1);
+-      src  = src_buf + y_pos * src_rowstride;
+-      dest = dest_buf + i * dest_rowstride;
++      src  = src_buf + (gsize)y_pos * src_rowstride;
++      dest = dest_buf + (gsize)i * dest_rowstride;
+       x = render_x0 * x_step + x_step / 2;
+@@ -368,8 +368,8 @@ pixops_composite_nearest (guchar        *dest_buf,
+       guchar       *dest;
+       y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
+       y_pos = CLAMP (y_pos, 0, src_height - 1);
+-      src  = src_buf + y_pos * src_rowstride;
+-      dest = dest_buf + i * dest_rowstride;
++      src  = src_buf + (gsize)y_pos * src_rowstride;
++      dest = dest_buf + (gsize)i * dest_rowstride;
+       x = render_x0 * x_step + x_step / 2;
+       
+@@ -460,8 +460,8 @@ pixops_composite_color_nearest (guchar        *dest_buf,
+       guchar       *dest;
+       y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
+       y_pos = CLAMP (y_pos, 0, src_height - 1);
+-      src  = src_buf + y_pos * src_rowstride;
+-      dest = dest_buf + i * dest_rowstride;
++      src  = src_buf + (gsize)y_pos * src_rowstride;
++      dest = dest_buf + (gsize)i * dest_rowstride;
+       x = render_x0 * x_step + x_step / 2;
+       
+@@ -1303,7 +1303,7 @@ pixops_process (guchar         *dest_buf,
+       guchar *new_outbuf;
+       guint32 tcolor1, tcolor2;
+-      guchar *outbuf = dest_buf + dest_rowstride * i;
++      guchar *outbuf = dest_buf + (gsize)dest_rowstride * i;
+       guchar *outbuf_end = outbuf + dest_channels * (render_x1 - render_x0);
+       if (((i + check_y) >> check_shift) & 1)
+@@ -1322,9 +1322,9 @@ pixops_process (guchar         *dest_buf,
+         if (y_start <  0)
+           line_bufs[j] = (guchar *)src_buf;
+         else if (y_start < src_height)
+-          line_bufs[j] = (guchar *)src_buf + src_rowstride * y_start;
++          line_bufs[j] = (guchar *)src_buf + (gsize)src_rowstride * y_start;
+         else
+-          line_bufs[j] = (guchar *)src_buf + src_rowstride * (src_height - 1);
++          line_bufs[j] = (guchar *)src_buf + (gsize)src_rowstride * (src_height - 1);
+         y_start++;
+       }
+@@ -1348,7 +1348,7 @@ pixops_process (guchar         *dest_buf,
+       }
+       new_outbuf = (*line_func) (run_weights, filter->x.n, filter->y.n,
+-                               outbuf, dest_x, dest_buf + dest_rowstride *
++                               outbuf, dest_x, dest_buf + (gsize)dest_rowstride *
+                                i + run_end_index * dest_channels,
+                                dest_channels, dest_has_alpha,
+                                line_bufs, src_channels, src_has_alpha,
+@@ -1866,7 +1866,7 @@ _pixops_composite (guchar          *dest_buf,
+   return;
+ #endif
+-  new_dest_buf = dest_buf + dest_y * dest_rowstride + dest_x * dest_channels;
++  new_dest_buf = dest_buf + (gsize)dest_y * dest_rowstride + (gsize)dest_x * dest_channels;
+   render_x0 = dest_x - offset_x;
+   render_y0 = dest_y - offset_y;
+   render_x1 = dest_x + dest_region_width  - offset_x;
+@@ -2026,7 +2026,7 @@ pixops_medialib_composite (guchar          *dest_buf,
+   if (!use_medialib)
+     {
+       /* Use non-mediaLib version */
+-      _pixops_composite_real (dest_buf + dest_y * dest_rowstride + dest_x *
++      _pixops_composite_real (dest_buf + (gsize)dest_y * dest_rowstride + (gsize)dest_x *
+                             dest_channels, dest_x - offset_x, dest_y -
+                             offset_y, dest_x + dest_region_width - offset_x,
+                             dest_y + dest_region_height - offset_y,
+@@ -2068,8 +2068,8 @@ pixops_medialib_composite (guchar          *dest_buf,
+         }
+       else
+         {
+-        mlib_u8 *data = dest_buf + (dest_y * dest_rowstride) + 
+-                                   (dest_x * dest_channels);
++        mlib_u8 *data = dest_buf + (gsize)dest_y * dest_rowstride +
++                                   (gsize)dest_x * dest_channels;
+           mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels,
+                              dest_region_width, dest_region_height,
+@@ -2136,8 +2136,8 @@ pixops_medialib_composite (guchar          *dest_buf,
+               else
+                 {
+                   /* Should not happen - Use non-mediaLib version */
+-                  _pixops_composite_real (dest_buf + dest_y * dest_rowstride +
+-                                          dest_x * dest_channels,
++                  _pixops_composite_real (dest_buf + (gsize)dest_y * dest_rowstride +
++                                          (gsize)dest_x * dest_channels,
+                                           dest_x - offset_x, dest_y - offset_y,
+                                           dest_x + dest_region_width - offset_x,
+                                           dest_y + dest_region_height - offset_y,
+@@ -2260,7 +2260,7 @@ _pixops_scale (guchar          *dest_buf,
+   return;
+ #endif
+-  new_dest_buf = dest_buf + dest_y * dest_rowstride + dest_x * dest_channels;
++  new_dest_buf = dest_buf + (gsize)dest_y * dest_rowstride + (gsize)dest_x * dest_channels;
+   render_x0    = dest_x - offset_x;
+   render_y0    = dest_y - offset_y;
+   render_x1    = dest_x + dest_region_width  - offset_x;
+@@ -2314,8 +2314,8 @@ pixops_medialib_scale     (guchar          *dest_buf,
+    */
+   if (!use_medialib)
+     {
+-      _pixops_scale_real (dest_buf + dest_y * dest_rowstride + dest_x *
+-                        dest_channels, dest_x - offset_x, dest_y - offset_y, 
++      _pixops_scale_real (dest_buf + (gsize)dest_y * dest_rowstride + (gsize)dest_x *
++                        dest_channels, dest_x - offset_x, dest_y - offset_y,
+                         dest_x + dest_region_width - offset_x,
+                         dest_y + dest_region_height - offset_y,
+                         dest_rowstride, dest_channels, dest_has_alpha,
+@@ -2343,8 +2343,8 @@ pixops_medialib_scale     (guchar          *dest_buf,
+         }
+       else
+         {
+-        mlib_u8 *data = dest_buf + (dest_y * dest_rowstride) + 
+-                                   (dest_x * dest_channels);
++        mlib_u8 *data = dest_buf + (gsize)dest_y * dest_rowstride +
++                                   (gsize)dest_x * dest_channels;
+           mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels,
+                              dest_region_width, dest_region_height,
+@@ -2379,7 +2379,7 @@ pixops_medialib_scale     (guchar          *dest_buf,
+               int channels  = 3;
+               int rowstride = (channels * src_width + 3) & ~3;
+         
+-              tmp_buf = g_malloc (src_rowstride * src_height);
++              tmp_buf = g_malloc_n (src_rowstride, src_height);
+               if (src_buf != NULL)
+                 {
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-variable-type.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-pixops-variable-type.patch
new file mode 100644 (file)
index 0000000..a83535f
--- /dev/null
@@ -0,0 +1,37 @@
+From 3df91dc6c6f8d1421e9c8756959280de792af77a Mon Sep 17 00:00:00 2001
+From: Benjamin Otte <otte@redhat.com>
+Date: Sat, 22 Aug 2015 17:57:23 +0200
+Subject: [PATCH] pixops: Chane variable type
+
+n_weights is used to do overflow checks. So by reducing the size to 32
+bits signed we overflow earlier. This is necessary because further down
+the code lots of code uses int variables to iterate over this variable
+and we don't want those to overflow.
+
+The correct fix would be to make all those variables gsize too, but
+that's way more invasive and requires different checks in different
+places so I'm not gonna do that now.
+And as long as scale factors are not expected to reach G_MAXINT it's not
+really necessary to do this change anyway.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=753908
+---
+ gdk-pixbuf/pixops/pixops.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
+index 7f2cbff..b7951c7 100644
+--- a/gdk-pixbuf/pixops/pixops.c
++++ b/gdk-pixbuf/pixops/pixops.c
+@@ -1272,7 +1272,7 @@ make_filter_table (PixopsFilter *filter)
+   int i_offset, j_offset;
+   int n_x = filter->x.n;
+   int n_y = filter->y.n;
+-  gsize n_weights;
++  int n_weights;
+   int *weights;
+   n_weights = SUBSAMPLE * SUBSAMPLE * n_x;
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-png-overflow.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-png-overflow.patch
new file mode 100644 (file)
index 0000000..83c67b5
--- /dev/null
@@ -0,0 +1,72 @@
+From 8714ab407c54d5989d15a78eb15550c2d52d95b8 Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Mon, 24 Aug 2015 14:13:37 -0400
+Subject: [PATCH] png: Fix some integer overflows
+
+The png loader was not careful enough in some places. Width * height
+can overflow an integer.
+
+This should fix http://bugzilla.gnome.org/734556.
+---
+ gdk-pixbuf/io-png.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
+index 3336b1e..5690875 100644
+--- a/gdk-pixbuf/io-png.c
++++ b/gdk-pixbuf/io-png.c
+@@ -267,6 +267,7 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
+         gchar *density_str;
+         guint32 retval;
+         gint compression_type;
++        gpointer ptr;
+ #ifdef PNG_USER_MEM_SUPPORTED
+       png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING,
+@@ -326,8 +327,8 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
+       rows = g_new (png_bytep, h);
+-      for (i = 0; i < h; i++)
+-              rows[i] = pixbuf->pixels + i * pixbuf->rowstride;
++        for (i = 0, ptr = pixbuf->pixels; i < h; i++, ptr += pixbuf->rowstride)
++              rows[i] = ptr;
+       png_read_image (png_ptr, rows);
+         png_read_end (png_ptr, info_ptr);
+@@ -745,6 +746,7 @@ png_row_callback   (png_structp png_read_ptr,
+ {
+         LoadContext* lc;
+         guchar* old_row = NULL;
++        gsize rowstride;
+         lc = png_get_progressive_ptr(png_read_ptr);
+@@ -770,8 +772,9 @@ png_row_callback   (png_structp png_read_ptr,
+         lc->max_row_seen_in_chunk = MAX(lc->max_row_seen_in_chunk, ((gint)row_num));
+         lc->last_row_seen_in_chunk = row_num;
+         lc->last_pass_seen_in_chunk = pass_num;
+-        
+-        old_row = lc->pixbuf->pixels + (row_num * lc->pixbuf->rowstride);
++
++        rowstride = lc->pixbuf->rowstride;
++        old_row = lc->pixbuf->pixels + (row_num * rowstride);
+         png_progressive_combine_row(lc->png_read_ptr, old_row, new_row);
+ }
+@@ -1123,11 +1126,9 @@ static gboolean real_save_png (GdkPixbuf        *pixbuf,
+        png_set_shift (png_ptr, &sig_bit);
+        png_set_packing (png_ptr);
+-       ptr = pixels;
+-       for (y = 0; y < h; y++) {
++       for (y = 0, ptr = pixels; y < h; y++, ptr += rowstride) {
+                row_ptr = (png_bytep)ptr;
+                png_write_rows (png_ptr, &row_ptr, 1);
+-               ptr += rowstride;
+        }
+        png_write_end (png_ptr, info_ptr);
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-rotate-overflow.patch b/x11-libs/gdk-pixbuf/files/gdk-pixbuf-2.31.6-rotate-overflow.patch
new file mode 100644 (file)
index 0000000..fa6b90c
--- /dev/null
@@ -0,0 +1,27 @@
+From 4f68cb78a5277f169b9531e6998c00c7976594e4 Mon Sep 17 00:00:00 2001
+From: Matthias Clasen <mclasen@redhat.com>
+Date: Mon, 24 Aug 2015 15:29:36 -0400
+Subject: [PATCH] Avoid integer overflow in gdk_pixbuf_rotate_simple
+
+Same as before: don't do ptr = base + y * rowstride if y and
+rowstride are integers.
+---
+ gdk-pixbuf/gdk-pixbuf-scale.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gdk-pixbuf/gdk-pixbuf-scale.c b/gdk-pixbuf/gdk-pixbuf-scale.c
+index 4288c65..475126a 100644
+--- a/gdk-pixbuf/gdk-pixbuf-scale.c
++++ b/gdk-pixbuf/gdk-pixbuf-scale.c
+@@ -396,7 +396,7 @@ gdk_pixbuf_composite_color_simple (const GdkPixbuf *src,
+   return dest;
+ }
+-#define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (y) * (pb)->rowstride)
++#define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (gsize)(y) * (pb)->rowstride)
+ /**
+  * gdk_pixbuf_rotate_simple:
+-- 
+2.5.1
+
diff --git a/x11-libs/gdk-pixbuf/gdk-pixbuf-2.30.8-r2.ebuild b/x11-libs/gdk-pixbuf/gdk-pixbuf-2.30.8-r2.ebuild
new file mode 100644 (file)
index 0000000..eb578ac
--- /dev/null
@@ -0,0 +1,134 @@
+# Copyright 1999-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI="5"
+GCONF_DEBUG="no"
+GNOME2_LA_PUNT="yes"
+
+inherit eutils flag-o-matic gnome2 multilib libtool multilib-minimal
+
+DESCRIPTION="Image loading library for GTK+"
+HOMEPAGE="http://www.gtk.org/"
+
+LICENSE="LGPL-2+"
+SLOT="2"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~amd64-fbsd ~x86-fbsd ~x86-freebsd ~x86-interix ~amd64-linux ~arm-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris"
+IUSE="+X debug +introspection jpeg jpeg2k tiff test"
+
+COMMON_DEPEND="
+       >=dev-libs/glib-2.37.6:2[${MULTILIB_USEDEP}]
+       >=media-libs/libpng-1.4:0=[${MULTILIB_USEDEP}]
+       introspection? ( >=dev-libs/gobject-introspection-0.9.3 )
+       jpeg? ( virtual/jpeg:0=[${MULTILIB_USEDEP}] )
+       jpeg2k? ( media-libs/jasper:=[${MULTILIB_USEDEP}] )
+       tiff? ( >=media-libs/tiff-3.9.2:0=[${MULTILIB_USEDEP}] )
+       X? ( x11-libs/libX11[${MULTILIB_USEDEP}] )
+"
+DEPEND="${COMMON_DEPEND}
+       >=dev-util/gtk-doc-am-1.20
+       >=sys-devel/gettext-0.17
+       virtual/pkgconfig
+"
+# librsvg blocker is for the new pixbuf loader API, you lose icons otherwise
+RDEPEND="${COMMON_DEPEND}
+       !<gnome-base/gail-1000
+       !<gnome-base/librsvg-2.31.0
+       !<x11-libs/gtk+-2.21.3:2
+       !<x11-libs/gtk+-2.90.4:3
+       abi_x86_32? (
+               !<=app-emulation/emul-linux-x86-gtklibs-20131008-r2
+               !app-emulation/emul-linux-x86-gtklibs[-abi_x86_32(-)]
+       )
+"
+
+MULTILIB_CHOST_TOOLS=(
+       /usr/bin/gdk-pixbuf-query-loaders
+)
+
+src_prepare() {
+       # Upstream patches from 2.31.x
+       epatch "${FILESDIR}"/${PN}-2.30.8-divide-by-zero.patch \
+               "${FILESDIR}"/${PN}-2.30.8-pixops-overflow.patch \
+               "${FILESDIR}"/${PN}-2.31.5-pixops-overflow.patch \
+               "${FILESDIR}"/${PN}-2.31.6-pixops-variable-type.patch \
+               "${FILESDIR}"/${PN}-2.31.6-pixops-gcc-optimizer.patch \
+               "${FILESDIR}"/${PN}-2.31.6-png-overflow.patch \
+               "${FILESDIR}"/${PN}-2.31.6-jpeg-overflow.patch \
+               "${FILESDIR}"/${PN}-2.31.6-pixops-overflow-rebased.patch \
+               "${FILESDIR}"/${PN}-2.31.6-alpha-overflow-rebased.patch \
+               "${FILESDIR}"/${PN}-2.31.6-rotate-overflow.patch #556314
+
+       # This will avoid polluting the pkg-config file with versioned libpng,
+       # which is causing problems with libpng14 -> libpng15 upgrade
+       # See upstream bug #667068
+       # First check that the pattern is present, to catch upstream changes on bumps,
+       # because sed doesn't return failure code if it doesn't do any replacements
+       grep -q  'l in libpng16' configure || die "libpng check order has changed upstream"
+       sed -e 's:l in libpng16:l in libpng libpng16:' -i configure || die
+       [[ ${CHOST} == *-solaris* ]] && append-libs intl
+
+       gnome2_src_prepare
+}
+
+multilib_src_configure() {
+       # png always on to display icons
+       ECONF_SOURCE="${S}" \
+       gnome2_src_configure \
+               $(usex debug --enable-debug=yes "") \
+               $(use_with jpeg libjpeg) \
+               $(use_with jpeg2k libjasper) \
+               $(use_with tiff libtiff) \
+               $(multilib_native_use_enable introspection) \
+               $(use_with X x11) \
+               --with-libpng
+
+       # work-around gtk-doc out-of-source brokedness
+       if multilib_is_native_abi; then
+               ln -s "${S}"/docs/reference/${PN}/html docs/reference/${PN}/html || die
+       fi
+}
+
+multilib_src_install() {
+       # Parallel install fails when no gdk-pixbuf is already installed, bug #481372
+       MAKEOPTS="${MAKEOPTS} -j1" gnome2_src_install
+}
+
+pkg_preinst() {
+       gnome2_pkg_preinst
+
+       multilib_pkg_preinst() {
+               # Make sure loaders.cache belongs to gdk-pixbuf alone
+               local cache="usr/$(get_libdir)/${PN}-2.0/2.10.0/loaders.cache"
+
+               if [[ -e ${EROOT}${cache} ]]; then
+                       cp "${EROOT}"${cache} "${ED}"/${cache} || die
+               else
+                       touch "${ED}"/${cache} || die
+               fi
+       }
+
+       multilib_foreach_abi multilib_pkg_preinst
+}
+
+pkg_postinst() {
+       # causes segfault if set, see bug 375615
+       unset __GL_NO_DSO_FINALIZER
+
+       multilib_foreach_abi gnome2_pkg_postinst
+
+       # Migration snippet for when this was handled by gtk+
+       if [ -e "${EROOT}"usr/lib/gtk-2.0/2.*/loaders ]; then
+               elog "You need to rebuild ebuilds that installed into" "${EROOT}"usr/lib/gtk-2.0/2.*/loaders
+               elog "to do that you can use qfile from portage-utils:"
+               elog "emerge -va1 \$(qfile -qC ${EPREFIX}/usr/lib/gtk-2.0/2.*/loaders)"
+       fi
+}
+
+pkg_postrm() {
+       gnome2_pkg_postrm
+
+       if [[ -z ${REPLACED_BY_VERSIONS} ]]; then
+               rm -f "${EROOT}"usr/lib*/${PN}-2.0/2.10.0/loaders.cache
+       fi
+}