Commit 985ca320 authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Mike Gabriel

dbe: unvalidated lengths in DbeSwapBuffers calls [CVE-2014-8097]

ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read from a buffer. The length is never validated, which can lead to out of bound reads, and possibly returning the data read from out of bounds to the misbehaving client via an X Error packet. SProcDbeSwapBuffers() swaps data (for correct endianness) before handing it off to the real proc. While doing the swapping, the length field is not validated, which can cause memory corruption. v2: reorder checks to avoid compilers optimizing out checks for overflow that happen after we'd already have done the overflowing multiplications. v3: backport to nx-libs 3.6.x (Mike DePaulo) Reported-by: 's avatarIlja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Reviewed-by: 's avatarPeter Hutterer <peter.hutterer@who-t.net> Conflicts: dbe/dbe.c
parent 82d7279e
...@@ -725,8 +725,8 @@ ProcDbeSwapBuffers(client) ...@@ -725,8 +725,8 @@ ProcDbeSwapBuffers(client)
DbeSwapInfoPtr swapInfo; DbeSwapInfoPtr swapInfo;
xDbeSwapInfo *dbeSwapInfo; xDbeSwapInfo *dbeSwapInfo;
int error; int error;
register int i, j; unsigned int i, j;
int nStuff; unsigned int nStuff;
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
...@@ -734,11 +734,13 @@ ProcDbeSwapBuffers(client) ...@@ -734,11 +734,13 @@ ProcDbeSwapBuffers(client)
if (nStuff == 0) if (nStuff == 0)
{ {
REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
return(Success); return(Success);
} }
if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
return BadAlloc; return BadAlloc;
REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
/* Get to the swap info appended to the end of the request. */ /* Get to the swap info appended to the end of the request. */
dbeSwapInfo = (xDbeSwapInfo *)&stuff[1]; dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
...@@ -1289,7 +1291,7 @@ SProcDbeSwapBuffers(client) ...@@ -1289,7 +1291,7 @@ SProcDbeSwapBuffers(client)
ClientPtr client; ClientPtr client;
{ {
REQUEST(xDbeSwapBuffersReq); REQUEST(xDbeSwapBuffersReq);
register int i, n; unsigned int i, n;
xDbeSwapInfo *pSwapInfo; xDbeSwapInfo *pSwapInfo;
...@@ -1297,6 +1299,9 @@ SProcDbeSwapBuffers(client) ...@@ -1297,6 +1299,9 @@ SProcDbeSwapBuffers(client)
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
swapl(&stuff->n, n); swapl(&stuff->n, n);
if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
return BadAlloc;
REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
if (stuff->n != 0) if (stuff->n != 0)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment