summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Mueller <muelli@cryptobitch.de>2016-12-06 11:50:58 +0100
committerBastien Nocera <hadess@hadess.net>2016-12-13 17:31:03 +0100
commit9ae4723ec3fa631354e3d201c5435a7385c33d45 (patch)
tree915652ef2f386e56c2c1b4430f86991649b85291
parentc456d26bc597518c67f9e220ab7ac233308a6c59 (diff)
downloadgdk-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.c19
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;