aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi
diff options
context:
space:
mode:
authorMike DePaulo <mikedep333@gmail.com>2015-01-10 12:03:47 -0500
committerMike DePaulo <mikedep333@gmail.com>2015-01-10 12:06:49 -0500
commit7e1c3b94f42dfc5e52f0f724b6bf7d03e3b743e3 (patch)
treef2a4bfed7809a8e0bf4d06ec56a80191badba48b /xorg-server/Xi
parent212ca5c6023b6b7455ad64b2c29aeff82f301a03 (diff)
downloadvcxsrv-7e1c3b94f42dfc5e52f0f724b6bf7d03e3b743e3.tar.gz
vcxsrv-7e1c3b94f42dfc5e52f0f724b6bf7d03e3b743e3.tar.bz2
vcxsrv-7e1c3b94f42dfc5e52f0f724b6bf7d03e3b743e3.zip
Fix CVE-2014-8091..8103. Patches were ported from Ubuntu 14.04 (xorg-server 1.15.1)
Diffstat (limited to 'xorg-server/Xi')
-rw-r--r--xorg-server/Xi/chgdctl.c8
-rw-r--r--xorg-server/Xi/chgfctl.c2
-rw-r--r--xorg-server/Xi/sendexev.c3
-rw-r--r--xorg-server/Xi/xiallowev.c2
-rw-r--r--xorg-server/Xi/xichangecursor.c2
-rw-r--r--xorg-server/Xi/xichangehierarchy.c35
-rw-r--r--xorg-server/Xi/xigetclientpointer.c1
-rw-r--r--xorg-server/Xi/xigrabdev.c9
-rw-r--r--xorg-server/Xi/xipassivegrab.c12
-rw-r--r--xorg-server/Xi/xiproperty.c14
-rw-r--r--xorg-server/Xi/xiquerydevice.c1
-rw-r--r--xorg-server/Xi/xiquerypointer.c2
-rw-r--r--xorg-server/Xi/xiselectev.c8
-rw-r--r--xorg-server/Xi/xisetclientpointer.c3
-rw-r--r--xorg-server/Xi/xisetdevfocus.c4
-rw-r--r--xorg-server/Xi/xiwarppointer.c2
16 files changed, 90 insertions, 18 deletions
diff --git a/xorg-server/Xi/chgdctl.c b/xorg-server/Xi/chgdctl.c
index 106b9aaed..cb7ad1ebc 100644
--- a/xorg-server/Xi/chgdctl.c
+++ b/xorg-server/Xi/chgdctl.c
@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr client)
REQUEST(xChangeDeviceControlReq);
swaps(&stuff->length);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
swaps(&stuff->control);
ctl = (xDeviceCtl *) &stuff[1];
swaps(&ctl->control);
@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr client)
xDeviceEnableCtl *e;
REQUEST(xChangeDeviceControlReq);
- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq));
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
@@ -191,6 +191,10 @@ ProcXChangeDeviceControl(ClientPtr client)
break;
case DEVICE_ENABLE:
e = (xDeviceEnableCtl *) &stuff[1];
+ if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) {
+ ret = BadLength;
+ goto out;
+ }
if (IsXTestDevice(dev, NULL))
status = !Success;
diff --git a/xorg-server/Xi/chgfctl.c b/xorg-server/Xi/chgfctl.c
index 6dcf60c66..224c2ba0a 100644
--- a/xorg-server/Xi/chgfctl.c
+++ b/xorg-server/Xi/chgfctl.c
@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr client)
xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
if (client->swapped) {
+ if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
+ return BadLength;
swaps(&f->num_keysyms);
}
if (len !=
diff --git a/xorg-server/Xi/sendexev.c b/xorg-server/Xi/sendexev.c
index 3c213864b..183f88dae 100644
--- a/xorg-server/Xi/sendexev.c
+++ b/xorg-server/Xi/sendexev.c
@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client)
if (ret != Success)
return ret;
+ if (stuff->num_events == 0)
+ return ret;
+
/* The client's event type must be one defined by an extension. */
first = ((xEvent *) &stuff[1]);
diff --git a/xorg-server/Xi/xiallowev.c b/xorg-server/Xi/xiallowev.c
index ebef23344..ca263ef1f 100644
--- a/xorg-server/Xi/xiallowev.c
+++ b/xorg-server/Xi/xiallowev.c
@@ -48,6 +48,7 @@ int
SProcXIAllowEvents(ClientPtr client)
{
REQUEST(xXIAllowEventsReq);
+ REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client)
if (stuff->length > 3) {
xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff;
+ REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq);
swapl(&req_xi22->touchid);
swapl(&req_xi22->grab_window);
}
diff --git a/xorg-server/Xi/xichangecursor.c b/xorg-server/Xi/xichangecursor.c
index 7a1bb7a0d..8e6255b6e 100644
--- a/xorg-server/Xi/xichangecursor.c
+++ b/xorg-server/Xi/xichangecursor.c
@@ -57,11 +57,11 @@ int
SProcXIChangeCursor(ClientPtr client)
{
REQUEST(xXIChangeCursorReq);
+ REQUEST_SIZE_MATCH(xXIChangeCursorReq);
swaps(&stuff->length);
swapl(&stuff->win);
swapl(&stuff->cursor);
swaps(&stuff->deviceid);
- REQUEST_SIZE_MATCH(xXIChangeCursorReq);
return (ProcXIChangeCursor(client));
}
diff --git a/xorg-server/Xi/xichangehierarchy.c b/xorg-server/Xi/xichangehierarchy.c
index 9e36354d1..27324452d 100644
--- a/xorg-server/Xi/xichangehierarchy.c
+++ b/xorg-server/Xi/xichangehierarchy.c
@@ -411,7 +411,7 @@ int
ProcXIChangeHierarchy(ClientPtr client)
{
xXIAnyHierarchyChangeInfo *any;
- int required_len = sizeof(xXIChangeHierarchyReq);
+ size_t len; /* length of data remaining in request */
int rc = Success;
int flags[MAXDEVICES] = { 0 };
@@ -421,21 +421,46 @@ ProcXIChangeHierarchy(ClientPtr client)
if (!stuff->num_changes)
return rc;
+ if (stuff->length > (INT_MAX >> 2))
+ return BadAlloc;
+ len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo);
+
any = (xXIAnyHierarchyChangeInfo *) &stuff[1];
while (stuff->num_changes--) {
+ if (len < sizeof(xXIAnyHierarchyChangeInfo)) {
+ rc = BadLength;
+ goto unwind;
+ }
+
SWAPIF(swaps(&any->type));
SWAPIF(swaps(&any->length));
- required_len += any->length;
- if ((stuff->length * 4) < required_len)
+ if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2)))
return BadLength;
+#define CHANGE_SIZE_MATCH(type) \
+ do { \
+ if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \
+ rc = BadLength; \
+ goto unwind; \
+ } \
+ } while(0)
+
switch (any->type) {
case XIAddMaster:
{
xXIAddMasterInfo *c = (xXIAddMasterInfo *) any;
+ /* Variable length, due to appended name string */
+ if (len < sizeof(xXIAddMasterInfo)) {
+ rc = BadLength;
+ goto unwind;
+ }
SWAPIF(swaps(&c->name_len));
+ if (c->name_len > (len - sizeof(xXIAddMasterInfo))) {
+ rc = BadLength;
+ goto unwind;
+ }
rc = add_master(client, c, flags);
if (rc != Success)
@@ -446,6 +471,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
+ CHANGE_SIZE_MATCH(xXIRemoveMasterInfo);
rc = remove_master(client, r, flags);
if (rc != Success)
goto unwind;
@@ -455,6 +481,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
+ CHANGE_SIZE_MATCH(xXIDetachSlaveInfo);
rc = detach_slave(client, c, flags);
if (rc != Success)
goto unwind;
@@ -464,6 +491,7 @@ ProcXIChangeHierarchy(ClientPtr client)
{
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
+ CHANGE_SIZE_MATCH(xXIAttachSlaveInfo);
rc = attach_slave(client, c, flags);
if (rc != Success)
goto unwind;
@@ -471,6 +499,7 @@ ProcXIChangeHierarchy(ClientPtr client)
break;
}
+ len -= any->length * 4;
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
}
diff --git a/xorg-server/Xi/xigetclientpointer.c b/xorg-server/Xi/xigetclientpointer.c
index 6ab2867f7..9d7feca4c 100644
--- a/xorg-server/Xi/xigetclientpointer.c
+++ b/xorg-server/Xi/xigetclientpointer.c
@@ -50,6 +50,7 @@ int
SProcXIGetClientPointer(ClientPtr client)
{
REQUEST(xXIGetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
swaps(&stuff->length);
swapl(&stuff->win);
diff --git a/xorg-server/Xi/xigrabdev.c b/xorg-server/Xi/xigrabdev.c
index 086e275d8..6be9971c9 100644
--- a/xorg-server/Xi/xigrabdev.c
+++ b/xorg-server/Xi/xigrabdev.c
@@ -47,6 +47,11 @@ int
SProcXIGrabDevice(ClientPtr client)
{
REQUEST(xXIGrabDeviceReq);
+ /*
+ * Check here for at least the length of the struct we swap, then
+ * let ProcXIGrabDevice check the full size after we swap mask_len.
+ */
+ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client)
unsigned int pointer_mode;
REQUEST(xXIGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
if (ret != Success)
@@ -130,6 +135,7 @@ int
SProcXIUngrabDevice(ClientPtr client)
{
REQUEST(xXIUngrabDeviceReq);
+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -147,6 +153,7 @@ ProcXIUngrabDevice(ClientPtr client)
TimeStamp time;
REQUEST(xXIUngrabDeviceReq);
+ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
if (ret != Success)
diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c
index ca69050b2..3f6268f69 100644
--- a/xorg-server/Xi/xipassivegrab.c
+++ b/xorg-server/Xi/xipassivegrab.c
@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr client)
uint32_t *mods;
REQUEST(xXIPassiveGrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr client)
swaps(&stuff->mask_len);
swaps(&stuff->num_modifiers);
+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
mods = (uint32_t *) &stuff[1] + stuff->mask_len;
for (i = 0; i < stuff->num_modifiers; i++, mods++) {
@@ -86,7 +89,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
int mask_len;
REQUEST(xXIPassiveGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
+ ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
rep.repType = X_Reply;
rep.RepType = X_XIPassiveGrabDevice;
@@ -252,6 +256,7 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
uint32_t *modifiers;
REQUEST(xXIPassiveUngrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
swaps(&stuff->length);
swapl(&stuff->grab_window);
@@ -259,6 +264,8 @@ SProcXIPassiveUngrabDevice(ClientPtr client)
swapl(&stuff->detail);
swaps(&stuff->num_modifiers);
+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+ ((uint32_t) stuff->num_modifiers) << 2);
modifiers = (uint32_t *) &stuff[1];
for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
@@ -277,7 +284,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
int i, rc;
REQUEST(xXIPassiveUngrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
+ ((uint32_t) stuff->num_modifiers) << 2);
if (stuff->deviceid == XIAllDevices)
dev = inputInfo.all_devices;
diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c
index 18936c587..13c478e65 100644
--- a/xorg-server/Xi/xiproperty.c
+++ b/xorg-server/Xi/xiproperty.c
@@ -1011,10 +1011,9 @@ int
SProcXListDeviceProperties(ClientPtr client)
{
REQUEST(xListDevicePropertiesReq);
+ REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
swaps(&stuff->length);
-
- REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
return (ProcXListDeviceProperties(client));
}
@@ -1035,10 +1034,10 @@ int
SProcXDeleteDeviceProperty(ClientPtr client)
{
REQUEST(xDeleteDevicePropertyReq);
+ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
swaps(&stuff->length);
swapl(&stuff->property);
- REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
return (ProcXDeleteDeviceProperty(client));
}
@@ -1046,13 +1045,13 @@ int
SProcXGetDeviceProperty(ClientPtr client)
{
REQUEST(xGetDevicePropertyReq);
+ REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
swaps(&stuff->length);
swapl(&stuff->property);
swapl(&stuff->type);
swapl(&stuff->longOffset);
swapl(&stuff->longLength);
- REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
return (ProcXGetDeviceProperty(client));
}
@@ -1249,11 +1248,10 @@ int
SProcXIListProperties(ClientPtr client)
{
REQUEST(xXIListPropertiesReq);
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
-
- REQUEST_SIZE_MATCH(xXIListPropertiesReq);
return (ProcXIListProperties(client));
}
@@ -1275,11 +1273,11 @@ int
SProcXIDeleteProperty(ClientPtr client)
{
REQUEST(xXIDeletePropertyReq);
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->property);
- REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
return (ProcXIDeleteProperty(client));
}
@@ -1287,6 +1285,7 @@ int
SProcXIGetProperty(ClientPtr client)
{
REQUEST(xXIGetPropertyReq);
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
@@ -1294,7 +1293,6 @@ SProcXIGetProperty(ClientPtr client)
swapl(&stuff->type);
swapl(&stuff->offset);
swapl(&stuff->len);
- REQUEST_SIZE_MATCH(xXIGetPropertyReq);
return (ProcXIGetProperty(client));
}
diff --git a/xorg-server/Xi/xiquerydevice.c b/xorg-server/Xi/xiquerydevice.c
index 1d1090046..186e21bf6 100644
--- a/xorg-server/Xi/xiquerydevice.c
+++ b/xorg-server/Xi/xiquerydevice.c
@@ -54,6 +54,7 @@ int
SProcXIQueryDevice(ClientPtr client)
{
REQUEST(xXIQueryDeviceReq);
+ REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
swaps(&stuff->length);
swaps(&stuff->deviceid);
diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c
index a87326181..014bffa7f 100644
--- a/xorg-server/Xi/xiquerypointer.c
+++ b/xorg-server/Xi/xiquerypointer.c
@@ -63,6 +63,8 @@ int
SProcXIQueryPointer(ClientPtr client)
{
REQUEST(xXIQueryPointerReq);
+ REQUEST_SIZE_MATCH(xXIQueryPointerReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->win);
diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c
index 8592747f6..701748eeb 100644
--- a/xorg-server/Xi/xiselectev.c
+++ b/xorg-server/Xi/xiselectev.c
@@ -114,6 +114,7 @@ int
SProcXISelectEvents(ClientPtr client)
{
int i;
+ int len;
xXIEventMask *evmask;
REQUEST(xXISelectEventsReq);
@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client)
swapl(&stuff->win);
swaps(&stuff->num_masks);
+ len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq));
evmask = (xXIEventMask *) &stuff[1];
for (i = 0; i < stuff->num_masks; i++) {
+ if (len < bytes_to_int32(sizeof(xXIEventMask)))
+ return BadLength;
+ len -= bytes_to_int32(sizeof(xXIEventMask));
swaps(&evmask->deviceid);
swaps(&evmask->mask_len);
+ if (len < evmask->mask_len)
+ return BadLength;
+ len -= evmask->mask_len;
evmask =
(xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4);
}
diff --git a/xorg-server/Xi/xisetclientpointer.c b/xorg-server/Xi/xisetclientpointer.c
index 38ff51e86..24d4a5379 100644
--- a/xorg-server/Xi/xisetclientpointer.c
+++ b/xorg-server/Xi/xisetclientpointer.c
@@ -51,10 +51,11 @@ int
SProcXISetClientPointer(ClientPtr client)
{
REQUEST(xXISetClientPointerReq);
+ REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+
swaps(&stuff->length);
swapl(&stuff->win);
swaps(&stuff->deviceid);
- REQUEST_SIZE_MATCH(xXISetClientPointerReq);
return (ProcXISetClientPointer(client));
}
diff --git a/xorg-server/Xi/xisetdevfocus.c b/xorg-server/Xi/xisetdevfocus.c
index aec822c6b..f3584d567 100644
--- a/xorg-server/Xi/xisetdevfocus.c
+++ b/xorg-server/Xi/xisetdevfocus.c
@@ -44,6 +44,8 @@ int
SProcXISetFocus(ClientPtr client)
{
REQUEST(xXISetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
swapl(&stuff->focus);
@@ -56,6 +58,8 @@ int
SProcXIGetFocus(ClientPtr client)
{
REQUEST(xXIGetFocusReq);
+ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
+
swaps(&stuff->length);
swaps(&stuff->deviceid);
diff --git a/xorg-server/Xi/xiwarppointer.c b/xorg-server/Xi/xiwarppointer.c
index 3f051f759..780758a9e 100644
--- a/xorg-server/Xi/xiwarppointer.c
+++ b/xorg-server/Xi/xiwarppointer.c
@@ -56,6 +56,8 @@ int
SProcXIWarpPointer(ClientPtr client)
{
REQUEST(xXIWarpPointerReq);
+ REQUEST_SIZE_MATCH(xXIWarpPointerReq);
+
swaps(&stuff->length);
swapl(&stuff->src_win);
swapl(&stuff->dst_win);