aboutsummaryrefslogtreecommitdiffstats
path: root/main/libxi/0004-Stack-buffer-overflow-in-XGetDeviceButtonMapping-CVE.patch
blob: c42dbd13f93ff730aa8faf4fa4ead845f608f018 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
From 4384e622471dbdab88dd5dae28f9eecbfe79ddd8 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Sat, 9 Mar 2013 22:26:52 -0800
Subject: [PATCH 04/16] 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)
(cherry picked from commit d7537ad6fba36af4536c576220c135a63507789c)
---
 src/XGetBMap.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/XGetBMap.c b/src/XGetBMap.c
index 610795b..a37c714 100644
--- a/src/XGetBMap.c
+++ b/src/XGetBMap.c
@@ -56,6 +56,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
@@ -71,7 +72,6 @@ XGetDeviceButtonMapping(
 {
     int status = 0;
     unsigned char mapping[256];	/* known fixed size */
-    long nbytes;
     XExtDisplayInfo *info = XInput_find_display(dpy);
 
     register xGetDeviceButtonMappingReq *req;
@@ -88,13 +88,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);
-- 
1.7.7.1