diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2013-03-09 22:26:52 -0800 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-05-24 11:46:37 +1000 |
commit | d7537ad6fba36af4536c576220c135a63507789c (patch) | |
tree | 957125142afad676e102f4ec630f192c31a7b30f | |
parent | 4579fadd11883c62db486ecc64c40342c2ab5506 (diff) |
Stack buffer overflow in XGetDeviceButtonMapping() [CVE-2013-1998 1/3]
We copy the entire reply sent by the server into the fixed size
mapping[] array on the stack, even if the server says it's a larger
size than the mapping array can hold. HULK SMASH STACK!
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit f3e08e4fbe40016484ba795feecf1a742170ffc1)
-rw-r--r-- | src/XGetBMap.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/src/XGetBMap.c b/src/XGetBMap.c index 211c9ca..002daba 100644 --- a/src/XGetBMap.c +++ b/src/XGetBMap.c @@ -60,6 +60,7 @@ SOFTWARE. #include <X11/extensions/XInput.h> #include <X11/extensions/extutil.h> #include "XIint.h" +#include <limits.h> #ifdef MIN /* some systems define this in <sys/param.h> */ #undef MIN @@ -75,7 +76,6 @@ XGetDeviceButtonMapping( { int status = 0; unsigned char mapping[256]; /* known fixed size */ - long nbytes; XExtDisplayInfo *info = XInput_find_display(dpy); register xGetDeviceButtonMappingReq *req; @@ -92,13 +92,18 @@ XGetDeviceButtonMapping( status = _XReply(dpy, (xReply *) & rep, 0, xFalse); if (status == 1) { - nbytes = (long)rep.length << 2; - _XRead(dpy, (char *)mapping, nbytes); - - /* don't return more data than the user asked for. */ - if (rep.nElts) - memcpy((char *)map, (char *)mapping, MIN((int)rep.nElts, nmap)); - status = rep.nElts; + if (rep.length <= (sizeof(mapping) >> 2)) { + unsigned long nbytes = rep.length << 2; + _XRead(dpy, (char *)mapping, nbytes); + + /* don't return more data than the user asked for. */ + if (rep.nElts) + memcpy(map, mapping, MIN((int)rep.nElts, nmap)); + status = rep.nElts; + } else { + _XEatDataWords(dpy, rep.length); + status = 0; + } } else status = 0; UnlockDisplay(dpy); |