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 f51b6a628679cad8e116fa4380ea7fb492b91901 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith@oracle.com>
Date: Sat, 9 Mar 2013 22:55:23 -0800
Subject: [PATCH 10/16] integer overflow in XGetDeviceMotionEvents()
[CVE-2013-1984 4/8]
If the number of events or axes 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 copied from the
X server reply than the size of the buffer we allocated to hold them.
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 bb922ed4253b35590f0369f32a917ff89ade0830)
(cherry picked from commit b273909309cfdde0369ee728b17c15984eb84e49)
---
src/XGMotion.c | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/XGMotion.c b/src/XGMotion.c
index f3b6751..def83a1 100644
--- a/src/XGMotion.c
+++ b/src/XGMotion.c
@@ -56,6 +56,7 @@ SOFTWARE.
#include <X11/extensions/XInput.h>
#include <X11/extensions/extutil.h>
#include "XIint.h"
+#include <limits.h>
XDeviceTimeCoord *
XGetDeviceMotionEvents(
@@ -71,7 +72,7 @@ XGetDeviceMotionEvents(
xGetDeviceMotionEventsReply rep;
XDeviceTimeCoord *tc;
int *data, *bufp, *readp, *savp;
- long size, size2;
+ unsigned long size;
int i, j;
XExtDisplayInfo *info = XInput_find_display(dpy);
@@ -101,10 +102,21 @@ XGetDeviceMotionEvents(
SyncHandle();
return (NULL);
}
- size = rep.length << 2;
- size2 = rep.nEvents * (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
- savp = readp = (int *)Xmalloc(size);
- bufp = (int *)Xmalloc(size2);
+ if (rep.length < (INT_MAX >> 2)) {
+ size = rep.length << 2;
+ savp = readp = Xmalloc(size);
+ } else {
+ size = 0;
+ savp = readp = NULL;
+ }
+ /* rep.axes is a CARD8, so assume max number of axes for bounds check */
+ if (rep.nEvents <
+ (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int))))) {
+ size_t bsize = rep.nEvents *
+ (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
+ bufp = Xmalloc(bsize);
+ } else
+ bufp = NULL;
if (!bufp || !savp) {
Xfree(bufp);
Xfree(savp);
--
1.7.7.1
|