Bump libXrender to 0.9.10
[unleashed-userland.git] / components / x11 / libXtst / patches / 02-CVE-2016-7951+CVE-2016-7952.patch
blobcd09d793e608d5e4b78b230ff5e4263d5cbcc6b0
1 From 9556ad67af3129ec4a7a4f4b54a0d59701beeae3 Mon Sep 17 00:00:00 2001
2 From: Tobias Stoeckmann <tobias@stoeckmann.org>
3 Date: Sun, 25 Sep 2016 21:37:01 +0200
4 Subject: Out of boundary access and endless loop in libXtst
6 A lack of range checks in libXtst allows out of boundary accesses.
7 The checks have to be done in-place here, because it cannot be done
8 without in-depth knowledge of the read data.
10 If XRecordStartOfData, XRecordEndOfData, or XRecordClientDied
11 without a client sequence have attached data, an endless loop would
12 occur. The do-while-loop continues until the current index reaches
13 the end. But in these cases, the current index would not be
14 incremented, leading to an endless processing.
16 Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
17 Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
19 diff --git a/src/XRecord.c b/src/XRecord.c
20 index 50420c0..fefd842 100644
21 --- a/src/XRecord.c
22 +++ b/src/XRecord.c
23 @@ -749,15 +749,23 @@ parse_reply_call_callback(
24 switch (rep->category) {
25 case XRecordFromServer:
26 if (rep->elementHeader&XRecordFromServerTime) {
27 + if (current_index + 4 > rep->length << 2)
28 + return Error;
29 EXTRACT_CARD32(rep->clientSwapped,
30 reply->buf+current_index,
31 data->server_time);
32 current_index += 4;
34 + if (current_index + 1 > rep->length << 2)
35 + return Error;
36 switch (reply->buf[current_index]) {
37 case X_Reply: /* reply */
38 + if (current_index + 8 > rep->length << 2)
39 + return Error;
40 EXTRACT_CARD32(rep->clientSwapped,
41 reply->buf+current_index+4, datum_bytes);
42 + if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8))
43 + return Error;
44 datum_bytes = (datum_bytes+8) << 2;
45 break;
46 default: /* error or event */
47 @@ -766,52 +774,73 @@ parse_reply_call_callback(
48 break;
49 case XRecordFromClient:
50 if (rep->elementHeader&XRecordFromClientTime) {
51 + if (current_index + 4 > rep->length << 2)
52 + return Error;
53 EXTRACT_CARD32(rep->clientSwapped,
54 reply->buf+current_index,
55 data->server_time);
56 current_index += 4;
58 if (rep->elementHeader&XRecordFromClientSequence) {
59 + if (current_index + 4 > rep->length << 2)
60 + return Error;
61 EXTRACT_CARD32(rep->clientSwapped,
62 reply->buf+current_index,
63 data->client_seq);
64 current_index += 4;
66 + if (current_index + 4 > rep->length<<2)
67 + return Error;
68 if (reply->buf[current_index+2] == 0
69 && reply->buf[current_index+3] == 0) /* needn't swap 0 */
70 { /* BIG-REQUESTS */
71 + if (current_index + 8 > rep->length << 2)
72 + return Error;
73 EXTRACT_CARD32(rep->clientSwapped,
74 reply->buf+current_index+4, datum_bytes);
75 } else {
76 EXTRACT_CARD16(rep->clientSwapped,
77 reply->buf+current_index+2, datum_bytes);
79 + if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2)
80 + return Error;
81 datum_bytes <<= 2;
82 break;
83 case XRecordClientStarted:
84 + if (current_index + 8 > rep->length << 2)
85 + return Error;
86 EXTRACT_CARD16(rep->clientSwapped,
87 reply->buf+current_index+6, datum_bytes);
88 datum_bytes = (datum_bytes+2) << 2;
89 break;
90 case XRecordClientDied:
91 if (rep->elementHeader&XRecordFromClientSequence) {
92 + if (current_index + 4 > rep->length << 2)
93 + return Error;
94 EXTRACT_CARD32(rep->clientSwapped,
95 reply->buf+current_index,
96 data->client_seq);
97 current_index += 4;
98 - }
99 - /* fall through */
100 + } else if (current_index < rep->length << 2)
101 + return Error;
102 + datum_bytes = 0;
103 + break;
104 case XRecordStartOfData:
105 case XRecordEndOfData:
106 + if (current_index < rep->length << 2)
107 + return Error;
108 datum_bytes = 0;
109 + break;
112 if (datum_bytes > 0) {
113 - if (current_index + datum_bytes > rep->length << 2)
114 + if (INT_MAX - datum_bytes < (rep->length << 2) - current_index) {
115 fprintf(stderr,
116 "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n",
117 - (long)rep->length << 2, current_index + datum_bytes,
118 + (unsigned long)rep->length << 2, current_index + datum_bytes,
119 dpy->last_request_read);
120 + return Error;
123 * This assignment (and indeed the whole buffer sharing
124 * scheme) assumes arbitrary 4-byte boundaries are
125 @@ -863,6 +892,12 @@ XRecordEnableContext(Display *dpy, XRecordContext context,
126 return 0;
129 + if (rep.length > INT_MAX >> 2) {
130 + UnlockDisplay(dpy);
131 + SyncHandle();
132 + return 0;
135 if (rep.length > 0) {
136 reply = alloc_reply_buffer(info, rep.length<<2);
137 if (!reply) {
139 cgit v0.10.2