ODROID-U3 xorg-server debian package fork :
[deb_xorg-server.git] / debian / patches / CVE-2014-8xxx / 0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch
CommitLineData
7217e0ca
ML
1From 54fa1f815507cd27280f661be7a64f2f2e6c579e Mon Sep 17 00:00:00 2001
2From: Alan Coopersmith <alan.coopersmith@oracle.com>
3Date: Sun, 26 Jan 2014 10:54:41 -0800
4Subject: [PATCH 08/33] Xi: unvalidated lengths in Xinput extension
5 [CVE-2014-8095]
6
7Multiple functions in the Xinput extension handling of requests from
8clients failed to check that the length of the request sent by the
9client was large enough to perform all the required operations and
10thus could read or write to memory outside the bounds of the request
11buffer.
12
13This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE
14macro in include/dix.h for the common case of needing to ensure a
15request is large enough to include both the request itself and a
16minimum amount of extra data following the request header.
17
18Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
19Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
20---
21 Xi/chgdctl.c | 8 ++++++--
22 Xi/chgfctl.c | 2 ++
23 Xi/sendexev.c | 3 +++
24 Xi/xiallowev.c | 2 ++
25 Xi/xichangecursor.c | 2 +-
26 Xi/xichangehierarchy.c | 35 ++++++++++++++++++++++++++++++++---
27 Xi/xigetclientpointer.c | 1 +
28 Xi/xigrabdev.c | 9 ++++++++-
29 Xi/xipassivegrab.c | 12 ++++++++++--
30 Xi/xiproperty.c | 14 ++++++--------
31 Xi/xiquerydevice.c | 1 +
32 Xi/xiquerypointer.c | 2 ++
33 Xi/xiselectev.c | 8 ++++++++
34 Xi/xisetclientpointer.c | 3 ++-
35 Xi/xisetdevfocus.c | 4 ++++
36 Xi/xiwarppointer.c | 2 ++
37 include/dix.h | 4 ++++
38 17 files changed, 94 insertions(+), 18 deletions(-)
39
7217e0ca
ML
40--- a/Xi/chgdctl.c
41+++ b/Xi/chgdctl.c
4db25562 42@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr clie
7217e0ca
ML
43
44 REQUEST(xChangeDeviceControlReq);
45 swaps(&stuff->length);
46- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
47+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
48 swaps(&stuff->control);
49 ctl = (xDeviceCtl *) &stuff[1];
50 swaps(&ctl->control);
4db25562 51@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr clien
7217e0ca
ML
52 xDeviceEnableCtl *e;
53
54 REQUEST(xChangeDeviceControlReq);
55- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
56+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
57
58 len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
59 ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
4db25562 60@@ -192,6 +192,10 @@ ProcXChangeDeviceControl(ClientPtr clien
7217e0ca
ML
61 break;
62 case DEVICE_ENABLE:
63 e = (xDeviceEnableCtl *) &stuff[1];
64+ if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) {
65+ ret = BadLength;
66+ goto out;
67+ }
68
69 if (IsXTestDevice(dev, NULL))
70 status = !Success;
7217e0ca
ML
71--- a/Xi/chgfctl.c
72+++ b/Xi/chgfctl.c
4db25562 73@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr cli
7217e0ca
ML
74 xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
75
76 if (client->swapped) {
77+ if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
78+ return BadLength;
79 swaps(&f->num_keysyms);
80 }
81 if (len !=
7217e0ca
ML
82--- a/Xi/sendexev.c
83+++ b/Xi/sendexev.c
4db25562 84@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client
7217e0ca
ML
85 if (ret != Success)
86 return ret;
87
88+ if (stuff->num_events == 0)
89+ return ret;
90+
91 /* The client's event type must be one defined by an extension. */
92
93 first = ((xEvent *) &stuff[1]);
7217e0ca
ML
94--- a/Xi/xiallowev.c
95+++ b/Xi/xiallowev.c
96@@ -48,6 +48,7 @@ int
97 SProcXIAllowEvents(ClientPtr client)
98 {
99 REQUEST(xXIAllowEventsReq);
100+ REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
101
102 swaps(&stuff->length);
103 swaps(&stuff->deviceid);
104@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client)
105 if (stuff->length > 3) {
106 xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff;
107
108+ REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq);
109 swapl(&req_xi22->touchid);
110 swapl(&req_xi22->grab_window);
111 }
7217e0ca
ML
112--- a/Xi/xichangecursor.c
113+++ b/Xi/xichangecursor.c
114@@ -57,11 +57,11 @@ int
115 SProcXIChangeCursor(ClientPtr client)
116 {
117 REQUEST(xXIChangeCursorReq);
118+ REQUEST_SIZE_MATCH(xXIChangeCursorReq);
119 swaps(&stuff->length);
120 swapl(&stuff->win);
121 swapl(&stuff->cursor);
122 swaps(&stuff->deviceid);
123- REQUEST_SIZE_MATCH(xXIChangeCursorReq);
124 return (ProcXIChangeCursor(client));
125 }
126
7217e0ca
ML
127--- a/Xi/xichangehierarchy.c
128+++ b/Xi/xichangehierarchy.c
129@@ -411,7 +411,7 @@ int
130 ProcXIChangeHierarchy(ClientPtr client)
131 {
132 xXIAnyHierarchyChangeInfo *any;
133- int required_len = sizeof(xXIChangeHierarchyReq);
134+ size_t len; /* length of data remaining in request */
135 int rc = Success;
136 int flags[MAXDEVICES] = { 0 };
137
138@@ -421,21 +421,46 @@ ProcXIChangeHierarchy(ClientPtr client)
139 if (!stuff->num_changes)
140 return rc;
141
142+ if (stuff->length > (INT_MAX >> 2))
143+ return BadAlloc;
144+ len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo);
145+
146 any = (xXIAnyHierarchyChangeInfo *) &stuff[1];
147 while (stuff->num_changes--) {
148+ if (len < sizeof(xXIAnyHierarchyChangeInfo)) {
149+ rc = BadLength;
150+ goto unwind;
151+ }
152+
153 SWAPIF(swaps(&any->type));
154 SWAPIF(swaps(&any->length));
155
156- required_len += any->length;
157- if ((stuff->length * 4) < required_len)
158+ if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2)))
159 return BadLength;
160
161+#define CHANGE_SIZE_MATCH(type) \
162+ do { \
163+ if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \
164+ rc = BadLength; \
165+ goto unwind; \
166+ } \
167+ } while(0)
168+
169 switch (any->type) {
170 case XIAddMaster:
171 {
172 xXIAddMasterInfo *c = (xXIAddMasterInfo *) any;
173
174+ /* Variable length, due to appended name string */
175+ if (len < sizeof(xXIAddMasterInfo)) {
176+ rc = BadLength;
177+ goto unwind;
178+ }
179 SWAPIF(swaps(&c->name_len));
180+ if (c->name_len > (len - sizeof(xXIAddMasterInfo))) {
181+ rc = BadLength;
182+ goto unwind;
183+ }
184
185 rc = add_master(client, c, flags);
186 if (rc != Success)
187@@ -446,6 +471,7 @@ ProcXIChangeHierarchy(ClientPtr client)
188 {
189 xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
190
191+ CHANGE_SIZE_MATCH(xXIRemoveMasterInfo);
192 rc = remove_master(client, r, flags);
193 if (rc != Success)
194 goto unwind;
195@@ -455,6 +481,7 @@ ProcXIChangeHierarchy(ClientPtr client)
196 {
197 xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
198
199+ CHANGE_SIZE_MATCH(xXIDetachSlaveInfo);
200 rc = detach_slave(client, c, flags);
201 if (rc != Success)
202 goto unwind;
203@@ -464,6 +491,7 @@ ProcXIChangeHierarchy(ClientPtr client)
204 {
205 xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
206
207+ CHANGE_SIZE_MATCH(xXIAttachSlaveInfo);
208 rc = attach_slave(client, c, flags);
209 if (rc != Success)
210 goto unwind;
211@@ -471,6 +499,7 @@ ProcXIChangeHierarchy(ClientPtr client)
212 break;
213 }
214
215+ len -= any->length * 4;
216 any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
217 }
218
7217e0ca
ML
219--- a/Xi/xigetclientpointer.c
220+++ b/Xi/xigetclientpointer.c
221@@ -50,6 +50,7 @@ int
222 SProcXIGetClientPointer(ClientPtr client)
223 {
224 REQUEST(xXIGetClientPointerReq);
225+ REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
226
227 swaps(&stuff->length);
228 swapl(&stuff->win);
7217e0ca
ML
229--- a/Xi/xigrabdev.c
230+++ b/Xi/xigrabdev.c
231@@ -47,6 +47,11 @@ int
232 SProcXIGrabDevice(ClientPtr client)
233 {
234 REQUEST(xXIGrabDeviceReq);
235+ /*
236+ * Check here for at least the length of the struct we swap, then
237+ * let ProcXIGrabDevice check the full size after we swap mask_len.
238+ */
239+ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
240
241 swaps(&stuff->length);
242 swaps(&stuff->deviceid);
243@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client)
244 unsigned int pointer_mode;
245
246 REQUEST(xXIGrabDeviceReq);
247- REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
248+ REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4);
249
250 ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
251 if (ret != Success)
252@@ -131,6 +136,7 @@ int
253 SProcXIUngrabDevice(ClientPtr client)
254 {
255 REQUEST(xXIUngrabDeviceReq);
256+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
257
258 swaps(&stuff->length);
259 swaps(&stuff->deviceid);
260@@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client)
261 TimeStamp time;
262
263 REQUEST(xXIUngrabDeviceReq);
264+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
265
266 ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
267 if (ret != Success)
7217e0ca
ML
268--- a/Xi/xipassivegrab.c
269+++ b/Xi/xipassivegrab.c
4db25562 270@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr clien
7217e0ca
ML
271 uint32_t *mods;
272
273 REQUEST(xXIPassiveGrabDeviceReq);
274+ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
275
276 swaps(&stuff->length);
277 swaps(&stuff->deviceid);
4db25562 278@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr clien
7217e0ca
ML
279 swaps(&stuff->mask_len);
280 swaps(&stuff->num_modifiers);
281
282+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
283+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
284 mods = (uint32_t *) &stuff[1] + stuff->mask_len;
285
286 for (i = 0; i < stuff->num_modifiers; i++, mods++) {
4db25562 287@@ -92,7 +95,8 @@ ProcXIPassiveGrabDevice(ClientPtr client
7217e0ca
ML
288 int mask_len;
289
290 REQUEST(xXIPassiveGrabDeviceReq);
291- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
292+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
293+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
294
295 if (stuff->deviceid == XIAllDevices)
296 dev = inputInfo.all_devices;
4db25562 297@@ -252,6 +256,7 @@ SProcXIPassiveUngrabDevice(ClientPtr cli
7217e0ca
ML
298 uint32_t *modifiers;
299
300 REQUEST(xXIPassiveUngrabDeviceReq);
301+ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
302
303 swaps(&stuff->length);
304 swapl(&stuff->grab_window);
4db25562 305@@ -259,6 +264,8 @@ SProcXIPassiveUngrabDevice(ClientPtr cli
7217e0ca
ML
306 swapl(&stuff->detail);
307 swaps(&stuff->num_modifiers);
308
309+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
310+ ((uint32_t) stuff->num_modifiers) << 2);
311 modifiers = (uint32_t *) &stuff[1];
312
313 for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
4db25562 314@@ -277,7 +284,8 @@ ProcXIPassiveUngrabDevice(ClientPtr clie
7217e0ca
ML
315 int i, rc;
316
317 REQUEST(xXIPassiveUngrabDeviceReq);
318- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
319+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
320+ ((uint32_t) stuff->num_modifiers) << 2);
321
322 if (stuff->deviceid == XIAllDevices)
323 dev = inputInfo.all_devices;
7217e0ca
ML
324--- a/Xi/xiproperty.c
325+++ b/Xi/xiproperty.c
326@@ -1013,10 +1013,9 @@ int
327 SProcXListDeviceProperties(ClientPtr client)
328 {
329 REQUEST(xListDevicePropertiesReq);
330+ REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
331
332 swaps(&stuff->length);
333-
334- REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
335 return (ProcXListDeviceProperties(client));
336 }
337
338@@ -1037,10 +1036,10 @@ int
339 SProcXDeleteDeviceProperty(ClientPtr client)
340 {
341 REQUEST(xDeleteDevicePropertyReq);
342+ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
343
344 swaps(&stuff->length);
345 swapl(&stuff->property);
346- REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
347 return (ProcXDeleteDeviceProperty(client));
348 }
349
350@@ -1048,13 +1047,13 @@ int
351 SProcXGetDeviceProperty(ClientPtr client)
352 {
353 REQUEST(xGetDevicePropertyReq);
354+ REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
355
356 swaps(&stuff->length);
357 swapl(&stuff->property);
358 swapl(&stuff->type);
359 swapl(&stuff->longOffset);
360 swapl(&stuff->longLength);
361- REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
362 return (ProcXGetDeviceProperty(client));
363 }
364
365@@ -1253,11 +1252,10 @@ int
366 SProcXIListProperties(ClientPtr client)
367 {
368 REQUEST(xXIListPropertiesReq);
369+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
370
371 swaps(&stuff->length);
372 swaps(&stuff->deviceid);
373-
374- REQUEST_SIZE_MATCH(xXIListPropertiesReq);
375 return (ProcXIListProperties(client));
376 }
377
378@@ -1279,11 +1277,11 @@ int
379 SProcXIDeleteProperty(ClientPtr client)
380 {
381 REQUEST(xXIDeletePropertyReq);
382+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
383
384 swaps(&stuff->length);
385 swaps(&stuff->deviceid);
386 swapl(&stuff->property);
387- REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
388 return (ProcXIDeleteProperty(client));
389 }
390
391@@ -1291,6 +1289,7 @@ int
392 SProcXIGetProperty(ClientPtr client)
393 {
394 REQUEST(xXIGetPropertyReq);
395+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
396
397 swaps(&stuff->length);
398 swaps(&stuff->deviceid);
399@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client)
400 swapl(&stuff->type);
401 swapl(&stuff->offset);
402 swapl(&stuff->len);
403- REQUEST_SIZE_MATCH(xXIGetPropertyReq);
404 return (ProcXIGetProperty(client));
405 }
406
7217e0ca
ML
407--- a/Xi/xiquerydevice.c
408+++ b/Xi/xiquerydevice.c
409@@ -54,6 +54,7 @@ int
410 SProcXIQueryDevice(ClientPtr client)
411 {
412 REQUEST(xXIQueryDeviceReq);
413+ REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
414
415 swaps(&stuff->length);
416 swaps(&stuff->deviceid);
7217e0ca
ML
417--- a/Xi/xiquerypointer.c
418+++ b/Xi/xiquerypointer.c
419@@ -63,6 +63,8 @@ int
420 SProcXIQueryPointer(ClientPtr client)
421 {
422 REQUEST(xXIQueryPointerReq);
423+ REQUEST_SIZE_MATCH(xXIQueryPointerReq);
424+
425 swaps(&stuff->length);
426 swaps(&stuff->deviceid);
427 swapl(&stuff->win);
7217e0ca
ML
428--- a/Xi/xiselectev.c
429+++ b/Xi/xiselectev.c
430@@ -114,6 +114,7 @@ int
431 SProcXISelectEvents(ClientPtr client)
432 {
433 int i;
434+ int len;
435 xXIEventMask *evmask;
436
437 REQUEST(xXISelectEventsReq);
438@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client)
439 swapl(&stuff->win);
440 swaps(&stuff->num_masks);
441
442+ len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq));
443 evmask = (xXIEventMask *) &stuff[1];
444 for (i = 0; i < stuff->num_masks; i++) {
445+ if (len < bytes_to_int32(sizeof(xXIEventMask)))
446+ return BadLength;
447+ len -= bytes_to_int32(sizeof(xXIEventMask));
448 swaps(&evmask->deviceid);
449 swaps(&evmask->mask_len);
450+ if (len < evmask->mask_len)
451+ return BadLength;
452+ len -= evmask->mask_len;
453 evmask =
454 (xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4);
455 }
7217e0ca
ML
456--- a/Xi/xisetclientpointer.c
457+++ b/Xi/xisetclientpointer.c
458@@ -51,10 +51,11 @@ int
459 SProcXISetClientPointer(ClientPtr client)
460 {
461 REQUEST(xXISetClientPointerReq);
462+ REQUEST_SIZE_MATCH(xXISetClientPointerReq);
463+
464 swaps(&stuff->length);
465 swapl(&stuff->win);
466 swaps(&stuff->deviceid);
467- REQUEST_SIZE_MATCH(xXISetClientPointerReq);
468 return (ProcXISetClientPointer(client));
469 }
470
7217e0ca
ML
471--- a/Xi/xisetdevfocus.c
472+++ b/Xi/xisetdevfocus.c
473@@ -44,6 +44,8 @@ int
474 SProcXISetFocus(ClientPtr client)
475 {
476 REQUEST(xXISetFocusReq);
477+ REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
478+
479 swaps(&stuff->length);
480 swaps(&stuff->deviceid);
481 swapl(&stuff->focus);
482@@ -56,6 +58,8 @@ int
483 SProcXIGetFocus(ClientPtr client)
484 {
485 REQUEST(xXIGetFocusReq);
486+ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
487+
488 swaps(&stuff->length);
489 swaps(&stuff->deviceid);
490
7217e0ca
ML
491--- a/Xi/xiwarppointer.c
492+++ b/Xi/xiwarppointer.c
493@@ -56,6 +56,8 @@ int
494 SProcXIWarpPointer(ClientPtr client)
495 {
496 REQUEST(xXIWarpPointerReq);
497+ REQUEST_SIZE_MATCH(xXIWarpPointerReq);
498+
499 swaps(&stuff->length);
500 swapl(&stuff->src_win);
501 swapl(&stuff->dst_win);
7217e0ca
ML
502--- a/include/dix.h
503+++ b/include/dix.h
504@@ -74,6 +74,10 @@ SOFTWARE.
505 if ((sizeof(req) >> 2) > client->req_len )\
506 return(BadLength)
507
508+#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \
509+ if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
510+ return(BadLength)
511+
512 #define REQUEST_FIXED_SIZE(req, n)\
513 if (((sizeof(req) >> 2) > client->req_len) || \
514 ((n >> 2) >= client->req_len) || \