Commit | Line | Data |
---|---|---|
7217e0ca ML |
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 | |
5 | [CVE-2014-8097] | |
6 | ||
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. | |
11 | ||
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. | |
15 | ||
16 | v2: reorder checks to avoid compilers optimizing out checks for overflow | |
17 | that happen after we'd already have done the overflowing multiplications. | |
18 | ||
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> | |
22 | --- | |
23 | dbe/dbe.c | 11 ++++++++--- | |
24 | 1 file changed, 8 insertions(+), 3 deletions(-) | |
25 | ||
26 | diff --git a/dbe/dbe.c b/dbe/dbe.c | |
27 | index 527588c..df2ad5c 100644 | |
28 | --- a/dbe/dbe.c | |
29 | +++ b/dbe/dbe.c | |
30 | @@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client) | |
31 | DbeSwapInfoPtr swapInfo; | |
32 | xDbeSwapInfo *dbeSwapInfo; | |
33 | int error; | |
34 | - register int i, j; | |
35 | - int nStuff; | |
36 | + unsigned int i, j; | |
37 | + unsigned int nStuff; | |
38 | ||
39 | REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); | |
40 | nStuff = stuff->n; /* use local variable for performance. */ | |
41 | ||
42 | if (nStuff == 0) { | |
43 | + REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); | |
44 | return Success; | |
45 | } | |
46 | ||
47 | if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) | |
48 | return BadAlloc; | |
49 | + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); | |
50 | ||
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) | |
55 | { | |
56 | REQUEST(xDbeSwapBuffersReq); | |
57 | - register int i; | |
58 | + unsigned int i; | |
59 | xDbeSwapInfo *pSwapInfo; | |
60 | ||
61 | swaps(&stuff->length); | |
62 | REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); | |
63 | ||
64 | swapl(&stuff->n); | |
65 | + if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) | |
66 | + return BadAlloc; | |
67 | + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); | |
68 | ||
69 | if (stuff->n != 0) { | |
70 | pSwapInfo = (xDbeSwapInfo *) stuff + 1; | |
71 | -- | |
72 | 1.7.9.2 | |
73 |