dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4]

RegionSizeof contains several integer overflows if a large length
value is passed in.  Once we fix it to return 0 on overflow, we
also have to fix the callers to handle this error condition

v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau.

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>
Reviewed-by: Julien Cristau <jcristau@debian.org>
This commit is contained in:
Alan Coopersmith 2014-01-22 22:37:15 -08:00
parent bc8e20430b
commit 97015a07b9
2 changed files with 20 additions and 10 deletions

View File

@ -169,7 +169,6 @@ Equipment Corporation.
((r1)->y1 <= (r2)->y1) && \
((r1)->y2 >= (r2)->y2) )
#define xallocData(n) malloc(RegionSizeof(n))
#define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
#define RECTALLOC_BAIL(pReg,n,bail) \
@ -205,8 +204,9 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
#define DOWNSIZE(reg,numRects) \
if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
{ \
RegDataPtr NewData; \
NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects)); \
size_t NewSize = RegionSizeof(numRects); \
RegDataPtr NewData = \
(NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ; \
if (NewData) \
{ \
NewData->size = (numRects); \
@ -345,17 +345,20 @@ Bool
RegionRectAlloc(RegionPtr pRgn, int n)
{
RegDataPtr data;
size_t rgnSize;
if (!pRgn->data) {
n++;
pRgn->data = xallocData(n);
rgnSize = RegionSizeof(n);
pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pRgn->data)
return RegionBreak(pRgn);
pRgn->data->numRects = 1;
*RegionBoxptr(pRgn) = pRgn->extents;
}
else if (!pRgn->data->size) {
pRgn->data = xallocData(n);
rgnSize = RegionSizeof(n);
pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pRgn->data)
return RegionBreak(pRgn);
pRgn->data->numRects = 0;
@ -367,7 +370,8 @@ RegionRectAlloc(RegionPtr pRgn, int n)
n = 250;
}
n += pRgn->data->numRects;
data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n));
rgnSize = RegionSizeof(n);
data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
if (!data)
return RegionBreak(pRgn);
pRgn->data = data;
@ -1312,6 +1316,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
{
RegionPtr pRgn;
size_t rgnSize;
RegDataPtr pData;
BoxPtr pBox;
int i;
@ -1338,7 +1343,8 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
}
return pRgn;
}
pData = xallocData(nrects);
rgnSize = RegionSizeof(nrects);
pData = (rgnSize > 0) ? malloc(rgnSize) : NULL;
if (!pData) {
RegionBreak(pRgn);
return pRgn;

View File

@ -127,7 +127,10 @@ RegionEnd(RegionPtr reg)
static inline size_t
RegionSizeof(size_t n)
{
return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec)))
return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
else
return 0;
}
static inline void
@ -138,9 +141,10 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
(_pReg)->data = (RegDataPtr) NULL;
}
else {
size_t rgnSize;
(_pReg)->extents = RegionEmptyBox;
if (((_size) > 1) && ((_pReg)->data =
(RegDataPtr) malloc(RegionSizeof(_size)))) {
if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) &&
(((_pReg)->data = malloc(rgnSize)) != NULL)) {
(_pReg)->data->size = (_size);
(_pReg)->data->numRects = 0;
}