1 From 0d50f11aa10fe64c74ab7b3c572cc2f3ff583020 Mon Sep 17 00:00:00 2001
2 From: Alan Coopersmith <alan.coopersmith@oracle.com>
3 Date: Wed, 22 Jan 2014 23:12:04 -0800
4 Subject: [PATCH 07/33] dbe: unvalidated lengths in DbeSwapBuffers calls
7 ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read
8 from a buffer. The length is never validated, which can lead to out of
9 bound reads, and possibly returning the data read from out of bounds to
10 the misbehaving client via an X Error packet.
12 SProcDbeSwapBuffers() swaps data (for correct endianness) before
13 handing it off to the real proc. While doing the swapping, the
14 length field is not validated, which can cause memory corruption.
16 v2: reorder checks to avoid compilers optimizing out checks for overflow
17 that happen after we'd already have done the overflowing multiplications.
19 Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
20 Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
21 Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
23 dbe/dbe.c | 11 ++++++++---
24 1 file changed, 8 insertions(+), 3 deletions(-)
26 diff --git a/dbe/dbe.c b/dbe/dbe.c
27 index 527588c..df2ad5c 100644
30 @@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client)
31 DbeSwapInfoPtr swapInfo;
32 xDbeSwapInfo *dbeSwapInfo;
37 + unsigned int nStuff;
39 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
40 nStuff = stuff->n; /* use local variable for performance. */
43 + REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
47 if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
49 + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
51 /* Get to the swap info appended to the end of the request. */
52 dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
53 @@ -914,13 +916,16 @@ static int
54 SProcDbeSwapBuffers(ClientPtr client)
56 REQUEST(xDbeSwapBuffersReq);
59 xDbeSwapInfo *pSwapInfo;
61 swaps(&stuff->length);
62 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
65 + if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
67 + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
70 pSwapInfo = (xDbeSwapInfo *) stuff + 1;