Imported Debian patch 2:1.15.1-0ubuntu2.6
[deb_xorg-server.git] / debian / patches / CVE-2014-8xxx / 0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch
diff --git a/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch b/debian/patches/CVE-2014-8xxx/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch
new file mode 100644 (file)
index 0000000..421f070
--- /dev/null
@@ -0,0 +1,551 @@
+From 54fa1f815507cd27280f661be7a64f2f2e6c579e Mon Sep 17 00:00:00 2001
+From: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date: Sun, 26 Jan 2014 10:54:41 -0800
+Subject: [PATCH 08/33] Xi: unvalidated lengths in Xinput extension
+ [CVE-2014-8095]
+
+Multiple functions in the Xinput extension handling of requests from
+clients failed to check that the length of the request sent by the
+client was large enough to perform all the required operations and
+thus could read or write to memory outside the bounds of the request
+buffer.
+
+This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE
+macro in include/dix.h for the common case of needing to ensure a
+request is large enough to include both the request itself and a
+minimum amount of extra data following the request header.
+
+Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+---
+ Xi/chgdctl.c            |    8 ++++++--
+ Xi/chgfctl.c            |    2 ++
+ Xi/sendexev.c           |    3 +++
+ Xi/xiallowev.c          |    2 ++
+ Xi/xichangecursor.c     |    2 +-
+ Xi/xichangehierarchy.c  |   35 ++++++++++++++++++++++++++++++++---
+ Xi/xigetclientpointer.c |    1 +
+ Xi/xigrabdev.c          |    9 ++++++++-
+ Xi/xipassivegrab.c      |   12 ++++++++++--
+ Xi/xiproperty.c         |   14 ++++++--------
+ Xi/xiquerydevice.c      |    1 +
+ Xi/xiquerypointer.c     |    2 ++
+ Xi/xiselectev.c         |    8 ++++++++
+ Xi/xisetclientpointer.c |    3 ++-
+ Xi/xisetdevfocus.c      |    4 ++++
+ Xi/xiwarppointer.c      |    2 ++
+ include/dix.h           |    4 ++++
+ 17 files changed, 94 insertions(+), 18 deletions(-)
+
+diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c
+index d078aa2..b3ee867 100644
+--- a/Xi/chgdctl.c
++++ b/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);
+@@ -192,6 +192,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/Xi/chgfctl.c b/Xi/chgfctl.c
+index 6dcf60c..224c2ba 100644
+--- a/Xi/chgfctl.c
++++ b/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/Xi/sendexev.c b/Xi/sendexev.c
+index 3c21386..183f88d 100644
+--- a/Xi/sendexev.c
++++ b/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/Xi/xiallowev.c b/Xi/xiallowev.c
+index ebef233..ca263ef 100644
+--- a/Xi/xiallowev.c
++++ b/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/Xi/xichangecursor.c b/Xi/xichangecursor.c
+index 7a1bb7a..8e6255b 100644
+--- a/Xi/xichangecursor.c
++++ b/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/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
+index 9e36354..2732445 100644
+--- a/Xi/xichangehierarchy.c
++++ b/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/Xi/xigetclientpointer.c b/Xi/xigetclientpointer.c
+index 3c90d58..306dd39 100644
+--- a/Xi/xigetclientpointer.c
++++ b/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/Xi/xigrabdev.c b/Xi/xigrabdev.c
+index 63d95bc..e2a2ae3 100644
+--- a/Xi/xigrabdev.c
++++ b/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)
+@@ -131,6 +136,7 @@ int
+ SProcXIUngrabDevice(ClientPtr client)
+ {
+     REQUEST(xXIUngrabDeviceReq);
++    REQUEST_SIZE_MATCH(xXIUngrabDeviceReq);
+     swaps(&stuff->length);
+     swaps(&stuff->deviceid);
+@@ -148,6 +154,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/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
+index 700622d..9241ffd 100644
+--- a/Xi/xipassivegrab.c
++++ b/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++) {
+@@ -92,7 +95,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);
+     if (stuff->deviceid == XIAllDevices)
+         dev = inputInfo.all_devices;
+@@ -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/Xi/xiproperty.c b/Xi/xiproperty.c
+index 463607d..8e8e4b0 100644
+--- a/Xi/xiproperty.c
++++ b/Xi/xiproperty.c
+@@ -1013,10 +1013,9 @@ int
+ SProcXListDeviceProperties(ClientPtr client)
+ {
+     REQUEST(xListDevicePropertiesReq);
++    REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
+     swaps(&stuff->length);
+-
+-    REQUEST_SIZE_MATCH(xListDevicePropertiesReq);
+     return (ProcXListDeviceProperties(client));
+ }
+@@ -1037,10 +1036,10 @@ int
+ SProcXDeleteDeviceProperty(ClientPtr client)
+ {
+     REQUEST(xDeleteDevicePropertyReq);
++    REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
+     swaps(&stuff->length);
+     swapl(&stuff->property);
+-    REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq);
+     return (ProcXDeleteDeviceProperty(client));
+ }
+@@ -1048,13 +1047,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));
+ }
+@@ -1253,11 +1252,10 @@ int
+ SProcXIListProperties(ClientPtr client)
+ {
+     REQUEST(xXIListPropertiesReq);
++    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+     swaps(&stuff->length);
+     swaps(&stuff->deviceid);
+-
+-    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+     return (ProcXIListProperties(client));
+ }
+@@ -1279,11 +1277,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));
+ }
+@@ -1291,6 +1289,7 @@ int
+ SProcXIGetProperty(ClientPtr client)
+ {
+     REQUEST(xXIGetPropertyReq);
++    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+     swaps(&stuff->length);
+     swaps(&stuff->deviceid);
+@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client)
+     swapl(&stuff->type);
+     swapl(&stuff->offset);
+     swapl(&stuff->len);
+-    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+     return (ProcXIGetProperty(client));
+ }
+diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
+index 4e544f0..67a9a4f 100644
+--- a/Xi/xiquerydevice.c
++++ b/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/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
+index e9bdd42..7ec0c85 100644
+--- a/Xi/xiquerypointer.c
++++ b/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/Xi/xiselectev.c b/Xi/xiselectev.c
+index 45a996e..168579f 100644
+--- a/Xi/xiselectev.c
++++ b/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/Xi/xisetclientpointer.c b/Xi/xisetclientpointer.c
+index 38ff51e..24d4a53 100644
+--- a/Xi/xisetclientpointer.c
++++ b/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/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c
+index 372ec24..96a9a16 100644
+--- a/Xi/xisetdevfocus.c
++++ b/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/Xi/xiwarppointer.c b/Xi/xiwarppointer.c
+index 3f051f7..780758a 100644
+--- a/Xi/xiwarppointer.c
++++ b/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);
+diff --git a/include/dix.h b/include/dix.h
+index e0c6ed8..21176a8 100644
+--- a/include/dix.h
++++ b/include/dix.h
+@@ -74,6 +74,10 @@ SOFTWARE.
+     if ((sizeof(req) >> 2) > client->req_len )\
+          return(BadLength)
++#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra)  \
++    if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
++         return(BadLength)
++
+ #define REQUEST_FIXED_SIZE(req, n)\
+     if (((sizeof(req) >> 2) > client->req_len) || \
+         ((n >> 2) >= client->req_len) || \
+-- 
+1.7.9.2
+