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:
parent
bc8e20430b
commit
97015a07b9
20
dix/region.c
20
dix/region.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue