summaryrefslogtreecommitdiffstats
path: root/main/libxext/0007-integer-overflow-in-XSyncListSystemCounters-CVE-2013.patch
blob: 95382256d1a5d16cb6302c008d3a7d351a9fd242 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
From dfe6e1f3b8ede3d0bab7a5fa57f73513a09ec649 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Sat, 9 Mar 2013 14:40:33 -0800
Subject: [PATCH 7/7] integer overflow in XSyncListSystemCounters()
 [CVE-2013-1982 6/6]

If the number of counters or amount of data reported by the server is
large enough that it overflows when multiplied by the size of the
appropriate struct, then memory corruption can occur when more bytes
are read from the X server than the size of the buffers we allocated
to hold them.

V2: Make sure we don't walk past the end of the reply when converting
data from wire format to the structures returned to the caller.

Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
---
 src/XSync.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/XSync.c b/src/XSync.c
index 3ca1308..ce4ab44 100644
--- a/src/XSync.c
+++ b/src/XSync.c
@@ -59,6 +59,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/extutil.h>
 #include <X11/extensions/sync.h>
 #include <X11/extensions/syncproto.h>
+#include <limits.h>
 #include "eat.h"
 
 static XExtensionInfo _sync_info_data;
@@ -352,19 +353,28 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
     if (rep.nCounters > 0)
     {
 	xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter;
+	xSyncSystemCounter *pLastWireSysCounter;
 	XSyncCounter counter;
-	int replylen;
+	unsigned int replylen;
 	int i;
 
-	list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
-	replylen = rep.length << 2;
-	pWireSysCounter = Xmalloc ((unsigned) replylen + sizeof(XSyncCounter));
-        /* +1 to leave room for last counter read-ahead */
+	if (rep.nCounters < (INT_MAX / sizeof(XSyncSystemCounter)))
+	    list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
+	if (rep.length < (INT_MAX >> 2)) {
+	    replylen = rep.length << 2;
+	    pWireSysCounter = Xmalloc (replylen + sizeof(XSyncCounter));
+	    /* +1 to leave room for last counter read-ahead */
+	    pLastWireSysCounter = (xSyncSystemCounter *)
+		((char *)pWireSysCounter) + replylen;
+	} else {
+	    replylen = 0;
+	    pWireSysCounter = NULL;
+	}
 
 	if ((!list) || (!pWireSysCounter))
 	{
-	    if (list) Xfree((char *) list);
-	    if (pWireSysCounter)   Xfree((char *) pWireSysCounter);
+	    Xfree(list);
+	    Xfree(pWireSysCounter);
 	    _XEatDataWords(dpy, rep.length);
 	    list = NULL;
 	    goto bail;
@@ -388,6 +398,14 @@ XSyncListSystemCounters(Display *dpy, int *n_counters_return)
 	    pNextWireSysCounter = (xSyncSystemCounter *)
 		(((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
 				     pWireSysCounter->name_length + 3) & ~3));
+	    /* Make sure we haven't gone too far */
+	    if (pNextWireSysCounter > pLastWireSysCounter) {
+		Xfree(list);
+		Xfree(pWireSysCounter);
+		list = NULL;
+		goto bail;
+	    }
+
 	    counter = pNextWireSysCounter->counter;
 
 	    list[i].name = ((char *)pWireSysCounter) +
-- 
1.8.2.3