1 From d7b2f5c06259c7e6ba037909adec4c2a5a8b15ec Mon Sep 17 00:00:00 2001
2 From: Alan Coopersmith <alan.coopersmith@oracle.com>
3 Date: Wed, 22 Jan 2014 22:37:15 -0800
4 Subject: [PATCH 04/33] dix: integer overflow in RegionSizeof() [CVE-2014-8092
7 RegionSizeof contains several integer overflows if a large length
8 value is passed in. Once we fix it to return 0 on overflow, we
9 also have to fix the callers to handle this error condition
11 v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau.
13 Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
14 Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
15 Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
16 Reviewed-by: Julien Cristau <jcristau@debian.org>
18 dix/region.c | 20 +++++++++++++-------
19 include/regionstr.h | 10 +++++++---
20 2 files changed, 20 insertions(+), 10 deletions(-)
22 Index: xorg-server-1.15.1/dix/region.c
23 ===================================================================
24 --- xorg-server-1.15.1.orig/dix/region.c 2014-12-05 08:24:42.034665485 -0500
25 +++ xorg-server-1.15.1/dix/region.c 2014-12-05 08:24:42.030665458 -0500
27 ((r1)->y1 <= (r2)->y1) && \
28 ((r1)->y2 >= (r2)->y2) )
30 -#define xallocData(n) malloc(RegionSizeof(n))
31 #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
33 #define RECTALLOC_BAIL(pReg,n,bail) \
35 #define DOWNSIZE(reg,numRects) \
36 if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
38 - RegDataPtr NewData; \
39 - NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects)); \
40 + size_t NewSize = RegionSizeof(numRects); \
41 + RegDataPtr NewData = \
42 + (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ; \
45 NewData->size = (numRects); \
47 RegionRectAlloc(RegionPtr pRgn, int n)
54 - pRgn->data = xallocData(n);
55 + rgnSize = RegionSizeof(n);
56 + pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
58 return RegionBreak(pRgn);
59 pRgn->data->numRects = 1;
60 *RegionBoxptr(pRgn) = pRgn->extents;
62 else if (!pRgn->data->size) {
63 - pRgn->data = xallocData(n);
64 + rgnSize = RegionSizeof(n);
65 + pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
67 return RegionBreak(pRgn);
68 pRgn->data->numRects = 0;
72 n += pRgn->data->numRects;
73 - data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
74 + rgnSize = RegionSizeof(n);
75 + data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
77 return RegionBreak(pRgn);
91 - pData = xallocData(nrects);
92 + rgnSize = RegionSizeof(nrects);
93 + pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
97 Index: xorg-server-1.15.1/include/regionstr.h
98 ===================================================================
99 --- xorg-server-1.15.1.orig/include/regionstr.h 2014-12-05 08:24:42.034665485 -0500
100 +++ xorg-server-1.15.1/include/regionstr.h 2014-12-05 08:24:42.030665458 -0500
103 RegionSizeof(size_t n)
105 - return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
106 + if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
107 + return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
114 (_pReg)->data = (RegDataPtr) NULL;
118 (_pReg)->extents = RegionEmptyBox;
119 - if (((_size) > 1) && ((_pReg)->data =
120 - (RegDataPtr) malloc(RegionSizeof(_size)))) {
121 + if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
122 + (((_pReg)->data = malloc(rgnSize)) != NULL)) {
123 (_pReg)->data->size = (_size);
124 (_pReg)->data->numRects = 0;