aboutsummaryrefslogtreecommitdiffstats
path: root/main/libxi/0006-unvalidated-lengths-in-XQueryDeviceState-CVE-2013-19.patch
blob: 7b8680a6d45d0a3905abf9c61df1890bdf8bb2eb (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
69
70
From ba6b8bc3413b4818d5c507421193eaa63e8a1ebe Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Fri, 26 Apr 2013 22:48:36 -0700
Subject: [PATCH 06/16] unvalidated lengths in XQueryDeviceState()
 [CVE-2013-1998 3/3]

If the lengths given for each class state in the reply add up to more
than the rep.length, we could read past the end of the buffer allocated
to hold the data read from the server.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit 5398ac0797f7516f2c9b8f2869a6c6d071437352)
(cherry picked from commit 2736e93eb52109e5bab5bd14395142cc750f2614)
---
 src/XQueryDv.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/XQueryDv.c b/src/XQueryDv.c
index 9ef0190..e9cdc55 100644
--- a/src/XQueryDv.c
+++ b/src/XQueryDv.c
@@ -56,6 +56,7 @@ SOFTWARE.
 #include <X11/extensions/XInput.h>
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
+#include <limits.h>
 
 XDeviceState *
 XQueryDeviceState(
@@ -63,8 +64,8 @@ XQueryDeviceState(
     XDevice		*dev)
 {
     int i, j;
-    int rlen;
-    int size = 0;
+    unsigned long rlen;
+    size_t size = 0;
     xQueryDeviceStateReq *req;
     xQueryDeviceStateReply rep;
     XDeviceState *state = NULL;
@@ -84,9 +85,11 @@ XQueryDeviceState(
     if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
         goto out;
 
-    rlen = rep.length << 2;
-    if (rlen > 0) {
-	data = Xmalloc(rlen);
+    if (rep.length > 0) {
+	if (rep.length < (INT_MAX >> 2)) {
+	    rlen = (unsigned long) rep.length << 2;
+	    data = Xmalloc(rlen);
+	}
 	if (!data) {
 	    _XEatDataWords(dpy, rep.length);
 	    goto out;
@@ -94,6 +97,10 @@ XQueryDeviceState(
 	_XRead(dpy, data, rlen);
 
 	for (i = 0, any = (XInputClass *) data; i < (int)rep.num_classes; i++) {
+	    if (any->length > rlen)
+		goto out;
+	    rlen -= any->length;
+
 	    switch (any->class) {
 	    case KeyClass:
 		size += sizeof(XKeyState);
-- 
1.7.7.1