xserver: Branch 'server-1.19-branch' - 3 commits

Adam Jackson ajax at kemper.freedesktop.org
Wed Oct 4 19:11:04 UTC 2017


 Xext/shm.c    |    1 +
 xkb/xkbtext.c |   42 +++++++++++++++++++++---------------------
 2 files changed, 22 insertions(+), 21 deletions(-)

New commits:
commit 8bd33a2db7337b2801fc630a57e36b6aeea219d9
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Jul 27 10:08:32 2017 -0700

    xkb: Handle xkb formated string output safely (CVE-2017-13723)
    
    Generating strings for XKB data used a single shared static buffer,
    which offered several opportunities for errors. Use a ring of
    resizable buffers instead, to avoid problems when strings end up
    longer than anticipated.
    
    Reviewed-by: Michal Srb <msrb at suse.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 94f11ca5cf011ef123bd222cabeaef6f424d76ac)

diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index ead2b1aee..d2a2567fc 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -47,23 +47,27 @@
 
 /***====================================================================***/
 
-#define	BUFFER_SIZE	512
-
-static char textBuffer[BUFFER_SIZE];
-static int tbNext = 0;
+#define NUM_BUFFER      8
+static struct textBuffer {
+    int size;
+    char *buffer;
+} textBuffer[NUM_BUFFER];
+static int textBufferIndex;
 
 static char *
 tbGetBuffer(unsigned size)
 {
-    char *rtrn;
+    struct textBuffer *tb;
 
-    if (size >= BUFFER_SIZE)
-        return NULL;
-    if ((BUFFER_SIZE - tbNext) <= size)
-        tbNext = 0;
-    rtrn = &textBuffer[tbNext];
-    tbNext += size;
-    return rtrn;
+    tb = &textBuffer[textBufferIndex];
+    textBufferIndex = (textBufferIndex + 1) % NUM_BUFFER;
+
+    if (size > tb->size) {
+        free(tb->buffer);
+        tb->buffer = xnfalloc(size);
+        tb->size = size;
+    }
+    return tb->buffer;
 }
 
 /***====================================================================***/
@@ -79,8 +83,6 @@ XkbAtomText(Atom atm, unsigned format)
         int len;
 
         len = strlen(atmstr) + 1;
-        if (len > BUFFER_SIZE)
-            len = BUFFER_SIZE - 2;
         rtrn = tbGetBuffer(len);
         strlcpy(rtrn, atmstr, len);
     }
@@ -128,8 +130,6 @@ XkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
     len = strlen(tmp) + 1;
     if (format == XkbCFile)
         len += 4;
-    if (len >= BUFFER_SIZE)
-        len = BUFFER_SIZE - 1;
     rtrn = tbGetBuffer(len);
     if (format == XkbCFile) {
         strcpy(rtrn, "vmod_");
@@ -140,6 +140,8 @@ XkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format)
     return rtrn;
 }
 
+#define VMOD_BUFFER_SIZE        512
+
 char *
 XkbVModMaskText(XkbDescPtr xkb,
                 unsigned modMask, unsigned mask, unsigned format)
@@ -147,7 +149,7 @@ XkbVModMaskText(XkbDescPtr xkb,
     register int i, bit;
     int len;
     char *mm, *rtrn;
-    char *str, buf[BUFFER_SIZE];
+    char *str, buf[VMOD_BUFFER_SIZE];
 
     if ((modMask == 0) && (mask == 0)) {
         rtrn = tbGetBuffer(5);
@@ -173,7 +175,7 @@ XkbVModMaskText(XkbDescPtr xkb,
                 len = strlen(tmp) + 1 + (str == buf ? 0 : 1);
                 if (format == XkbCFile)
                     len += 4;
-                if ((str - (buf + len)) <= BUFFER_SIZE) {
+                if ((str - (buf + len)) <= VMOD_BUFFER_SIZE) {
                     if (str != buf) {
                         if (format == XkbCFile)
                             *str++ = '|';
@@ -199,8 +201,6 @@ XkbVModMaskText(XkbDescPtr xkb,
         len = 0;
     if (str)
         len += strlen(str) + (mm == NULL ? 0 : 1);
-    if (len >= BUFFER_SIZE)
-        len = BUFFER_SIZE - 1;
     rtrn = tbGetBuffer(len + 1);
     rtrn[0] = '\0';
 
commit 3094c4c6d879215923f2183ecd048b4f5429b182
Author: Michal Srb <msrb at suse.com>
Date:   Thu Jul 27 11:54:26 2017 +0200

    xkb: Escape non-printable characters correctly.
    
    XkbStringText escapes non-printable characters using octal numbers. Such escape
    sequence would be at most 5 characters long ("\0123"), so it reserves 5 bytes
    in the buffer. Due to char->unsigned int conversion, it would print much longer
    string for negative numbers.
    
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit eaf1f72ed8994b708d94ec2de7b1a99f5c4a39b8)

diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c
index ffbc546b3..ead2b1aee 100644
--- a/xkb/xkbtext.c
+++ b/xkb/xkbtext.c
@@ -603,7 +603,7 @@ XkbStringText(char *str, unsigned format)
             }
             else {
                 *out++ = '0';
-                sprintf(out, "%o", *in);
+                sprintf(out, "%o", (unsigned char) *in);
                 while (*out != '\0')
                     out++;
             }
commit a510fb811100bc27f0bfafe5d073998551161819
Author: Michal Srb <msrb at suse.com>
Date:   Fri Jul 28 16:27:10 2017 +0200

    Xext/shm: Validate shmseg resource id (CVE-2017-13721)
    
    Otherwise it can belong to a non-existing client and abort X server with
    FatalError "client not in use", or overwrite existing segment of another
    existing client.
    
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit b95f25af141d33a65f6f821ea9c003f66a01e1f1)

diff --git a/Xext/shm.c b/Xext/shm.c
index 1b622e353..c98d4a0c3 100644
--- a/Xext/shm.c
+++ b/Xext/shm.c
@@ -1238,6 +1238,7 @@ ProcShmCreateSegment(ClientPtr client)
     };
 
     REQUEST_SIZE_MATCH(xShmCreateSegmentReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
     if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) {
         client->errorValue = stuff->readOnly;
         return BadValue;


More information about the xorg-commit mailing list