kwo pushed a commit to branch master. http://git.enlightenment.org/legacy/imlib2.git/commit/?id=633a8667b1aad09708e68e0524eff076078a11c7
commit 633a8667b1aad09708e68e0524eff076078a11c7 Author: Yuriy M. Kaminskiy <yum...@gmail.com> Date: Wed Apr 13 00:00:58 2016 +0300 Harden API and internals against overly large images Prevents potential integer overflow -> insufficient allocation -> heap overflow scenarios. --- src/lib/api.c | 25 ++++++++++++++++++++++--- src/lib/font_draw.c | 5 +++-- src/lib/rend.c | 3 +++ 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); --