diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-04-12 22:45:20 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-05-03 23:07:14 -0700 |
commit | e52853974664289fe42a92909667ed77cfa1cec5 (patch) | |
tree | db24bf819f88918b61cf20d19c193bcf49ce2411 | |
parent | 73e77eb21d649edc1ce1746739f9358e337b2935 (diff) |
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 <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | src/Filter.c | 39 |
1 files 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 <config.h> #endif #include "Xrenderint.h" +#include <limits.h> 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) { |