summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2013-03-09 22:26:52 -0800
committerPeter Hutterer <peter.hutterer@who-t.net>2013-05-24 11:46:37 +1000
commitd7537ad6fba36af4536c576220c135a63507789c (patch)
tree957125142afad676e102f4ec630f192c31a7b30f
parent4579fadd11883c62db486ecc64c40342c2ab5506 (diff)
downloadxorg-lib-libXi-d7537ad6fba36af4536c576220c135a63507789c.tar.gz
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.c21
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);