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 | ||
7217e0ca ML |
26 | --- a/dbe/dbe.c |
27 | +++ b/dbe/dbe.c | |
28 | @@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client) | |
29 | DbeSwapInfoPtr swapInfo; | |
30 | xDbeSwapInfo *dbeSwapInfo; | |
31 | int error; | |
32 | - register int i, j; | |
33 | - int nStuff; | |
34 | + unsigned int i, j; | |
35 | + unsigned int nStuff; | |
36 | ||
37 | REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); | |
38 | nStuff = stuff->n; /* use local variable for performance. */ | |
39 | ||
40 | if (nStuff == 0) { | |
41 | + REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); | |
42 | return Success; | |
43 | } | |
44 | ||
45 | if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) | |
46 | return BadAlloc; | |
47 | + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); | |
48 | ||
49 | /* Get to the swap info appended to the end of the request. */ | |
50 | dbeSwapInfo = (xDbeSwapInfo *) &stuff[1]; | |
51 | @@ -914,13 +916,16 @@ static int | |
52 | SProcDbeSwapBuffers(ClientPtr client) | |
53 | { | |
54 | REQUEST(xDbeSwapBuffersReq); | |
55 | - register int i; | |
56 | + unsigned int i; | |
57 | xDbeSwapInfo *pSwapInfo; | |
58 | ||
59 | swaps(&stuff->length); | |
60 | REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); | |
61 | ||
62 | swapl(&stuff->n); | |
63 | + if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) | |
64 | + return BadAlloc; | |
65 | + REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); | |
66 | ||
67 | if (stuff->n != 0) { | |
68 | pSwapInfo = (xDbeSwapInfo *) stuff + 1; |