Blame SOURCES/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch

0fd959
From eb6ed19fb89996cf630259ba474c186d35993799 Mon Sep 17 00:00:00 2001
0fd959
From: Alan Coopersmith <alan.coopersmith@oracle.com>
0fd959
Date: Wed, 22 Jan 2014 22:37:15 -0800
0fd959
Subject: [PATCH 04/33] dix: integer overflow in RegionSizeof() [CVE-2014-8092
0fd959
 3/4]
0fd959
0fd959
RegionSizeof contains several integer overflows if a large length
0fd959
value is passed in.  Once we fix it to return 0 on overflow, we
0fd959
also have to fix the callers to handle this error condition
0fd959
0fd959
v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau.
0fd959
0fd959
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
0fd959
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
0fd959
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
0fd959
Reviewed-by: Julien Cristau <jcristau@debian.org>
0fd959
Signed-off-by: Fedora X Ninjas <x@fedoraproject.org>
0fd959
---
0fd959
 dix/region.c        | 20 +++++++++++++-------
0fd959
 include/regionstr.h | 10 +++++++---
0fd959
 2 files changed, 20 insertions(+), 10 deletions(-)
0fd959
0fd959
diff --git a/dix/region.c b/dix/region.c
0fd959
index 15f3d01..e5eed01 100644
0fd959
--- a/dix/region.c
0fd959
+++ b/dix/region.c
0fd959
@@ -169,7 +169,6 @@ Equipment Corporation.
0fd959
         ((r1)->y1 <= (r2)->y1) && \
0fd959
         ((r1)->y2 >= (r2)->y2) )
0fd959
 
0fd959
-#define xallocData(n) malloc(RegionSizeof(n))
0fd959
 #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
0fd959
 
0fd959
 #define RECTALLOC_BAIL(pReg,n,bail) \
0fd959
@@ -205,8 +204,9 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
0fd959
 #define DOWNSIZE(reg,numRects)						 \
0fd959
 if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
0fd959
 {									 \
0fd959
-    RegDataPtr NewData;							 \
0fd959
-    NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects));	 \
0fd959
+    size_t NewSize = RegionSizeof(numRects);				 \
0fd959
+    RegDataPtr NewData =						 \
0fd959
+        (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ;		 \
0fd959
     if (NewData)							 \
0fd959
     {									 \
0fd959
 	NewData->size = (numRects);					 \
0fd959
@@ -345,17 +345,20 @@ Bool
0fd959
 RegionRectAlloc(RegionPtr pRgn, int n)
0fd959
 {
0fd959
     RegDataPtr data;
0fd959
+    size_t rgnSize;
0fd959
 
0fd959
     if (!pRgn->data) {
0fd959
         n++;
0fd959
-        pRgn->data = xallocData(n);
0fd959
+        rgnSize = RegionSizeof(n);
0fd959
+        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
0fd959
         if (!pRgn->data)
0fd959
             return RegionBreak(pRgn);
0fd959
         pRgn->data->numRects = 1;
0fd959
         *RegionBoxptr(pRgn) = pRgn->extents;
0fd959
     }
0fd959
     else if (!pRgn->data->size) {
0fd959
-        pRgn->data = xallocData(n);
0fd959
+        rgnSize = RegionSizeof(n);
0fd959
+        pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
0fd959
         if (!pRgn->data)
0fd959
             return RegionBreak(pRgn);
0fd959
         pRgn->data->numRects = 0;
0fd959
@@ -367,7 +370,8 @@ RegionRectAlloc(RegionPtr pRgn, int n)
0fd959
                 n = 250;
0fd959
         }
0fd959
         n += pRgn->data->numRects;
0fd959
-        data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
0fd959
+        rgnSize = RegionSizeof(n);
0fd959
+        data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
0fd959
         if (!data)
0fd959
             return RegionBreak(pRgn);
0fd959
         pRgn->data = data;
0fd959
@@ -1312,6 +1316,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
0fd959
 {
0fd959
 
0fd959
     RegionPtr pRgn;
0fd959
+    size_t rgnSize;
0fd959
     RegDataPtr pData;
0fd959
     BoxPtr pBox;
0fd959
     int i;
0fd959
@@ -1338,7 +1343,8 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
0fd959
         }
0fd959
         return pRgn;
0fd959
     }
0fd959
-    pData = xallocData(nrects);
0fd959
+    rgnSize = RegionSizeof(nrects);
0fd959
+    pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
0fd959
     if (!pData) {
0fd959
         RegionBreak(pRgn);
0fd959
         return pRgn;
0fd959
diff --git a/include/regionstr.h b/include/regionstr.h
0fd959
index 4a0725d..33df87f 100644
0fd959
--- a/include/regionstr.h
0fd959
+++ b/include/regionstr.h
0fd959
@@ -127,7 +127,10 @@ RegionEnd(RegionPtr reg)
0fd959
 static inline size_t
0fd959
 RegionSizeof(int n)
0fd959
 {
0fd959
-    return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
0fd959
+    if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
0fd959
+        return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
0fd959
+    else
0fd959
+        return 0;
0fd959
 }
0fd959
 
0fd959
 static inline void
0fd959
@@ -138,9 +141,10 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
0fd959
         (_pReg)->data = (RegDataPtr) NULL;
0fd959
     }
0fd959
     else {
0fd959
+        size_t rgnSize;
0fd959
         (_pReg)->extents = RegionEmptyBox;
0fd959
-        if (((_size) > 1) && ((_pReg)->data =
0fd959
-                              (RegDataPtr) malloc(RegionSizeof(_size)))) {
0fd959
+        if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
0fd959
+            (((_pReg)->data = malloc(rgnSize)) != NULL)) {
0fd959
             (_pReg)->data->size = (_size);
0fd959
             (_pReg)->data->numRects = 0;
0fd959
         }
0fd959
-- 
0fd959
1.9.3
0fd959