summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuriy M. Kaminskiy <yumkam@gmail.com>2016-04-13 00:00:58 +0300
committerKim Woelders <kim@woelders.dk>2016-04-13 22:21:58 +0200
commit633a8667b1aad09708e68e0524eff076078a11c7 (patch)
tree6633f87d83cc5676797fed1588827ad8496e1989
parent7836d839512f1a766fa34a098bda31ef2216480c (diff)
downloadimlib2-633a8667b1aad09708e68e0524eff076078a11c7.tar.gz
Harden API and internals against overly large images
Prevents potential integer overflow -> insufficient allocation -> heap overflow scenarios.
-rw-r--r--src/lib/api.c25
-rw-r--r--src/lib/font_draw.c5
-rw-r--r--src/lib/rend.c3
3 files changed, 28 insertions, 5 deletions
diff --git a/src/lib/api.c b/src/lib/api.c
index 35e49c7..9eb1b63 100644
--- a/src/lib/api.c
+++ b/src/lib/api.c
@@ -1976,7 +1976,7 @@ imlib_create_image(int width, int height)
DATA32 *data;
CHECK_CONTEXT(ctx);
- if ((width <= 0) || (height <= 0))
+ if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
data = malloc(width * height * sizeof(DATA32));
if (data)
@@ -2010,7 +2010,7 @@ imlib_create_image_using_data(int width, int height, DATA32 * data)
CHECK_CONTEXT(ctx);
CHECK_PARAM_POINTER_RETURN("imlib_create_image_using_data", "data", data,
NULL);
- if ((width <= 0) || (height <= 0))
+ if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
im = __imlib_CreateImage(width, height, data);
if (im)
@@ -2039,7 +2039,7 @@ imlib_create_image_using_copied_data(int width, int height, DATA32 * data)
CHECK_CONTEXT(ctx);
CHECK_PARAM_POINTER_RETURN("imlib_create_image_using_copied_data", "data",
data, NULL);
- if ((width <= 0) || (height <= 0))
+ if (!IMAGE_DIMENSIONS_OK(width, height))
return NULL;
im = __imlib_CreateImage(width, height, NULL);
if (!im)
@@ -2085,6 +2085,8 @@ imlib_create_image_from_drawable(Pixmap mask, int x, int y, int width,
char domask = 0;
CHECK_CONTEXT(ctx);
+ if (!IMAGE_DIMENSIONS_OK(width, height))
+ return NULL;
if (mask)
{
domask = 1;
@@ -2131,6 +2133,8 @@ imlib_create_image_from_ximage(XImage * image, XImage * mask, int x, int y,
ImlibImage *im;
CHECK_CONTEXT(ctx);
+ if (!IMAGE_DIMENSIONS_OK(width, height))
+ return NULL;
im = __imlib_CreateImage(width, height, NULL);
im->data = malloc(width * height * sizeof(DATA32));
__imlib_GrabXImageToRGBA(im->data, 0, 0, width, height,
@@ -2181,6 +2185,10 @@ imlib_create_scaled_image_from_drawable(Pixmap mask, int source_x,
Pixmap p, m;
CHECK_CONTEXT(ctx);
+ if (!IMAGE_DIMENSIONS_OK(source_width, source_height))
+ return NULL;
+ if (!IMAGE_DIMENSIONS_OK(destination_width, destination_height))
+ return NULL;
if ((mask) || (get_mask_from_shape))
domask = 1;
p = XCreatePixmap(ctx->display, ctx->drawable, destination_width,
@@ -2375,6 +2383,10 @@ imlib_clone_image(void)
im_old->loader->load(im_old, NULL, 0, 1);
if (!(im_old->data))
return NULL;
+ /* Note: below check should've ensured by original image allocation,
+ * but better safe than sorry. */
+ if (!IMAGE_DIMENSIONS_OK(im_old->w, im_old->h))
+ return NULL;
im = __imlib_CreateImage(im_old->w, im_old->h, NULL);
if (!(im))
return NULL;
@@ -2423,6 +2435,8 @@ imlib_create_cropped_image(int x, int y, int width, int height)
CHECK_CONTEXT(ctx);
CHECK_PARAM_POINTER_RETURN("imlib_create_cropped_image", "image",
ctx->image, NULL);
+ if (!IMAGE_DIMENSIONS_OK(abs(width), abs(height)))
+ return NULL;
CAST_IMAGE(im_old, ctx->image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1);
@@ -2479,6 +2493,8 @@ imlib_create_cropped_scaled_image(int source_x, int source_y,
CHECK_CONTEXT(ctx);
CHECK_PARAM_POINTER_RETURN("imlib_create_cropped_scaled_image", "image",
ctx->image, NULL);
+ if (!IMAGE_DIMENSIONS_OK(abs(destination_width), abs(destination_height)))
+ return NULL;
CAST_IMAGE(im_old, ctx->image);
if ((!(im_old->data)) && (im_old->loader) && (im_old->loader->load))
im_old->loader->load(im_old, NULL, 0, 1);
@@ -4681,6 +4697,9 @@ imlib_create_rotated_image(double angle)
dx = (int)(cos(angle) * _ROTATE_PREC_MAX);
dy = -(int)(sin(angle) * _ROTATE_PREC_MAX);
+ if (!IMAGE_DIMENSIONS_OK(sz, sz))
+ return NULL;
+
im = __imlib_CreateImage(sz, sz, NULL);
im->data = calloc(sz * sz, sizeof(DATA32));
if (!(im->data))
diff --git a/src/lib/font_draw.c b/src/lib/font_draw.c
index 72f0316..8ca6c25 100644
--- a/src/lib/font_draw.c
+++ b/src/lib/font_draw.c
@@ -81,10 +81,11 @@ __imlib_render_str(ImlibImage * im, ImlibFont * fn, int drx, int dry,
__imlib_font_query_advance(fn, text, &w, NULL);
h = __imlib_font_max_ascent_get(fn) - __imlib_font_max_descent_get(fn);
- data = malloc(w * h * sizeof(DATA32));
+ if (!IMAGE_DIMENSIONS_OK(w, h))
+ return;
+ data = calloc(w * h, sizeof(DATA32));
if (!data)
return;
- memset(data, 0, w * h * sizeof(DATA32));
/* TODO check if this is the right way of rendering. Esp for huge sizes */
im2 = __imlib_CreateImage(w, h, data);
if (!im2)
diff --git a/src/lib/rend.c b/src/lib/rend.c
index 44be783..cfab830 100644
--- a/src/lib/rend.c
+++ b/src/lib/rend.c
@@ -580,6 +580,9 @@ __imlib_RenderImageSkewed(Display * d, ImlibImage * im, Drawable w, Drawable m,
dy1 = 0;
}
+ if (!IMAGE_DIMENSIONS_OK(dw, dh))
+ return;
+
__imlib_GetContext(d, v, cm, depth);
back = __imlib_CreateImage(dw, dh, NULL);