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
|
From e52853974664289fe42a92909667ed77cfa1cec5 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Sat, 13 Apr 2013 05:45:20 +0000
Subject: integer overflow in XRenderQueryFilters() [CVE-2013-1987 1/3]
The length, numFilters & numAliases members of the reply are all CARD32
and need to be bounds checked before multiplying & adding them together
to come up with the total size to allocate, to avoid integer overflow
leading to underallocation and writing data from the network past the
end of the allocated buffer.
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
---
diff --git a/src/Filter.c b/src/Filter.c
index 924b2a3..edfa572 100644
--- a/src/Filter.c
+++ b/src/Filter.c
@@ -25,6 +25,7 @@
#include <config.h>
#endif
#include "Xrenderint.h"
+#include <limits.h>
XFilters *
XRenderQueryFilters (Display *dpy, Drawable drawable)
@@ -37,7 +38,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
char *name;
char len;
int i;
- long nbytes, nbytesAlias, nbytesName;
+ unsigned long nbytes, nbytesAlias, nbytesName;
if (!RenderHasExtension (info))
return NULL;
@@ -60,22 +61,32 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
SyncHandle ();
return NULL;
}
- /*
- * Compute total number of bytes for filter names
- */
- nbytes = (long)rep.length << 2;
- nbytesAlias = rep.numAliases * 2;
- if (rep.numAliases & 1)
- nbytesAlias += 2;
- nbytesName = nbytes - nbytesAlias;
/*
- * Allocate one giant block for the whole data structure
+ * Limit each component of combined size to 1/4 the max, which is far
+ * more than they should ever possibly need.
*/
- filters = Xmalloc (sizeof (XFilters) +
- rep.numFilters * sizeof (char *) +
- rep.numAliases * sizeof (short) +
- nbytesName);
+ if ((rep.length < (INT_MAX >> 2)) &&
+ (rep.numFilters < ((INT_MAX / 4) / sizeof (char *))) &&
+ (rep.numAliases < ((INT_MAX / 4) / sizeof (short)))) {
+ /*
+ * Compute total number of bytes for filter names
+ */
+ nbytes = (unsigned long)rep.length << 2;
+ nbytesAlias = rep.numAliases * 2;
+ if (rep.numAliases & 1)
+ nbytesAlias += 2;
+ nbytesName = nbytes - nbytesAlias;
+
+ /*
+ * Allocate one giant block for the whole data structure
+ */
+ filters = Xmalloc (sizeof (XFilters) +
+ (rep.numFilters * sizeof (char *)) +
+ (rep.numAliases * sizeof (short)) +
+ nbytesName);
+ } else
+ filters = NULL;
if (!filters)
{
--
cgit v0.9.0.2-2-gbebe
|