[gdk-pixbuf] io-bmp: Add overflow checks to BMP image saver



commit fe541abddc141b017a03b1b71df0a6f038acf13b
Author: Philip Withnall <withnall endlessm com>
Date:   Mon Jan 16 10:14:49 2017 +0000

    io-bmp: Add overflow checks to BMP image saver
    
    Return an error if the image width or height are too big to fit in the
    BMP size fields.
    
    This bumps our GLib dependency to 2.48.0, as it uses
    g_uint_checked_mul(). If you want to backport this fix, it’s probably
    best to use __builtin_umul_overflow() directly (if compiling using GCC
    or another compiler which supports it).
    
    Coverity ID: 1388532
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777315

 configure.ac        |    2 +-
 gdk-pixbuf/io-bmp.c |   26 +++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 0608c38..d55f3dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ m4_define([gdk_pixbuf_binary_version], [2.10.0])
 
 
 # required versions of other packages
-m4_define([glib_required_version], [2.37.6])
+m4_define([glib_required_version], [2.48.0])
 
 AC_INIT([gdk-pixbuf], [gdk_pixbuf_version],
         [http://bugzilla.gnome.org/enter_bug.cgi?product=gdk-pixbuf],
diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c
index f78c092..6460e7f 100644
--- a/gdk-pixbuf/io-bmp.c
+++ b/gdk-pixbuf/io-bmp.c
@@ -1327,6 +1327,7 @@ gdk_pixbuf__bmp_image_save_to_callback (GdkPixbufSaveFunc   save_func,
                                        GError            **error)
 {
        guint width, height, channel, size, stride, src_stride, x, y;
+       guint bf_size;
        guchar BFH_BIH[54], *pixels, *buf, *src, *dst, *dst_line;
        gboolean ret;
 
@@ -1335,14 +1336,33 @@ gdk_pixbuf__bmp_image_save_to_callback (GdkPixbufSaveFunc   save_func,
        channel = gdk_pixbuf_get_n_channels (pixbuf);
        pixels = gdk_pixbuf_get_pixels (pixbuf);
        src_stride = gdk_pixbuf_get_rowstride (pixbuf);
-       stride = (width * 3 + 3) & ~3;
-       size = stride * height;
+
+       /* stride = (width * 3 + 3) & ~3 */
+       if (!g_uint_checked_mul (&stride, width, 3) ||
+           !g_uint_checked_add (&stride, stride, 3)) {
+               g_set_error_literal (error, GDK_PIXBUF_ERROR,
+                                    GDK_PIXBUF_ERROR_FAILED,
+                                    _("Image is too wide for BMP format."));
+               return FALSE;
+       }
+
+       stride &= ~3;
+
+       /* size = stride * height
+        * bf_size = size + 14 + 40 */
+       if (!g_uint_checked_mul (&size, stride, height) ||
+           !g_uint_checked_add (&bf_size, size, 14 + 40)) {
+               g_set_error_literal (error, GDK_PIXBUF_ERROR,
+                                    GDK_PIXBUF_ERROR_FAILED,
+                                    _("Image is too wide for BMP format."));
+               return FALSE;
+       }
 
        /* filling BFH */
        dst = BFH_BIH;
        *dst++ = 'B';                   /* bfType */
        *dst++ = 'M';
-       put32 (dst, size + 14 + 40);    /* bfSize */
+       put32 (dst, bf_size);   /* bfSize */
        put32 (dst, 0);                 /* bfReserved1 + bfReserved2 */
        put32 (dst, 14 + 40);           /* bfOffBits */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]