* gnu/packages/patches/libx11-CVE-2016-7942.patch,
gnu/packages/patches/libx11-CVE-2016-7943.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/xorg.scm (libx11)[replacement]: New field.
(libx11/fixed): New variable.
---
 gnu/local.mk                                    |   2 +
 gnu/packages/patches/libx11-CVE-2016-7942.patch |  76 ++++++++++++++++
 gnu/packages/patches/libx11-CVE-2016-7943.patch | 113 ++++++++++++++++++++++++
 gnu/packages/xorg.scm                           |   9 ++
 4 files changed, 200 insertions(+)
 create mode 100644 gnu/packages/patches/libx11-CVE-2016-7942.patch
 create mode 100644 gnu/packages/patches/libx11-CVE-2016-7943.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index a609bf6..03d07f6 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -669,6 +669,8 @@ dist_patch_DATA =                                           
\
   %D%/packages/patches/libwmf-CVE-2015-0848+CVE-2015-4588.patch        \
   %D%/packages/patches/libwmf-CVE-2015-4695.patch              \
   %D%/packages/patches/libwmf-CVE-2015-4696.patch              \
+  %D%/packages/patches/libx11-CVE-2016-7942.patch              \
+  %D%/packages/patches/libx11-CVE-2016-7943.patch              \
   %D%/packages/patches/libxslt-generated-ids.patch             \
   %D%/packages/patches/lirc-localstatedir.patch                        \
   %D%/packages/patches/llvm-for-extempore.patch                        \
diff --git a/gnu/packages/patches/libx11-CVE-2016-7942.patch 
b/gnu/packages/patches/libx11-CVE-2016-7942.patch
new file mode 100644
index 0000000..7577023
--- /dev/null
+++ b/gnu/packages/patches/libx11-CVE-2016-7942.patch
@@ -0,0 +1,76 @@
+Fix CVE-2016-7942:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7942
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libX11/commit/?id=8ea762f94f4c942d898fdeb590a1630c83235c17
+
+From 8ea762f94f4c942d898fdeb590a1630c83235c17 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tob...@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:25:25 +0200
+Subject: [PATCH] Validation of server responses in XGetImage()
+
+Check if enough bytes were received for specified image type and
+geometry. Otherwise GetPixel and other functions could trigger an
+out of boundary read later on.
+
+Signed-off-by: Tobias Stoeckmann <tob...@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matth...@herrb.eu>
+---
+ src/GetImage.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/src/GetImage.c b/src/GetImage.c
+index c461abc..ff32d58 100644
+--- a/src/GetImage.c
++++ b/src/GetImage.c
+@@ -59,6 +59,7 @@ XImage *XGetImage (
+       char *data;
+       unsigned long nbytes;
+       XImage *image;
++      int planes;
+       LockDisplay(dpy);
+       GetReq (GetImage, req);
+       /*
+@@ -91,18 +92,28 @@ XImage *XGetImage (
+           return (XImage *) NULL;
+       }
+         _XReadPad (dpy, data, nbytes);
+-        if (format == XYPixmap)
+-         image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual),
+-                Ones (plane_mask &
+-                      (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))),
+-                format, 0, data, width, height, dpy->bitmap_pad, 0);
+-      else /* format == ZPixmap */
+-           image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual),
+-               rep.depth, ZPixmap, 0, data, width, height,
+-                _XGetScanlinePad(dpy, (int) rep.depth), 0);
++        if (format == XYPixmap) {
++          image = XCreateImage(dpy, _XVIDtoVisual(dpy, rep.visual),
++              Ones (plane_mask &
++                  (((unsigned long)0xFFFFFFFF) >> (32 - rep.depth))),
++              format, 0, data, width, height, dpy->bitmap_pad, 0);
++          planes = image->depth;
++      } else { /* format == ZPixmap */
++            image = XCreateImage (dpy, _XVIDtoVisual(dpy, rep.visual),
++              rep.depth, ZPixmap, 0, data, width, height,
++                  _XGetScanlinePad(dpy, (int) rep.depth), 0);
++          planes = 1;
++      }
+ 
+       if (!image)
+           Xfree(data);
++      if (planes < 1 || image->height < 1 || image->bytes_per_line < 1 ||
++          INT_MAX / image->height <= image->bytes_per_line ||
++          INT_MAX / planes <= image->height * image->bytes_per_line ||
++          nbytes < planes * image->height * image->bytes_per_line) {
++          XDestroyImage(image);
++          image = NULL;
++      }
+       UnlockDisplay(dpy);
+       SyncHandle();
+       return (image);
+-- 
+2.10.1
+
diff --git a/gnu/packages/patches/libx11-CVE-2016-7943.patch 
b/gnu/packages/patches/libx11-CVE-2016-7943.patch
new file mode 100644
index 0000000..7bcbc58
--- /dev/null
+++ b/gnu/packages/patches/libx11-CVE-2016-7943.patch
@@ -0,0 +1,113 @@
+Fix CVE-2016-7943:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7943.
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libX11/commit/?id=8c29f1607a31dac0911e45a0dd3d74173822b3c9
+
+From 8c29f1607a31dac0911e45a0dd3d74173822b3c9 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tob...@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:22:57 +0200
+Subject: [PATCH] The validation of server responses avoids out of boundary
+ accesses.
+
+v2: FontNames.c  return a NULL list whenever a single
+length field from the server is incohent.
+
+Signed-off-by: Tobias Stoeckmann <tob...@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matth...@herrb.eu>
+---
+ src/FontNames.c | 23 +++++++++++++++++------
+ src/ListExt.c   | 12 ++++++++----
+ src/ModMap.c    |  3 ++-
+ 3 files changed, 27 insertions(+), 11 deletions(-)
+
+diff --git a/src/FontNames.c b/src/FontNames.c
+index 21dcafe..e55f338 100644
+--- a/src/FontNames.c
++++ b/src/FontNames.c
+@@ -66,7 +66,7 @@ int *actualCount)    /* RETURN */
+ 
+     if (rep.nFonts) {
+       flist = Xmalloc (rep.nFonts * sizeof(char *));
+-      if (rep.length < (INT_MAX >> 2)) {
++      if (rep.length > 0 && rep.length < (INT_MAX >> 2)) {
+           rlen = rep.length << 2;
+           ch = Xmalloc(rlen + 1);
+           /* +1 to leave room for last null-terminator */
+@@ -93,11 +93,22 @@ int *actualCount)  /* RETURN */
+           if (ch + length < chend) {
+               flist[i] = ch + 1;  /* skip over length */
+               ch += length + 1;  /* find next length ... */
+-              length = *(unsigned char *)ch;
+-              *ch = '\0';  /* and replace with null-termination */
+-              count++;
+-          } else
+-              flist[i] = NULL;
++              if (ch <= chend) {
++                  length = *(unsigned char *)ch;
++                  *ch = '\0';  /* and replace with null-termination */
++                  count++;
++              } else {
++                    Xfree(flist);
++                    flist = NULL;
++                    count = 0;
++                    break;
++              }
++          } else {
++                Xfree(flist);
++                flist = NULL;
++                count = 0;
++                break;
++            }
+       }
+     }
+     *actualCount = count;
+diff --git a/src/ListExt.c b/src/ListExt.c
+index be6b989..0516e45 100644
+--- a/src/ListExt.c
++++ b/src/ListExt.c
+@@ -55,7 +55,7 @@ char **XListExtensions(
+ 
+       if (rep.nExtensions) {
+           list = Xmalloc (rep.nExtensions * sizeof (char *));
+-          if (rep.length < (INT_MAX >> 2)) {
++          if (rep.length > 0 && rep.length < (INT_MAX >> 2)) {
+               rlen = rep.length << 2;
+               ch = Xmalloc (rlen + 1);
+                 /* +1 to leave room for last null-terminator */
+@@ -80,9 +80,13 @@ char **XListExtensions(
+               if (ch + length < chend) {
+                   list[i] = ch+1;  /* skip over length */
+                   ch += length + 1; /* find next length ... */
+-                  length = *ch;
+-                  *ch = '\0'; /* and replace with null-termination */
+-                  count++;
++                  if (ch <= chend) {
++                      length = *ch;
++                      *ch = '\0'; /* and replace with null-termination */
++                      count++;
++                  } else {
++                      list[i] = NULL;
++                  }
+               } else
+                   list[i] = NULL;
+           }
+diff --git a/src/ModMap.c b/src/ModMap.c
+index a809aa2..49a5d08 100644
+--- a/src/ModMap.c
++++ b/src/ModMap.c
+@@ -42,7 +42,8 @@ XGetModifierMapping(register Display *dpy)
+     GetEmptyReq(GetModifierMapping, req);
+     (void) _XReply (dpy, (xReply *)&rep, 0, xFalse);
+ 
+-    if (rep.length < (INT_MAX >> 2)) {
++    if (rep.length < (INT_MAX >> 2) &&
++      (rep.length >> 1) == rep.numKeyPerModifier) {
+       nbytes = (unsigned long)rep.length << 2;
+       res = Xmalloc(sizeof (XModifierKeymap));
+       if (res)
+-- 
+2.10.1
+
diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm
index 0d3cdce..83dfd5d 100644
--- a/gnu/packages/xorg.scm
+++ b/gnu/packages/xorg.scm
@@ -5181,6 +5181,7 @@ draggable titlebars and borders.")
 (define-public libx11
   (package
     (name "libx11")
+    (replacement libx11/fixed)
     (version "1.6.3")
     (source
       (origin
@@ -5213,6 +5214,14 @@ draggable titlebars and borders.")
     (description "Xorg Core X11 protocol client library.")
     (license license:x11)))
 
+(define libx11/fixed
+  (package
+    (inherit libx11)
+    (source (origin
+              (inherit (package-source libx11))
+              (patches (search-patches
+                         "libx11-CVE-2016-7942.patch"
+                         "libx11-CVE-2016-7943.patch"))))))
 
 ;; packages of height 5 in the propagated-inputs tree
 
-- 
2.10.1


Reply via email to