From 1f3adb0ea5171f990b2299fb6e2c9f25030ccbd3 Mon Sep 17 00:00:00 2001 From: Martin Frydl Date: Fri, 26 Feb 2010 11:10:18 +0100 Subject: [PATCH] Patch for WINGs buffer overflow I've found a buffer overflow problem in RSmoothScaleImage. There are some scaling calculations involving floats which are finally converted to integers. Since such conversion does not round the number, just truncates the decimal part, sometimes the number is smaller than it should be. As a result, smaller buffer is allocated for picture scaling and thus buffer overflow occurs. Strange thing is that this bug has not appeared earlier so it probably has something to do with newer gcc or glibc (I switch from "prehistoric" Fedora Core 5 to Fedora 12). There were several ones, probably depending on application version and compilation flags. First, it just stopped responding. Looking at the process with strace I saw it locked in some FUTEX wait (unfortunately I don't have the logs). Second, it just crashed. And last I got complaint from glibc about double free or corrupted heap before malloc. I've found the bug through wmweather+ dockapp, versions 2.9 and 2.11 (http://sourceforge.net/projects/wmweatherplus/), I've never encountered it in WindowMaker itself. --- wrlib/scale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wrlib/scale.c b/wrlib/scale.c index 7e490744..0ff683f9 100644 --- a/wrlib/scale.c +++ b/wrlib/scale.c @@ -327,7 +327,7 @@ RImage *RSmoothScaleImage(RImage * src, unsigned new_width, unsigned new_height) fscale = 1.0 / xscale; for (i = 0; i < new_width; ++i) { contrib[i].n = 0; - contrib[i].p = (CONTRIB *) calloc((int)(width * 2 + 1), sizeof(CONTRIB)); + contrib[i].p = (CONTRIB *) calloc((int) ceil(width * 2 + 1), sizeof(CONTRIB)); center = (double)i / xscale; left = ceil(center - width); right = floor(center + width); @@ -350,7 +350,7 @@ RImage *RSmoothScaleImage(RImage * src, unsigned new_width, unsigned new_height) for (i = 0; i < new_width; ++i) { contrib[i].n = 0; - contrib[i].p = (CONTRIB *) calloc((int)(fwidth * 2 + 1), sizeof(CONTRIB)); + contrib[i].p = (CONTRIB *) calloc((int) ceil(fwidth * 2 + 1), sizeof(CONTRIB)); center = (double)i / xscale; left = ceil(center - fwidth); right = floor(center + fwidth); @@ -408,7 +408,7 @@ RImage *RSmoothScaleImage(RImage * src, unsigned new_width, unsigned new_height) fscale = 1.0 / yscale; for (i = 0; i < dst->height; ++i) { contrib[i].n = 0; - contrib[i].p = (CONTRIB *) calloc((int)(width * 2 + 1), sizeof(CONTRIB)); + contrib[i].p = (CONTRIB *) calloc((int) ceil(width * 2 + 1), sizeof(CONTRIB)); center = (double)i / yscale; left = ceil(center - width); right = floor(center + width); @@ -430,7 +430,7 @@ RImage *RSmoothScaleImage(RImage * src, unsigned new_width, unsigned new_height) } else { for (i = 0; i < dst->height; ++i) { contrib[i].n = 0; - contrib[i].p = (CONTRIB *) calloc((int)(fwidth * 2 + 1), sizeof(CONTRIB)); + contrib[i].p = (CONTRIB *) calloc((int) ceil(fwidth * 2 + 1), sizeof(CONTRIB)); center = (double)i / yscale; left = ceil(center - fwidth); right = floor(center + fwidth); -- 2.11.4.GIT