diff options
author | Tobias Mueller <muelli@cryptobitch.de> | 2016-12-06 11:50:58 +0100 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2016-12-13 17:31:03 +0100 |
commit | 9ae4723ec3fa631354e3d201c5435a7385c33d45 (patch) | |
tree | 915652ef2f386e56c2c1b4430f86991649b85291 | |
parent | c456d26bc597518c67f9e220ab7ac233308a6c59 (diff) | |
download | gdk-pixbuf-9ae4723ec3fa631354e3d201c5435a7385c33d45.tar.gz |
pixdata: Prevent buffer overflow by checking for bounds before memcpy
https://bugzilla.gnome.org/show_bug.cgi?id=775693
-rw-r--r-- | gdk-pixbuf/gdk-pixdata.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/gdk-pixbuf/gdk-pixdata.c b/gdk-pixbuf/gdk-pixdata.c index e187f8d66..9f1adc146 100644 --- a/gdk-pixbuf/gdk-pixdata.c +++ b/gdk-pixbuf/gdk-pixdata.c @@ -430,6 +430,7 @@ gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata, { guint encoding, bpp; guint8 *data = NULL; + guint8 *data_limit = NULL; g_return_val_if_fail (pixdata != NULL, NULL); g_return_val_if_fail (pixdata->width > 0, NULL); @@ -449,6 +450,9 @@ gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata, if (copy_pixels) { data = g_try_malloc_n (pixdata->height, pixdata->rowstride); + /* If this calculation overflows, data is NULL */ + const size_t data_size = pixdata->height * pixdata->rowstride; + data_limit = data + data_size; if (!data) { g_set_error (error, GDK_PIXBUF_ERROR, @@ -515,7 +519,20 @@ gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata, } } else if (copy_pixels) - memcpy (data, pixdata->pixel_data, pixdata->rowstride * pixdata->height); + { + if (data + (pixdata->rowstride * pixdata->height) < data_limit) + { + memcpy (data, pixdata->pixel_data, pixdata->rowstride * pixdata->height); + } + else + { + g_free (data); + g_set_error_literal (error, GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image pixel data corrupt")); + return NULL; + } + } else data = pixdata->pixel_data; |