summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2016-09-25 21:42:09 +0200
committerMatthieu Herrb <matthieu@herrb.eu>2016-09-25 22:14:27 +0200
commit8fad00b0b647ee662ce4737ca15be033b7a21714 (patch)
treedefc41b75d44d03839779cd43a72288efc3ee004 /src
parentb2df5bc42f64b45e44dbad61f3386bcb5ec1383d (diff)
downloadxorg-lib-libXrender-8fad00b0b647ee662ce4737ca15be033b7a21714.tar.gz
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. v2: consume remaining bytes in reply buffer on error. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
Diffstat (limited to 'src')
-rw-r--r--src/Filter.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/Filter.c b/src/Filter.c
index edfa572..8d701eb 100644
--- a/src/Filter.c
+++ b/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;
}