Blame SOURCES/0001-xkb-Check-strings-length-against-request-size.patch

c8093e
From ab0fd32fb12b2153177dd101976c9dd23793b947 Mon Sep 17 00:00:00 2001
c8093e
From: Olivier Fourdan <ofourdan@redhat.com>
c8093e
Date: Fri, 16 Jan 2015 08:44:45 +0100
c8093e
Subject: [PATCH] xkb: Check strings length against request size
c8093e
c8093e
Ensure that the given strings length in an XkbSetGeometry request remain
c8093e
within the limits of the size of the request.
c8093e
c8093e
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
c8093e
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
c8093e
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
c8093e
---
c8093e
 xkb/xkb.c | 65 +++++++++++++++++++++++++++++++++++++++------------------------
c8093e
 1 file changed, 40 insertions(+), 25 deletions(-)
c8093e
c8093e
diff --git a/xkb/xkb.c b/xkb/xkb.c
c8093e
index b9a3ac4..f3988f9 100644
c8093e
--- a/xkb/xkb.c
c8093e
+++ b/xkb/xkb.c
c8093e
@@ -4957,25 +4957,29 @@ ProcXkbGetGeometry(ClientPtr client)
c8093e
 
c8093e
 /***====================================================================***/
c8093e
 
c8093e
-static char *
c8093e
-_GetCountedString(char **wire_inout, Bool swap)
c8093e
+static Status
c8093e
+_GetCountedString(char **wire_inout, ClientPtr client, char **str)
c8093e
 {
c8093e
-    char *wire, *str;
c8093e
+    char *wire, *next;
c8093e
     CARD16 len;
c8093e
 
c8093e
     wire = *wire_inout;
c8093e
     len = *(CARD16 *) wire;
c8093e
-    if (swap) {
c8093e
+    if (client->swapped) {
c8093e
         swaps(&len;;
c8093e
     }
c8093e
-    str = malloc(len + 1);
c8093e
-    if (str) {
c8093e
-        memcpy(str, &wire[2], len);
c8093e
-        str[len] = '\0';
c8093e
-    }
c8093e
-    wire += XkbPaddedSize(len + 2);
c8093e
-    *wire_inout = wire;
c8093e
-    return str;
c8093e
+    next = wire + XkbPaddedSize(len + 2);
c8093e
+    /* Check we're still within the size of the request */
c8093e
+    if (client->req_len <
c8093e
+        bytes_to_int32(next - (char *) client->requestBuffer))
c8093e
+        return BadValue;
c8093e
+    *str = malloc(len + 1);
c8093e
+    if (!*str)
c8093e
+        return BadAlloc;
c8093e
+    memcpy(*str, &wire[2], len);
c8093e
+    *(*str + len) = '\0';
c8093e
+    *wire_inout = next;
c8093e
+    return Success;
c8093e
 }
c8093e
 
c8093e
 static Status
c8093e
@@ -4987,6 +4991,7 @@ _CheckSetDoodad(char **wire_inout,
c8093e
     xkbAnyDoodadWireDesc any;
c8093e
     xkbTextDoodadWireDesc text;
c8093e
     XkbDoodadPtr doodad;
c8093e
+    Status status;
c8093e
 
c8093e
     dWire = (xkbDoodadWireDesc *) (*wire_inout);
c8093e
     any = dWire->any;
c8093e
@@ -5036,8 +5041,14 @@ _CheckSetDoodad(char **wire_inout,
c8093e
         doodad->text.width = text.width;
c8093e
         doodad->text.height = text.height;
c8093e
         doodad->text.color_ndx = dWire->text.colorNdx;
c8093e
-        doodad->text.text = _GetCountedString(&wire, client->swapped);
c8093e
-        doodad->text.font = _GetCountedString(&wire, client->swapped);
c8093e
+        status = _GetCountedString(&wire, client, &doodad->text.text);
c8093e
+        if (status != Success)
c8093e
+            return status;
c8093e
+        status = _GetCountedString(&wire, client, &doodad->text.font);
c8093e
+        if (status != Success) {
c8093e
+            free (doodad->text.text);
c8093e
+            return status;
c8093e
+        }
c8093e
         break;
c8093e
     case XkbIndicatorDoodad:
c8093e
         if (dWire->indicator.onColorNdx >= geom->num_colors) {
c8093e
@@ -5072,7 +5083,9 @@ _CheckSetDoodad(char **wire_inout,
c8093e
         }
c8093e
         doodad->logo.color_ndx = dWire->logo.colorNdx;
c8093e
         doodad->logo.shape_ndx = dWire->logo.shapeNdx;
c8093e
-        doodad->logo.logo_name = _GetCountedString(&wire, client->swapped);
c8093e
+        status = _GetCountedString(&wire, client, &doodad->logo.logo_name);
c8093e
+        if (status != Success)
c8093e
+            return status;
c8093e
         break;
c8093e
     default:
c8093e
         client->errorValue = _XkbErrCode2(0x4F, dWire->any.type);
c8093e
@@ -5304,18 +5317,20 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
c8093e
     char *wire;
c8093e
 
c8093e
     wire = (char *) &req[1];
c8093e
-    geom->label_font = _GetCountedString(&wire, client->swapped);
c8093e
+    status = _GetCountedString(&wire, client, &geom->label_font);
c8093e
+    if (status != Success)
c8093e
+        return status;
c8093e
 
c8093e
     for (i = 0; i < req->nProperties; i++) {
c8093e
         char *name, *val;
c8093e
 
c8093e
-        name = _GetCountedString(&wire, client->swapped);
c8093e
-        if (!name)
c8093e
-            return BadAlloc;
c8093e
-        val = _GetCountedString(&wire, client->swapped);
c8093e
-        if (!val) {
c8093e
+        status = _GetCountedString(&wire, client, &name);
c8093e
+        if (status != Success)
c8093e
+            return status;
c8093e
+        status = _GetCountedString(&wire, client, &val;;
c8093e
+        if (status != Success) {
c8093e
             free(name);
c8093e
-            return BadAlloc;
c8093e
+            return status;
c8093e
         }
c8093e
         if (XkbAddGeomProperty(geom, name, val) == NULL) {
c8093e
             free(name);
c8093e
@@ -5349,9 +5364,9 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client)
c8093e
     for (i = 0; i < req->nColors; i++) {
c8093e
         char *name;
c8093e
 
c8093e
-        name = _GetCountedString(&wire, client->swapped);
c8093e
-        if (!name)
c8093e
-            return BadAlloc;
c8093e
+        status = _GetCountedString(&wire, client, &name);
c8093e
+        if (status != Success)
c8093e
+            return status;
c8093e
         if (!XkbAddGeomColor(geom, name, geom->num_colors)) {
c8093e
             free(name);
c8093e
             return BadAlloc;
c8093e
-- 
c8093e
2.1.0
c8093e