summaryrefslogtreecommitdiff
path: root/src/Filter.c
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-04-12 22:45:20 -0700
committerAlan Coopersmith <alan.coopersmith@oracle.com>2013-05-03 23:07:14 -0700
commite52853974664289fe42a92909667ed77cfa1cec5 (patch)
treedb24bf819f88918b61cf20d19c193bcf49ce2411 /src/Filter.c
parent73e77eb21d649edc1ce1746739f9358e337b2935 (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>
Diffstat (limited to 'src/Filter.c')
-rw-r--r--src/Filter.c39
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)
{