|
|
0fd959 |
From 5c37a8a720a39c881fe8e5ee59de1e570f9ce01d Mon Sep 17 00:00:00 2001
|
|
|
0fd959 |
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
|
0fd959 |
Date: Wed, 22 Jan 2014 23:12:04 -0800
|
|
|
0fd959 |
Subject: [PATCH 07/33] dbe: unvalidated lengths in DbeSwapBuffers calls
|
|
|
0fd959 |
[CVE-2014-8097]
|
|
|
0fd959 |
|
|
|
0fd959 |
ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read
|
|
|
0fd959 |
from a buffer. The length is never validated, which can lead to out of
|
|
|
0fd959 |
bound reads, and possibly returning the data read from out of bounds to
|
|
|
0fd959 |
the misbehaving client via an X Error packet.
|
|
|
0fd959 |
|
|
|
0fd959 |
SProcDbeSwapBuffers() swaps data (for correct endianness) before
|
|
|
0fd959 |
handing it off to the real proc. While doing the swapping, the
|
|
|
0fd959 |
length field is not validated, which can cause memory corruption.
|
|
|
0fd959 |
|
|
|
0fd959 |
v2: reorder checks to avoid compilers optimizing out checks for overflow
|
|
|
0fd959 |
that happen after we'd already have done the overflowing multiplications.
|
|
|
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 |
Signed-off-by: Fedora X Ninjas <x@fedoraproject.org>
|
|
|
0fd959 |
---
|
|
|
0fd959 |
dbe/dbe.c | 11 ++++++++---
|
|
|
0fd959 |
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
0fd959 |
|
|
|
0fd959 |
diff --git a/dbe/dbe.c b/dbe/dbe.c
|
|
|
0b0bd3 |
index 5524615..79eefeb 100644
|
|
|
0fd959 |
--- a/dbe/dbe.c
|
|
|
0fd959 |
+++ b/dbe/dbe.c
|
|
|
0fd959 |
@@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client)
|
|
|
0fd959 |
DbeSwapInfoPtr swapInfo;
|
|
|
0fd959 |
xDbeSwapInfo *dbeSwapInfo;
|
|
|
0fd959 |
int error;
|
|
|
0fd959 |
- register int i, j;
|
|
|
0fd959 |
- int nStuff;
|
|
|
0fd959 |
+ unsigned int i, j;
|
|
|
0fd959 |
+ unsigned int nStuff;
|
|
|
0fd959 |
|
|
|
0fd959 |
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
|
|
|
0fd959 |
nStuff = stuff->n; /* use local variable for performance. */
|
|
|
0fd959 |
|
|
|
0fd959 |
if (nStuff == 0) {
|
|
|
0fd959 |
+ REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
|
|
|
0fd959 |
return Success;
|
|
|
0fd959 |
}
|
|
|
0fd959 |
|
|
|
0fd959 |
if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
|
|
|
0fd959 |
return BadAlloc;
|
|
|
0fd959 |
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
|
|
|
0fd959 |
|
|
|
0fd959 |
/* Get to the swap info appended to the end of the request. */
|
|
|
0b0bd3 |
dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
|
|
|
0fd959 |
@@ -914,13 +916,16 @@ static int
|
|
|
0fd959 |
SProcDbeSwapBuffers(ClientPtr client)
|
|
|
0fd959 |
{
|
|
|
0fd959 |
REQUEST(xDbeSwapBuffersReq);
|
|
|
0fd959 |
- register int i;
|
|
|
0fd959 |
+ unsigned int i;
|
|
|
0fd959 |
xDbeSwapInfo *pSwapInfo;
|
|
|
0fd959 |
|
|
|
0fd959 |
swaps(&stuff->length);
|
|
|
0fd959 |
REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
|
|
|
0fd959 |
|
|
|
0fd959 |
swapl(&stuff->n);
|
|
|
0fd959 |
+ if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
|
|
|
0fd959 |
+ return BadAlloc;
|
|
|
0fd959 |
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
|
|
|
0fd959 |
|
|
|
0fd959 |
if (stuff->n != 0) {
|
|
|
0fd959 |
pSwapInfo = (xDbeSwapInfo *) stuff + 1;
|
|
|
0fd959 |
--
|
|
|
0fd959 |
1.9.3
|
|
|
0fd959 |
|