From e52853974664289fe42a92909667ed77cfa1cec5 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 12 Apr 2013 22:45:20 -0700 Subject: integer overflow in XRenderQueryFilters() [CVE-2013-1987 1/3] The length, numFilters & numAliases members of the reply are all CARD32 and need to be bounds checked before multiplying & adding them together to come up with the total size to allocate, to avoid integer overflow leading to underallocation and writing data from the network past the end of the allocated buffer. Reported-by: Ilja Van Sprundel Signed-off-by: Alan Coopersmith --- src/Filter.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Filter.c b/src/Filter.c index 924b2a3..edfa572 100644 --- a/src/Filter.c +++ b/src/Filter.c @@ -25,6 +25,7 @@ #include #endif #include "Xrenderint.h" +#include XFilters * XRenderQueryFilters (Display *dpy, Drawable drawable) @@ -37,7 +38,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable) char *name; char len; int i; - long nbytes, nbytesAlias, nbytesName; + unsigned long nbytes, nbytesAlias, nbytesName; if (!RenderHasExtension (info)) return NULL; @@ -60,22 +61,32 @@ XRenderQueryFilters (Display *dpy, Drawable drawable) SyncHandle (); return NULL; } - /* - * Compute total number of bytes for filter names - */ - nbytes = (long)rep.length << 2; - nbytesAlias = rep.numAliases * 2; - if (rep.numAliases & 1) - nbytesAlias += 2; - nbytesName = nbytes - nbytesAlias; /* - * Allocate one giant block for the whole data structure + * Limit each component of combined size to 1/4 the max, which is far + * more than they should ever possibly need. */ - filters = Xmalloc (sizeof (XFilters) + - rep.numFilters * sizeof (char *) + - rep.numAliases * sizeof (short) + - nbytesName); + if ((rep.length < (INT_MAX >> 2)) && + (rep.numFilters < ((INT_MAX / 4) / sizeof (char *))) && + (rep.numAliases < ((INT_MAX / 4) / sizeof (short)))) { + /* + * Compute total number of bytes for filter names + */ + nbytes = (unsigned long)rep.length << 2; + nbytesAlias = rep.numAliases * 2; + if (rep.numAliases & 1) + nbytesAlias += 2; + nbytesName = nbytes - nbytesAlias; + + /* + * Allocate one giant block for the whole data structure + */ + filters = Xmalloc (sizeof (XFilters) + + (rep.numFilters * sizeof (char *)) + + (rep.numAliases * sizeof (short)) + + nbytesName); + } else + filters = NULL; if (!filters) { -- cgit v1.2.3