summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2016-10-04 15:03:49 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2016-10-04 15:03:49 +0000
commita2ee4c357e901e111f8dbfb940342581aeed2df1 (patch)
treedd894d1d99672bb51b19979591bf0de9864a69ac
parent9609ef3e8cf0c5b70bab5f2f1ecfbd7eeab26abc (diff)
Avoid OOB write in XRenderQueryFilters
The memory for filter names is reserved right after receiving the reply. After that, filters are iterated and each individual filter name is stored in that reserved memory. The individual name lengths are not checked for validity, which means that a malicious server can reserve less memory than it will write to during each iteration. From Tobias Stoeckmann / X.Org security advisory Oct 4, 2016
-rw-r--r--lib/libXrender/src/Filter.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/lib/libXrender/src/Filter.c b/lib/libXrender/src/Filter.c
index edfa57231..8d701eb98 100644
--- a/lib/libXrender/src/Filter.c
+++ b/lib/libXrender/src/Filter.c
@@ -38,7 +38,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
char *name;
char len;
int i;
- unsigned long nbytes, nbytesAlias, nbytesName;
+ unsigned long nbytes, nbytesAlias, nbytesName, reply_left;
if (!RenderHasExtension (info))
return NULL;
@@ -114,6 +114,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
* Read the filter aliases
*/
_XRead16Pad (dpy, filters->alias, 2 * rep.numAliases);
+ reply_left = 8 + rep.length - 2 * rep.numAliases;;
/*
* Read the filter names
@@ -122,9 +123,19 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
{
int l;
_XRead (dpy, &len, 1);
+ reply_left--;
l = len & 0xff;
+ if ((unsigned long)l + 1 > nbytesName) {
+ _XEatDataWords(dpy, reply_left);
+ Xfree(filters);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ nbytesName -= l + 1;
filters->filter[i] = name;
_XRead (dpy, name, l);
+ reply_left -= l;
name[l] = '\0';
name += l + 1;
}