After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 752297 - heap overflow and DoS affecting Firefox and other programs (x86_64)
heap overflow and DoS affecting Firefox and other programs (x86_64)
Status: RESOLVED FIXED
Product: gdk-pixbuf
Classification: Platform
Component: general
unspecified
Other All
: High normal
: ---
Assigned To: gdk-pixbuf-maint
gdk-pixbuf-maint
Depends on:
Blocks:
 
 
Reported: 2015-07-12 20:52 UTC by Olav Vitters
Modified: 2015-08-17 18:48 UTC
See Also:
GNOME target: 3.18
GNOME version: ---


Attachments
overflow-firefox.bmp (82 bytes, image/bmp)
2015-07-12 20:53 UTC, Olav Vitters
  Details
pixbuf_vuln_poc.c (396 bytes, text/plain)
2015-07-12 20:55 UTC, Olav Vitters
  Details
overflow-32x32.bmp (82 bytes, image/bmp)
2015-07-12 20:57 UTC, Olav Vitters
  Details
pixops: Be more careful about integer overflow (2.72 KB, patch)
2015-07-13 04:45 UTC, Matthias Clasen
committed Details | Review

Description Olav Vitters 2015-07-12 20:52:10 UTC
From: Gustavo Grieco <gustavo.grieco@imag.fr>,
To: security@gnome.org

Hello!

We found a heap overflow and a DoS in the gdk-pixbuf implementation triggered by the scaling of a malformed bmp. These issues are affecting x86_64 builds (we tested in a fully updated Ubuntu 14.04 and Debian Wheezy). For example, Ubuntu 14.04 ships with gdk-pixbuf 2.30 but newer versions are affected as well.

The issue happens when a program is trying to parse and scale a crafted bmp using gdk-pixbuf (for instance, using get_scaled_pixbuf). It will result at least in an DoS aborting the program with a SIGTRAP. It is also possible to perform a heap overflow if you select the suitable width and height in a malicious bmp according to the scaled width and height. The cause of the heap overflow is this integer overflow located here:
https://github.com/GNOME/gdk-pixbuf/blob/f79085cbec9997895e252dce994d18139d719e26/gdk-pixbuf/pixops/pixops.c#L1275
and the insufficient checks performed in the gdk_pixbuf_new function.

Interestingly enough, in a recent version of gdk-pixbuf (2.31 or newer) somebody replaced some old code that checks for a overflow with a g_try_malloc_n that is supposed to check for overflow, but it doesn't in x86_64 (you can see the old and new code here:
https://github.com/GNOME/gdk-pixbuf/commit/deb78d971c4bcb9e3ccbb71e7925bc6baa707188#diff-cde3af8b5b1c0789407148d53a75
ae22R448)

Unfortunately, at least Firefox and Chromium are using gdk-pixbuf primitives to implement file pickers, so they are affected. A minimal example of a vulnerable program is attached: it is just a call to gdk_pixbuf_new_from_file_at_size. Also two bmp POC are included: one to crash the minimal example and another POC to trigger a heap overflow in Firefox (it works with pixbuf 2.31 or newer). You should attach the uncompressed bmp or try to open it (using ctrl+O) (that's the reason we are sending it compressed!). Remember that this vulnerability depends on a malloc call and can fail if your real/virtual memory is not large enough. In particular, the Firefox POC requires at least 12GB of memory available for allocation.

Regards,
Gus.
Comment 1 Olav Vitters 2015-07-12 20:53:55 UTC
Created attachment 307318 [details]
overflow-firefox.bmp
Comment 2 Olav Vitters 2015-07-12 20:55:04 UTC
Created attachment 307319 [details]
pixbuf_vuln_poc.c
Comment 3 Olav Vitters 2015-07-12 20:57:57 UTC
Created attachment 307320 [details]
overflow-32x32.bmp
Comment 4 Matthias Clasen 2015-07-13 04:44:40 UTC
Not sure I see what x86_64 has to do with it - g_malloc_n works just fine here to detect overflow on x86_64. I do see the possibility for overflow in the g_new call you're pointing out, though.

The attached patch tries to catch that possibility.
Comment 5 Matthias Clasen 2015-07-13 04:45:06 UTC
Created attachment 307326 [details] [review]
pixops: Be more careful about integer overflow

Our loader code is supposed to handle out-of-memory and overflow
situations gracefully, reporting errors instead of aborting. But
if you load an image at a specific size, we also execute our
scaling code, which was not careful enough about overflow in some
places. This commit makes the scaling code silently return if
it fails to allocate filter tables.
Comment 6 Benjamin Otte (Company) 2015-07-13 04:53:54 UTC
Review of attachment 307326 [details] [review]:

::: gdk-pixbuf/pixops/pixops.c
@@ +1278,3 @@
+  n_weights = SUBSAMPLE * SUBSAMPLE * n_x * n_y;
+  if (n_weights / (SUBSAMPLE * SUBSAMPLE) != n_x * n_y)
+    return NULL; /* overflow, bail */

This can still overflow if n_x * n_y >= MAXINT.

> if (n_weights / (SUBSAMPLE * SUBSAMPLE * n_x) != n_y)

should be the right check.
Comment 7 Benjamin Otte (Company) 2015-07-13 04:53:56 UTC
Review of attachment 307326 [details] [review]:

::: gdk-pixbuf/pixops/pixops.c
@@ +1278,3 @@
+  n_weights = SUBSAMPLE * SUBSAMPLE * n_x * n_y;
+  if (n_weights / (SUBSAMPLE * SUBSAMPLE) != n_x * n_y)
+    return NULL; /* overflow, bail */

This can still overflow if n_x * n_y >= MAXINT.

> if (n_weights / (SUBSAMPLE * SUBSAMPLE * n_x) != n_y)

should be the right check.
Comment 8 Matthias Clasen 2015-07-13 10:22:00 UTC
Bug 752297 - heap overflow and DoS affecting Firefox and other programs (x86_64) - NEW

Attachment 307326 [details] pushed as ffec86e - pixops: Be more careful about integer overflow
Comment 9 Benjamin Otte (Company) 2015-08-17 18:48:36 UTC
Pushed an update for this bug:

commit 8dba67cb4f38d62a47757741ad41e3f245b4a32a
Author: Benjamin Otte <otte@redhat.com>
Date:   Mon Aug 17 18:52:47 2015 +0200

    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