aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorLeo Famulari <leo@famulari.name>2016-10-05 19:15:25 -0400
committerLeo Famulari <leo@famulari.name>2016-10-05 19:15:25 -0400
commitb19c7989b770f47011cd531a13c89002374dc3e0 (patch)
treeca0dccd3a677d4ac5237de87c9f78c31dbdaf148 /gnu/packages/patches
parent6524c1cfcf6088c5574e6ff21f540dfb22f944bf (diff)
parent145947608905d36f31227e87bebd7ed3a922e910 (diff)
downloadguix-b19c7989b770f47011cd531a13c89002374dc3e0.tar
guix-b19c7989b770f47011cd531a13c89002374dc3e0.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/cpio-gets-undeclared.patch45
-rw-r--r--gnu/packages/patches/gsl-test-i686.patch17
-rw-r--r--gnu/packages/patches/libx11-CVE-2016-7942.patch76
-rw-r--r--gnu/packages/patches/libx11-CVE-2016-7943.patch113
-rw-r--r--gnu/packages/patches/libxfixes-CVE-2016-7944.patch62
-rw-r--r--gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch420
-rw-r--r--gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch447
-rw-r--r--gnu/packages/patches/libxrender-CVE-2016-7949.patch66
-rw-r--r--gnu/packages/patches/libxrender-CVE-2016-7950.patch73
-rw-r--r--gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch152
-rw-r--r--gnu/packages/patches/libxv-CVE-2016-5407.patch162
-rw-r--r--gnu/packages/patches/libxvmc-CVE-2016-7953.patch42
-rw-r--r--gnu/packages/patches/metabat-remove-compilation-date.patch16
-rw-r--r--gnu/packages/patches/rush-CVE-2013-6889.patch23
14 files changed, 1646 insertions, 68 deletions
diff --git a/gnu/packages/patches/cpio-gets-undeclared.patch b/gnu/packages/patches/cpio-gets-undeclared.patch
deleted file mode 100644
index bc34de6455..0000000000
--- a/gnu/packages/patches/cpio-gets-undeclared.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-This patch is needed to allow builds with newer versions of
-the GNU libc (2.16+).
-
-The upstream fix was:
-
- commit 66712c23388e93e5c518ebc8515140fa0c807348
- Author: Eric Blake <eblake@redhat.com>
- Date: Thu Mar 29 13:30:41 2012 -0600
-
- stdio: don't assume gets any more
-
- Gnulib intentionally does not have a gets module, and now that C11
- and glibc have dropped it, we should be more proactive about warning
- any user on a platform that still has a declaration of this dangerous
- interface.
-
- * m4/stdio_h.m4 (gl_STDIO_H, gl_STDIO_H_DEFAULTS): Drop gets
- support.
- * modules/stdio (Makefile.am): Likewise.
- * lib/stdio-read.c (gets): Likewise.
- * tests/test-stdio-c++.cc: Likewise.
- * m4/warn-on-use.m4 (gl_WARN_ON_USE_PREPARE): Fix comment.
- * lib/stdio.in.h (gets): Make warning occur in more places.
- * doc/posix-functions/gets.texi (gets): Update documentation.
- Reported by Christer Solskogen.
-
- Signed-off-by: Eric Blake <eblake@redhat.com>
-
-This patch just gets rid of the offending part.
-
---- cpio-2.11/gnu/stdio.in.h-orig 2012-11-25 22:17:06.000000000 +0400
-+++ cpio-2.11/gnu/stdio.in.h 2012-11-25 22:18:36.000000000 +0400
-@@ -135,12 +135,6 @@
- "use gnulib module fflush for portable POSIX compliance");
- #endif
-
--/* It is very rare that the developer ever has full control of stdin,
-- so any use of gets warrants an unconditional warning. Assume it is
-- always declared, since it is required by C89. */
--#undef gets
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
--
- #if @GNULIB_FOPEN@
- # if @REPLACE_FOPEN@
- # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/gnu/packages/patches/gsl-test-i686.patch b/gnu/packages/patches/gsl-test-i686.patch
new file mode 100644
index 0000000000..8828c08614
--- /dev/null
+++ b/gnu/packages/patches/gsl-test-i686.patch
@@ -0,0 +1,17 @@
+Work around a test failure due to a rounding issue on 32-bit
+platforms, as reported at:
+
+ https://lists.gnu.org/archive/html/bug-gsl/2016-10/msg00000.html
+
+--- gsl-2.2.1/linalg/test.c 2016-10-05 13:27:42.464059730 +0200
++++ gsl-2.2.1/linalg/test.c 2016-10-05 13:27:46.988095882 +0200
+@@ -4843,9 +4843,6 @@ main(void)
+ gsl_test(test_cholesky_decomp_unit(), "Cholesky Decomposition [unit triangular]");
+ gsl_test(test_cholesky_solve(), "Cholesky Solve");
+
+- gsl_test(test_cholesky_decomp(r), "Cholesky Decomposition");
+- gsl_test(test_cholesky_invert(r), "Cholesky Inverse");
+- gsl_test(test_pcholesky_decomp(r), "Pivoted Cholesky Decomposition");
+ gsl_test(test_pcholesky_solve(r), "Pivoted Cholesky Solve");
+ gsl_test(test_pcholesky_invert(r), "Pivoted Cholesky Inverse");
+ gsl_test(test_mcholesky_decomp(r), "Modified Cholesky Decomposition");
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 0000000000..75770235ef
--- /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 <tobias@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 <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@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 0000000000..7bcbc58dd4
--- /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 <tobias@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 <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@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/patches/libxfixes-CVE-2016-7944.patch b/gnu/packages/patches/libxfixes-CVE-2016-7944.patch
new file mode 100644
index 0000000000..2ce463fc46
--- /dev/null
+++ b/gnu/packages/patches/libxfixes-CVE-2016-7944.patch
@@ -0,0 +1,62 @@
+Fix CVE-2016-7944:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7944
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXfixes/commit/?id=61c1039ee23a2d1de712843bed3480654d7ef42e
+
+From 61c1039ee23a2d1de712843bed3480654d7ef42e Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 22:38:44 +0200
+Subject: [PATCH] Integer overflow on illegal server response
+
+The 32 bit field "rep.length" is not checked for validity, which allows
+an integer overflow on 32 bit systems.
+
+A malicious server could send INT_MAX as length, which gets multiplied
+by the size of XRectangle. In that case the client won't read the whole
+data from server, getting out of sync.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/Region.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/src/Region.c b/src/Region.c
+index cb0cf6e..59bcc1a 100644
+--- a/src/Region.c
++++ b/src/Region.c
+@@ -23,6 +23,7 @@
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
++#include <limits.h>
+ #include "Xfixesint.h"
+
+ XserverRegion
+@@ -333,9 +334,17 @@ XFixesFetchRegionAndBounds (Display *dpy,
+ bounds->y = rep.y;
+ bounds->width = rep.width;
+ bounds->height = rep.height;
+- nbytes = (long) rep.length << 2;
+- nrects = rep.length >> 1;
+- rects = Xmalloc (nrects * sizeof (XRectangle));
++
++ if (rep.length < (INT_MAX >> 2)) {
++ nbytes = (long) rep.length << 2;
++ nrects = rep.length >> 1;
++ rects = Xmalloc (nrects * sizeof (XRectangle));
++ } else {
++ nbytes = 0;
++ nrects = 0;
++ rects = NULL;
++ }
++
+ if (!rects)
+ {
+ _XEatDataWords(dpy, rep.length);
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch b/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch
new file mode 100644
index 0000000000..ca899e34c0
--- /dev/null
+++ b/gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch
@@ -0,0 +1,420 @@
+Fix CVE-2016-7945:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7945
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXi/commit/?id=19a9cd607de73947fcfb104682f203ffe4e1f4e5
+
+From 19a9cd607de73947fcfb104682f203ffe4e1f4e5 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 22:31:34 +0200
+Subject: [PATCH] Properly validate server responses.
+
+By validating length fields from server responses, out of boundary
+accesses and endless loops can be mitigated.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/XGMotion.c | 3 ++-
+ src/XGetBMap.c | 3 ++-
+ src/XGetDCtl.c | 6 ++++--
+ src/XGetFCtl.c | 7 ++++++-
+ src/XGetKMap.c | 14 +++++++++++---
+ src/XGetMMap.c | 11 +++++++++--
+ src/XIQueryDevice.c | 36 ++++++++++++++++++++++++++++++++++--
+ src/XListDev.c | 21 +++++++++++++++------
+ src/XOpenDev.c | 13 ++++++++++---
+ src/XQueryDv.c | 8 ++++++--
+ 10 files changed, 99 insertions(+), 23 deletions(-)
+
+diff --git a/src/XGMotion.c b/src/XGMotion.c
+index 7785843..9433e29 100644
+--- a/src/XGMotion.c
++++ b/src/XGMotion.c
+@@ -114,7 +114,8 @@ XGetDeviceMotionEvents(
+ }
+ /* rep.axes is a CARD8, so assume max number of axes for bounds check */
+ if (rep.nEvents <
+- (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int))))) {
++ (INT_MAX / (sizeof(XDeviceTimeCoord) + (UCHAR_MAX * sizeof(int)))) &&
++ rep.nEvents * (rep.axes + 1) <= rep.length) {
+ size_t bsize = rep.nEvents *
+ (sizeof(XDeviceTimeCoord) + (rep.axes * sizeof(int)));
+ bufp = Xmalloc(bsize);
+diff --git a/src/XGetBMap.c b/src/XGetBMap.c
+index 002daba..13bb8c6 100644
+--- a/src/XGetBMap.c
++++ b/src/XGetBMap.c
+@@ -92,7 +92,8 @@ XGetDeviceButtonMapping(
+
+ status = _XReply(dpy, (xReply *) & rep, 0, xFalse);
+ if (status == 1) {
+- if (rep.length <= (sizeof(mapping) >> 2)) {
++ if (rep.length <= (sizeof(mapping) >> 2) &&
++ rep.nElts <= (rep.length << 2)) {
+ unsigned long nbytes = rep.length << 2;
+ _XRead(dpy, (char *)mapping, nbytes);
+
+diff --git a/src/XGetDCtl.c b/src/XGetDCtl.c
+index c5d3b53..7f6b396 100644
+--- a/src/XGetDCtl.c
++++ b/src/XGetDCtl.c
+@@ -93,7 +93,8 @@ XGetDeviceControl(
+ if (rep.length > 0) {
+ unsigned long nbytes;
+ size_t size = 0;
+- if (rep.length < (INT_MAX >> 2)) {
++ if (rep.length < (INT_MAX >> 2) &&
++ (rep.length << 2) >= sizeof(xDeviceState)) {
+ nbytes = (unsigned long) rep.length << 2;
+ d = Xmalloc(nbytes);
+ }
+@@ -117,7 +118,8 @@ XGetDeviceControl(
+ size_t val_size;
+
+ r = (xDeviceResolutionState *) d;
+- if (r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
++ if (sizeof(xDeviceResolutionState) > nbytes ||
++ r->num_valuators >= (INT_MAX / (3 * sizeof(int))))
+ goto out;
+ val_size = 3 * sizeof(int) * r->num_valuators;
+ if ((sizeof(xDeviceResolutionState) + val_size) > nbytes)
+diff --git a/src/XGetFCtl.c b/src/XGetFCtl.c
+index 7fd6d0e..82dcc64 100644
+--- a/src/XGetFCtl.c
++++ b/src/XGetFCtl.c
+@@ -73,6 +73,7 @@ XGetFeedbackControl(
+ XFeedbackState *Sav = NULL;
+ xFeedbackState *f = NULL;
+ xFeedbackState *sav = NULL;
++ char *end = NULL;
+ xGetFeedbackControlReq *req;
+ xGetFeedbackControlReply rep;
+ XExtDisplayInfo *info = XInput_find_display(dpy);
+@@ -105,10 +106,12 @@ XGetFeedbackControl(
+ goto out;
+ }
+ sav = f;
++ end = (char *)f + nbytes;
+ _XRead(dpy, (char *)f, nbytes);
+
+ for (i = 0; i < *num_feedbacks; i++) {
+- if (f->length > nbytes)
++ if ((char *)f + sizeof(*f) > end ||
++ f->length == 0 || f->length > nbytes)
+ goto out;
+ nbytes -= f->length;
+
+@@ -125,6 +128,8 @@ XGetFeedbackControl(
+ case StringFeedbackClass:
+ {
+ xStringFeedbackState *strf = (xStringFeedbackState *) f;
++ if ((char *)f + sizeof(*strf) > end)
++ goto out;
+ size += sizeof(XStringFeedbackState) +
+ (strf->num_syms_supported * sizeof(KeySym));
+ }
+diff --git a/src/XGetKMap.c b/src/XGetKMap.c
+index 0540ce4..008a72b 100644
+--- a/src/XGetKMap.c
++++ b/src/XGetKMap.c
+@@ -54,6 +54,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -93,9 +94,16 @@ XGetDeviceKeyMapping(register Display * dpy, XDevice * dev,
+ return (KeySym *) NULL;
+ }
+ if (rep.length > 0) {
+- *syms_per_code = rep.keySymsPerKeyCode;
+- nbytes = (long)rep.length << 2;
+- mapping = (KeySym *) Xmalloc((unsigned)nbytes);
++ if (rep.length < INT_MAX >> 2 &&
++ rep.length == rep.keySymsPerKeyCode * keycount) {
++ *syms_per_code = rep.keySymsPerKeyCode;
++ nbytes = (long)rep.length << 2;
++ mapping = (KeySym *) Xmalloc((unsigned)nbytes);
++ } else {
++ *syms_per_code = 0;
++ nbytes = 0;
++ mapping = NULL;
++ }
+ if (mapping)
+ _XRead(dpy, (char *)mapping, nbytes);
+ else
+diff --git a/src/XGetMMap.c b/src/XGetMMap.c
+index 246698c..33c114f 100644
+--- a/src/XGetMMap.c
++++ b/src/XGetMMap.c
+@@ -53,6 +53,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -85,8 +86,14 @@ XGetDeviceModifierMapping(
+ SyncHandle();
+ return (XModifierKeymap *) NULL;
+ }
+- nbytes = (unsigned long)rep.length << 2;
+- res = (XModifierKeymap *) Xmalloc(sizeof(XModifierKeymap));
++ if (rep.length < (INT_MAX >> 2) &&
++ rep.numKeyPerModifier == rep.length >> 1) {
++ nbytes = (unsigned long)rep.length << 2;
++ res = (XModifierKeymap *) Xmalloc(sizeof(XModifierKeymap));
++ } else {
++ nbytes = 0;
++ res = NULL;
++ }
+ if (res) {
+ res->modifiermap = (KeyCode *) Xmalloc(nbytes);
+ if (res->modifiermap)
+diff --git a/src/XIQueryDevice.c b/src/XIQueryDevice.c
+index fb8504f..a457cd6 100644
+--- a/src/XIQueryDevice.c
++++ b/src/XIQueryDevice.c
+@@ -26,6 +26,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdint.h>
+ #include <X11/Xlibint.h>
+ #include <X11/extensions/XI2proto.h>
+@@ -43,6 +44,7 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ xXIQueryDeviceReq *req;
+ xXIQueryDeviceReply reply;
+ char *ptr;
++ char *end;
+ int i;
+ char *buf;
+
+@@ -60,14 +62,24 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ if (!_XReply(dpy, (xReply*) &reply, 0, xFalse))
+ goto error;
+
+- *ndevices_return = reply.num_devices;
+- info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo));
++ if (reply.length < INT_MAX / 4)
++ {
++ *ndevices_return = reply.num_devices;
++ info = Xmalloc((reply.num_devices + 1) * sizeof(XIDeviceInfo));
++ }
++ else
++ {
++ *ndevices_return = 0;
++ info = NULL;
++ }
++
+ if (!info)
+ goto error;
+
+ buf = Xmalloc(reply.length * 4);
+ _XRead(dpy, buf, reply.length * 4);
+ ptr = buf;
++ end = buf + reply.length * 4;
+
+ /* info is a null-terminated array */
+ info[reply.num_devices].name = NULL;
+@@ -79,6 +91,9 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ XIDeviceInfo *lib = &info[i];
+ xXIDeviceInfo *wire = (xXIDeviceInfo*)ptr;
+
++ if (ptr + sizeof(xXIDeviceInfo) > end)
++ goto error_loop;
++
+ lib->deviceid = wire->deviceid;
+ lib->use = wire->use;
+ lib->attachment = wire->attachment;
+@@ -87,12 +102,23 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+
+ ptr += sizeof(xXIDeviceInfo);
+
++ if (ptr + wire->name_len > end)
++ goto error_loop;
++
+ lib->name = Xcalloc(wire->name_len + 1, 1);
++ if (lib->name == NULL)
++ goto error_loop;
+ strncpy(lib->name, ptr, wire->name_len);
++ lib->name[wire->name_len] = '\0';
+ ptr += ((wire->name_len + 3)/4) * 4;
+
+ sz = size_classes((xXIAnyInfo*)ptr, nclasses);
+ lib->classes = Xmalloc(sz);
++ if (lib->classes == NULL)
++ {
++ Xfree(lib->name);
++ goto error_loop;
++ }
+ ptr += copy_classes(lib, (xXIAnyInfo*)ptr, &nclasses);
+ /* We skip over unused classes */
+ lib->num_classes = nclasses;
+@@ -103,6 +129,12 @@ XIQueryDevice(Display *dpy, int deviceid, int *ndevices_return)
+ SyncHandle();
+ return info;
+
++error_loop:
++ while (--i >= 0)
++ {
++ Xfree(info[i].name);
++ Xfree(info[i].classes);
++ }
+ error:
+ UnlockDisplay(dpy);
+ error_unlocked:
+diff --git a/src/XListDev.c b/src/XListDev.c
+index b85ff3c..f850cd0 100644
+--- a/src/XListDev.c
++++ b/src/XListDev.c
+@@ -74,7 +74,7 @@ static int pad_to_xid(int base_size)
+ }
+
+ static size_t
+-SizeClassInfo(xAnyClassPtr *any, int num_classes)
++SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes)
+ {
+ int size = 0;
+ int j;
+@@ -90,6 +90,8 @@ SizeClassInfo(xAnyClassPtr *any, int num_classes)
+ {
+ xValuatorInfoPtr v;
+
++ if (len < sizeof(v))
++ return 0;
+ v = (xValuatorInfoPtr) *any;
+ size += pad_to_xid(sizeof(XValuatorInfo) +
+ (v->num_axes * sizeof(XAxisInfo)));
+@@ -98,6 +100,8 @@ SizeClassInfo(xAnyClassPtr *any, int num_classes)
+ default:
+ break;
+ }
++ if ((*any)->length > len)
++ return 0;
+ *any = (xAnyClassPtr) ((char *)(*any) + (*any)->length);
+ }
+
+@@ -170,7 +174,7 @@ XListInputDevices(
+ register Display *dpy,
+ int *ndevices)
+ {
+- size_t size;
++ size_t s, size;
+ xListInputDevicesReq *req;
+ xListInputDevicesReply rep;
+ xDeviceInfo *list, *slist = NULL;
+@@ -178,6 +182,7 @@ XListInputDevices(
+ XDeviceInfo *clist = NULL;
+ xAnyClassPtr any, sav_any;
+ XAnyClassPtr Any;
++ char *end = NULL;
+ unsigned char *nptr, *Nptr;
+ int i;
+ unsigned long rlen;
+@@ -213,16 +218,20 @@ XListInputDevices(
+
+ any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo)));
+ sav_any = any;
++ end = (char *)list + rlen;
+ for (i = 0; i < *ndevices; i++, list++) {
+- size += SizeClassInfo(&any, (int)list->num_classes);
++ s = SizeClassInfo(&any, end - (char *)any, (int)list->num_classes);
++ if (!s)
++ goto out;
++ size += s;
+ }
+
+- Nptr = ((unsigned char *)list) + rlen + 1;
++ Nptr = ((unsigned char *)list) + rlen;
+ for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) {
++ if (nptr >= Nptr)
++ goto out;
+ size += *nptr + 1;
+ nptr += (*nptr + 1);
+- if (nptr > Nptr)
+- goto out;
+ }
+
+ clist = (XDeviceInfoPtr) Xmalloc(size);
+diff --git a/src/XOpenDev.c b/src/XOpenDev.c
+index 029dec2..4b3c460 100644
+--- a/src/XOpenDev.c
++++ b/src/XOpenDev.c
+@@ -53,6 +53,7 @@ SOFTWARE.
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <X11/extensions/XI.h>
+ #include <X11/extensions/XIproto.h>
+ #include <X11/Xlibint.h>
+@@ -86,9 +87,15 @@ XOpenDevice(
+ return (XDevice *) NULL;
+ }
+
+- rlen = rep.length << 2;
+- dev = (XDevice *) Xmalloc(sizeof(XDevice) + rep.num_classes *
+- sizeof(XInputClassInfo));
++ if (rep.length < INT_MAX >> 2 &&
++ (rep.length << 2) >= rep.num_classes * sizeof(xInputClassInfo)) {
++ rlen = rep.length << 2;
++ dev = (XDevice *) Xmalloc(sizeof(XDevice) + rep.num_classes *
++ sizeof(XInputClassInfo));
++ } else {
++ rlen = 0;
++ dev = NULL;
++ }
+ if (dev) {
+ int dlen; /* data length */
+
+diff --git a/src/XQueryDv.c b/src/XQueryDv.c
+index de1c0e5..7ee2272 100644
+--- a/src/XQueryDv.c
++++ b/src/XQueryDv.c
+@@ -73,7 +73,7 @@ XQueryDeviceState(
+ xQueryDeviceStateReply rep;
+ XDeviceState *state = NULL;
+ XInputClass *any, *Any;
+- char *data = NULL;
++ char *data = NULL, *end = NULL;
+ XExtDisplayInfo *info = XInput_find_display(dpy);
+
+ LockDisplay(dpy);
+@@ -92,6 +92,7 @@ XQueryDeviceState(
+ if (rep.length < (INT_MAX >> 2)) {
+ rlen = (unsigned long) rep.length << 2;
+ data = Xmalloc(rlen);
++ end = data + rlen;
+ }
+ if (!data) {
+ _XEatDataWords(dpy, rep.length);
+@@ -100,7 +101,8 @@ XQueryDeviceState(
+ _XRead(dpy, data, rlen);
+
+ for (i = 0, any = (XInputClass *) data; i < (int)rep.num_classes; i++) {
+- if (any->length > rlen)
++ if ((char *)any + sizeof(XInputClass) > end ||
++ any->length == 0 || any->length > rlen)
+ goto out;
+ rlen -= any->length;
+
+@@ -114,6 +116,8 @@ XQueryDeviceState(
+ case ValuatorClass:
+ {
+ xValuatorState *v = (xValuatorState *) any;
++ if ((char *)any + sizeof(xValuatorState) > end)
++ goto out;
+ size += (sizeof(XValuatorState) +
+ (v->num_valuators * sizeof(int)));
+ }
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch b/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch
new file mode 100644
index 0000000000..ece8b18309
--- /dev/null
+++ b/gnu/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch
@@ -0,0 +1,447 @@
+Fix CVE-2016-7947 and CVE-2016-7948.
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7947
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7948
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXrandr/commit/?id=a0df3e1c7728205e5c7650b2e6dce684139254a6
+
+From a0df3e1c7728205e5c7650b2e6dce684139254a6 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 22:21:40 +0200
+Subject: [PATCH] Avoid out of boundary accesses on illegal responses
+
+The responses of the connected X server have to be properly checked
+to avoid out of boundary accesses that could otherwise be triggered
+by a malicious server.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/XrrConfig.c | 32 +++++++++++++--------
+ src/XrrCrtc.c | 83 ++++++++++++++++++++++++++++++++++++++++++-------------
+ src/XrrMonitor.c | 18 ++++++++++++
+ src/XrrOutput.c | 11 ++++++++
+ src/XrrProvider.c | 28 ++++++++++++++++---
+ src/XrrScreen.c | 52 ++++++++++++++++++++++------------
+ 6 files changed, 172 insertions(+), 52 deletions(-)
+
+diff --git a/src/XrrConfig.c b/src/XrrConfig.c
+index 2f0282b..e68c45a 100644
+--- a/src/XrrConfig.c
++++ b/src/XrrConfig.c
+@@ -29,6 +29,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -272,23 +273,30 @@ static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy,
+ rep.rate = 0;
+ rep.nrateEnts = 0;
+ }
++ if (rep.length < INT_MAX >> 2) {
++ nbytes = (long) rep.length << 2;
+
+- nbytes = (long) rep.length << 2;
++ nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
++ ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF(CARD16) */);
+
+- nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
+- ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */);
++ /*
++ * first we must compute how much space to allocate for
++ * randr library's use; we'll allocate the structures in a single
++ * allocation, on cleanlyness grounds.
++ */
+
+- /*
+- * first we must compute how much space to allocate for
+- * randr library's use; we'll allocate the structures in a single
+- * allocation, on cleanlyness grounds.
+- */
++ rbytes = sizeof (XRRScreenConfiguration) +
++ (rep.nSizes * sizeof (XRRScreenSize) +
++ rep.nrateEnts * sizeof (int));
+
+- rbytes = sizeof (XRRScreenConfiguration) +
+- (rep.nSizes * sizeof (XRRScreenSize) +
+- rep.nrateEnts * sizeof (int));
++ scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
++ } else {
++ nbytes = 0;
++ nbytesRead = 0;
++ rbytes = 0;
++ scp = NULL;
++ }
+
+- scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
+ if (scp == NULL) {
+ _XEatData (dpy, (unsigned long) nbytes);
+ return NULL;
+diff --git a/src/XrrCrtc.c b/src/XrrCrtc.c
+index 5ae35c5..6665092 100644
+--- a/src/XrrCrtc.c
++++ b/src/XrrCrtc.c
+@@ -24,6 +24,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -57,22 +58,33 @@ XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources, RRCrtc crtc)
+ return NULL;
+ }
+
+- nbytes = (long) rep.length << 2;
++ if (rep.length < INT_MAX >> 2)
++ {
++ nbytes = (long) rep.length << 2;
+
+- nbytesRead = (long) (rep.nOutput * 4 +
+- rep.nPossibleOutput * 4);
++ nbytesRead = (long) (rep.nOutput * 4 +
++ rep.nPossibleOutput * 4);
+
+- /*
+- * first we must compute how much space to allocate for
+- * randr library's use; we'll allocate the structures in a single
+- * allocation, on cleanlyness grounds.
+- */
++ /*
++ * first we must compute how much space to allocate for
++ * randr library's use; we'll allocate the structures in a single
++ * allocation, on cleanlyness grounds.
++ */
+
+- rbytes = (sizeof (XRRCrtcInfo) +
+- rep.nOutput * sizeof (RROutput) +
+- rep.nPossibleOutput * sizeof (RROutput));
++ rbytes = (sizeof (XRRCrtcInfo) +
++ rep.nOutput * sizeof (RROutput) +
++ rep.nPossibleOutput * sizeof (RROutput));
++
++ xci = (XRRCrtcInfo *) Xmalloc(rbytes);
++ }
++ else
++ {
++ nbytes = 0;
++ nbytesRead = 0;
++ rbytes = 0;
++ xci = NULL;
++ }
+
+- xci = (XRRCrtcInfo *) Xmalloc(rbytes);
+ if (xci == NULL) {
+ _XEatDataWords (dpy, rep.length);
+ UnlockDisplay (dpy);
+@@ -194,12 +206,21 @@ XRRGetCrtcGamma (Display *dpy, RRCrtc crtc)
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ goto out;
+
+- nbytes = (long) rep.length << 2;
++ if (rep.length < INT_MAX >> 2)
++ {
++ nbytes = (long) rep.length << 2;
+
+- /* three channels of CARD16 data */
+- nbytesRead = (rep.size * 2 * 3);
++ /* three channels of CARD16 data */
++ nbytesRead = (rep.size * 2 * 3);
+
+- crtc_gamma = XRRAllocGamma (rep.size);
++ crtc_gamma = XRRAllocGamma (rep.size);
++ }
++ else
++ {
++ nbytes = 0;
++ nbytesRead = 0;
++ crtc_gamma = NULL;
++ }
+
+ if (!crtc_gamma)
+ {
+@@ -357,7 +378,7 @@ XRRGetCrtcTransform (Display *dpy,
+ xRRGetCrtcTransformReq *req;
+ int major_version, minor_version;
+ XRRCrtcTransformAttributes *attr;
+- char *extra = NULL, *e;
++ char *extra = NULL, *end = NULL, *e;
+ int p;
+
+ *attributes = NULL;
+@@ -395,9 +416,17 @@ XRRGetCrtcTransform (Display *dpy,
+ else
+ {
+ int extraBytes = rep.length * 4 - CrtcTransformExtra;
+- extra = Xmalloc (extraBytes);
++ if (rep.length < INT_MAX / 4 &&
++ rep.length * 4 >= CrtcTransformExtra) {
++ extra = Xmalloc (extraBytes);
++ end = extra + extraBytes;
++ } else
++ extra = NULL;
+ if (!extra) {
+- _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2));
++ if (rep.length > (CrtcTransformExtra >> 2))
++ _XEatDataWords (dpy, rep.length - (CrtcTransformExtra >> 2));
++ else
++ _XEatDataWords (dpy, rep.length);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return False;
+@@ -429,22 +458,38 @@ XRRGetCrtcTransform (Display *dpy,
+
+ e = extra;
+
++ if (e + rep.pendingNbytesFilter > end) {
++ XFree (extra);
++ return False;
++ }
+ memcpy (attr->pendingFilter, e, rep.pendingNbytesFilter);
+ attr->pendingFilter[rep.pendingNbytesFilter] = '\0';
+ e += (rep.pendingNbytesFilter + 3) & ~3;
+ for (p = 0; p < rep.pendingNparamsFilter; p++) {
+ INT32 f;
++ if (e + 4 > end) {
++ XFree (extra);
++ return False;
++ }
+ memcpy (&f, e, 4);
+ e += 4;
+ attr->pendingParams[p] = (XFixed) f;
+ }
+ attr->pendingNparams = rep.pendingNparamsFilter;
+
++ if (e + rep.currentNbytesFilter > end) {
++ XFree (extra);
++ return False;
++ }
+ memcpy (attr->currentFilter, e, rep.currentNbytesFilter);
+ attr->currentFilter[rep.currentNbytesFilter] = '\0';
+ e += (rep.currentNbytesFilter + 3) & ~3;
+ for (p = 0; p < rep.currentNparamsFilter; p++) {
+ INT32 f;
++ if (e + 4 > end) {
++ XFree (extra);
++ return False;
++ }
+ memcpy (&f, e, 4);
+ e += 4;
+ attr->currentParams[p] = (XFixed) f;
+diff --git a/src/XrrMonitor.c b/src/XrrMonitor.c
+index a9eaa7b..adc5330 100644
+--- a/src/XrrMonitor.c
++++ b/src/XrrMonitor.c
+@@ -24,6 +24,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -65,6 +66,15 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors)
+ return NULL;
+ }
+
++ if (rep.length > INT_MAX >> 2 ||
++ rep.nmonitors > INT_MAX / SIZEOF(xRRMonitorInfo) ||
++ rep.noutputs > INT_MAX / 4 ||
++ rep.nmonitors * SIZEOF(xRRMonitorInfo) > INT_MAX - rep.noutputs * 4) {
++ _XEatData (dpy, rep.length);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
+ nbytes = (long) rep.length << 2;
+ nmon = rep.nmonitors;
+ noutput = rep.noutputs;
+@@ -111,6 +121,14 @@ XRRGetMonitors(Display *dpy, Window window, Bool get_active, int *nmonitors)
+ mon[m].outputs = output;
+ buf += SIZEOF (xRRMonitorInfo);
+ xoutput = (CARD32 *) buf;
++ if (xmon->noutput > rep.noutputs) {
++ Xfree(buf);
++ Xfree(mon);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
++ rep.noutputs -= xmon->noutput;
+ for (o = 0; o < xmon->noutput; o++)
+ output[o] = xoutput[o];
+ output += xmon->noutput;
+diff --git a/src/XrrOutput.c b/src/XrrOutput.c
+index 85f0b6e..30f3d40 100644
+--- a/src/XrrOutput.c
++++ b/src/XrrOutput.c
+@@ -25,6 +25,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -60,6 +61,16 @@ XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output)
+ return NULL;
+ }
+
++ if (rep.length > INT_MAX >> 2 || rep.length < (OutputInfoExtra >> 2))
++ {
++ if (rep.length > (OutputInfoExtra >> 2))
++ _XEatDataWords (dpy, rep.length - (OutputInfoExtra >> 2));
++ else
++ _XEatDataWords (dpy, rep.length);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
+ nbytes = ((long) (rep.length) << 2) - OutputInfoExtra;
+
+ nbytesRead = (long) (rep.nCrtcs * 4 +
+diff --git a/src/XrrProvider.c b/src/XrrProvider.c
+index 9e620c7..d796cd0 100644
+--- a/src/XrrProvider.c
++++ b/src/XrrProvider.c
+@@ -25,6 +25,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -59,12 +60,20 @@ XRRGetProviderResources(Display *dpy, Window window)
+ return NULL;
+ }
+
+- nbytes = (long) rep.length << 2;
++ if (rep.length < INT_MAX >> 2) {
++ nbytes = (long) rep.length << 2;
+
+- nbytesRead = (long) (rep.nProviders * 4);
++ nbytesRead = (long) (rep.nProviders * 4);
+
+- rbytes = (sizeof(XRRProviderResources) + rep.nProviders * sizeof(RRProvider));
+- xrpr = (XRRProviderResources *) Xmalloc(rbytes);
++ rbytes = (sizeof(XRRProviderResources) + rep.nProviders *
++ sizeof(RRProvider));
++ xrpr = (XRRProviderResources *) Xmalloc(rbytes);
++ } else {
++ nbytes = 0;
++ nbytesRead = 0;
++ rbytes = 0;
++ xrpr = NULL;
++ }
+
+ if (xrpr == NULL) {
+ _XEatDataWords (dpy, rep.length);
+@@ -121,6 +130,17 @@ XRRGetProviderInfo(Display *dpy, XRRScreenResources *resources, RRProvider provi
+ return NULL;
+ }
+
++ if (rep.length > INT_MAX >> 2 || rep.length < ProviderInfoExtra >> 2)
++ {
++ if (rep.length < ProviderInfoExtra >> 2)
++ _XEatDataWords (dpy, rep.length);
++ else
++ _XEatDataWords (dpy, rep.length - (ProviderInfoExtra >> 2));
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
++
+ nbytes = ((long) rep.length << 2) - ProviderInfoExtra;
+
+ nbytesRead = (long)(rep.nCrtcs * 4 +
+diff --git a/src/XrrScreen.c b/src/XrrScreen.c
+index b8ce7e5..1f7ffe6 100644
+--- a/src/XrrScreen.c
++++ b/src/XrrScreen.c
+@@ -24,6 +24,7 @@
+ #include <config.h>
+ #endif
+
++#include <limits.h>
+ #include <stdio.h>
+ #include <X11/Xlib.h>
+ /* we need to be able to manipulate the Display structure on events */
+@@ -105,27 +106,36 @@ doGetScreenResources (Display *dpy, Window window, int poll)
+ xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
+ }
+
+- nbytes = (long) rep.length << 2;
++ if (rep.length < INT_MAX >> 2) {
++ nbytes = (long) rep.length << 2;
+
+- nbytesRead = (long) (rep.nCrtcs * 4 +
+- rep.nOutputs * 4 +
+- rep.nModes * SIZEOF (xRRModeInfo) +
+- ((rep.nbytesNames + 3) & ~3));
++ nbytesRead = (long) (rep.nCrtcs * 4 +
++ rep.nOutputs * 4 +
++ rep.nModes * SIZEOF (xRRModeInfo) +
++ ((rep.nbytesNames + 3) & ~3));
+
+- /*
+- * first we must compute how much space to allocate for
+- * randr library's use; we'll allocate the structures in a single
+- * allocation, on cleanlyness grounds.
+- */
++ /*
++ * first we must compute how much space to allocate for
++ * randr library's use; we'll allocate the structures in a single
++ * allocation, on cleanlyness grounds.
++ */
++
++ rbytes = (sizeof (XRRScreenResources) +
++ rep.nCrtcs * sizeof (RRCrtc) +
++ rep.nOutputs * sizeof (RROutput) +
++ rep.nModes * sizeof (XRRModeInfo) +
++ rep.nbytesNames + rep.nModes); /* '\0' terminate names */
+
+- rbytes = (sizeof (XRRScreenResources) +
+- rep.nCrtcs * sizeof (RRCrtc) +
+- rep.nOutputs * sizeof (RROutput) +
+- rep.nModes * sizeof (XRRModeInfo) +
+- rep.nbytesNames + rep.nModes); /* '\0' terminate names */
++ xrsr = (XRRScreenResources *) Xmalloc(rbytes);
++ wire_names = (char *) Xmalloc (rep.nbytesNames);
++ } else {
++ nbytes = 0;
++ nbytesRead = 0;
++ rbytes = 0;
++ xrsr = NULL;
++ wire_names = NULL;
++ }
+
+- xrsr = (XRRScreenResources *) Xmalloc(rbytes);
+- wire_names = (char *) Xmalloc (rep.nbytesNames);
+ if (xrsr == NULL || wire_names == NULL) {
+ Xfree (xrsr);
+ Xfree (wire_names);
+@@ -174,6 +184,14 @@ doGetScreenResources (Display *dpy, Window window, int poll)
+ wire_name = wire_names;
+ for (i = 0; i < rep.nModes; i++) {
+ xrsr->modes[i].name = names;
++ if (xrsr->modes[i].nameLength > rep.nbytesNames) {
++ Xfree (xrsr);
++ Xfree (wire_names);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
++ rep.nbytesNames -= xrsr->modes[i].nameLength;
+ memcpy (names, wire_name, xrsr->modes[i].nameLength);
+ names[xrsr->modes[i].nameLength] = '\0';
+ names += xrsr->modes[i].nameLength + 1;
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxrender-CVE-2016-7949.patch b/gnu/packages/patches/libxrender-CVE-2016-7949.patch
new file mode 100644
index 0000000000..3a2be4ea8e
--- /dev/null
+++ b/gnu/packages/patches/libxrender-CVE-2016-7949.patch
@@ -0,0 +1,66 @@
+Fix CVE-2016-7949:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7949
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXrender/commit/?id=9362c7ddd1af3b168953d0737877bc52d79c94f4
+
+From 9362c7ddd1af3b168953d0737877bc52d79c94f4 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:43:09 +0200
+Subject: [PATCH] Validate lengths while parsing server data.
+
+Individual lengths inside received server data can overflow
+the previously reserved memory.
+
+It is therefore important to validate every single length
+field to not overflow the previously agreed sum of all invidual
+length fields.
+
+v2: consume remaining bytes in the reply buffer on error.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb@laas.fr
+---
+ src/Xrender.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/src/Xrender.c b/src/Xrender.c
+index 3102eb2..71cf3e6 100644
+--- a/src/Xrender.c
++++ b/src/Xrender.c
+@@ -533,12 +533,30 @@ XRenderQueryFormats (Display *dpy)
+ screen->fallback = _XRenderFindFormat (xri, xScreen->fallback);
+ screen->subpixel = SubPixelUnknown;
+ xDepth = (xPictDepth *) (xScreen + 1);
++ if (screen->ndepths > rep.numDepths) {
++ Xfree (xri);
++ Xfree (xData);
++ _XEatDataWords (dpy, rep.length);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return 0;
++ }
++ rep.numDepths -= screen->ndepths;
+ for (nd = 0; nd < screen->ndepths; nd++)
+ {
+ depth->depth = xDepth->depth;
+ depth->nvisuals = xDepth->nPictVisuals;
+ depth->visuals = visual;
+ xVisual = (xPictVisual *) (xDepth + 1);
++ if (depth->nvisuals > rep.numVisuals) {
++ Xfree (xri);
++ Xfree (xData);
++ _XEatDataWords (dpy, rep.length);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return 0;
++ }
++ rep.numVisuals -= depth->nvisuals;
+ for (nv = 0; nv < depth->nvisuals; nv++)
+ {
+ visual->visual = _XRenderFindVisual (dpy, xVisual->visual);
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxrender-CVE-2016-7950.patch b/gnu/packages/patches/libxrender-CVE-2016-7950.patch
new file mode 100644
index 0000000000..1a64b6e724
--- /dev/null
+++ b/gnu/packages/patches/libxrender-CVE-2016-7950.patch
@@ -0,0 +1,73 @@
+Fix CVE-2016-7950:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7950
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXrender/commit/?id=8fad00b0b647ee662ce4737ca15be033b7a21714
+
+From 8fad00b0b647ee662ce4737ca15be033b7a21714 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:42:09 +0200
+Subject: [PATCH] Avoid OOB write in XRenderQueryFilters
+
+The memory for filter names is reserved right after receiving the reply.
+After that, filters are iterated and each individual filter name is
+stored in that reserved memory.
+
+The individual name lengths are not checked for validity, which means
+that a malicious server can reserve less memory than it will write to
+during each iteration.
+
+v2: consume remaining bytes in reply buffer on error.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/Filter.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/Filter.c b/src/Filter.c
+index edfa572..8d701eb 100644
+--- a/src/Filter.c
++++ b/src/Filter.c
+@@ -38,7 +38,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
+ char *name;
+ char len;
+ int i;
+- unsigned long nbytes, nbytesAlias, nbytesName;
++ unsigned long nbytes, nbytesAlias, nbytesName, reply_left;
+
+ if (!RenderHasExtension (info))
+ return NULL;
+@@ -114,6 +114,7 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
+ * Read the filter aliases
+ */
+ _XRead16Pad (dpy, filters->alias, 2 * rep.numAliases);
++ reply_left = 8 + rep.length - 2 * rep.numAliases;;
+
+ /*
+ * Read the filter names
+@@ -122,9 +123,19 @@ XRenderQueryFilters (Display *dpy, Drawable drawable)
+ {
+ int l;
+ _XRead (dpy, &len, 1);
++ reply_left--;
+ l = len & 0xff;
++ if ((unsigned long)l + 1 > nbytesName) {
++ _XEatDataWords(dpy, reply_left);
++ Xfree(filters);
++ UnlockDisplay (dpy);
++ SyncHandle ();
++ return NULL;
++ }
++ nbytesName -= l + 1;
+ filters->filter[i] = name;
+ _XRead (dpy, name, l);
++ reply_left -= l;
+ name[l] = '\0';
+ name += l + 1;
+ }
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch b/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch
new file mode 100644
index 0000000000..9df6cf3f4d
--- /dev/null
+++ b/gnu/packages/patches/libxtst-CVE-2016-7951-CVE-2016-7952.patch
@@ -0,0 +1,152 @@
+Fix CVE-2016-7951 and CVE-2016-7952
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7951
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7952
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXtst/commit/?id=9556ad67af3129ec4a7a4f4b54a0d59701beeae3
+
+From 9556ad67af3129ec4a7a4f4b54a0d59701beeae3 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:37:01 +0200
+Subject: [PATCH] Out of boundary access and endless loop in libXtst
+
+A lack of range checks in libXtst allows out of boundary accesses.
+The checks have to be done in-place here, because it cannot be done
+without in-depth knowledge of the read data.
+
+If XRecordStartOfData, XRecordEndOfData, or XRecordClientDied
+without a client sequence have attached data, an endless loop would
+occur. The do-while-loop continues until the current index reaches
+the end. But in these cases, the current index would not be
+incremented, leading to an endless processing.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/XRecord.c | 43 +++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 39 insertions(+), 4 deletions(-)
+
+diff --git a/src/XRecord.c b/src/XRecord.c
+index 50420c0..fefd842 100644
+--- a/src/XRecord.c
++++ b/src/XRecord.c
+@@ -749,15 +749,23 @@ parse_reply_call_callback(
+ switch (rep->category) {
+ case XRecordFromServer:
+ if (rep->elementHeader&XRecordFromServerTime) {
++ if (current_index + 4 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->server_time);
+ current_index += 4;
+ }
++ if (current_index + 1 > rep->length << 2)
++ return Error;
+ switch (reply->buf[current_index]) {
+ case X_Reply: /* reply */
++ if (current_index + 8 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index+4, datum_bytes);
++ if (datum_bytes < 0 || datum_bytes > ((INT_MAX >> 2) - 8))
++ return Error;
+ datum_bytes = (datum_bytes+8) << 2;
+ break;
+ default: /* error or event */
+@@ -766,52 +774,73 @@ parse_reply_call_callback(
+ break;
+ case XRecordFromClient:
+ if (rep->elementHeader&XRecordFromClientTime) {
++ if (current_index + 4 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->server_time);
+ current_index += 4;
+ }
+ if (rep->elementHeader&XRecordFromClientSequence) {
++ if (current_index + 4 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->client_seq);
+ current_index += 4;
+ }
++ if (current_index + 4 > rep->length<<2)
++ return Error;
+ if (reply->buf[current_index+2] == 0
+ && reply->buf[current_index+3] == 0) /* needn't swap 0 */
+ { /* BIG-REQUESTS */
++ if (current_index + 8 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index+4, datum_bytes);
+ } else {
+ EXTRACT_CARD16(rep->clientSwapped,
+ reply->buf+current_index+2, datum_bytes);
+ }
++ if (datum_bytes < 0 || datum_bytes > INT_MAX >> 2)
++ return Error;
+ datum_bytes <<= 2;
+ break;
+ case XRecordClientStarted:
++ if (current_index + 8 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD16(rep->clientSwapped,
+ reply->buf+current_index+6, datum_bytes);
+ datum_bytes = (datum_bytes+2) << 2;
+ break;
+ case XRecordClientDied:
+ if (rep->elementHeader&XRecordFromClientSequence) {
++ if (current_index + 4 > rep->length << 2)
++ return Error;
+ EXTRACT_CARD32(rep->clientSwapped,
+ reply->buf+current_index,
+ data->client_seq);
+ current_index += 4;
+- }
+- /* fall through */
++ } else if (current_index < rep->length << 2)
++ return Error;
++ datum_bytes = 0;
++ break;
+ case XRecordStartOfData:
+ case XRecordEndOfData:
++ if (current_index < rep->length << 2)
++ return Error;
+ datum_bytes = 0;
++ break;
+ }
+
+ if (datum_bytes > 0) {
+- if (current_index + datum_bytes > rep->length << 2)
++ if (INT_MAX - datum_bytes < (rep->length << 2) - current_index) {
+ fprintf(stderr,
+ "XRecord: %lu-byte reply claims %d-byte element (seq %lu)\n",
+- (long)rep->length << 2, current_index + datum_bytes,
++ (unsigned long)rep->length << 2, current_index + datum_bytes,
+ dpy->last_request_read);
++ return Error;
++ }
+ /*
+ * This assignment (and indeed the whole buffer sharing
+ * scheme) assumes arbitrary 4-byte boundaries are
+@@ -863,6 +892,12 @@ XRecordEnableContext(Display *dpy, XRecordContext context,
+ return 0;
+ }
+
++ if (rep.length > INT_MAX >> 2) {
++ UnlockDisplay(dpy);
++ SyncHandle();
++ return 0;
++ }
++
+ if (rep.length > 0) {
+ reply = alloc_reply_buffer(info, rep.length<<2);
+ if (!reply) {
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxv-CVE-2016-5407.patch b/gnu/packages/patches/libxv-CVE-2016-5407.patch
new file mode 100644
index 0000000000..e6a76c9f70
--- /dev/null
+++ b/gnu/packages/patches/libxv-CVE-2016-5407.patch
@@ -0,0 +1,162 @@
+Fix CVE-2016-5407:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5407
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXv/commit/?id=d9da580b46a28ab497de2e94fdc7b9ff953dab17
+
+From d9da580b46a28ab497de2e94fdc7b9ff953dab17 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 21:30:03 +0200
+Subject: [PATCH] Protocol handling issues in libXv - CVE-2016-5407
+
+The Xv query functions for adaptors and encodings suffer from out of
+boundary accesses if a hostile X server sends a maliciously crafted
+response.
+
+A previous fix already checks the received length against fixed values
+but ignores additional length specifications which are stored inside
+the received data.
+
+These lengths are accessed in a for-loop. The easiest way to guarantee
+a correct processing is by validating all lengths against the
+remaining size left before accessing referenced memory.
+
+This makes the previously applied check obsolete, therefore I removed
+it.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/Xv.c | 46 +++++++++++++++++++++++++++++-----------------
+ 1 file changed, 29 insertions(+), 17 deletions(-)
+
+diff --git a/src/Xv.c b/src/Xv.c
+index e47093a..be450c4 100644
+--- a/src/Xv.c
++++ b/src/Xv.c
+@@ -158,6 +158,7 @@ XvQueryAdaptors(
+ size_t size;
+ unsigned int ii, jj;
+ char *name;
++ char *end;
+ XvAdaptorInfo *pas = NULL, *pa;
+ XvFormat *pfs, *pf;
+ char *buffer = NULL;
+@@ -197,17 +198,13 @@ XvQueryAdaptors(
+ /* GET INPUT ADAPTORS */
+
+ if (rep.num_adaptors == 0) {
+- /* If there's no adaptors, there's nothing more to do. */
++ /* If there are no adaptors, there's nothing more to do. */
+ status = Success;
+ goto out;
+ }
+
+- if (size < (rep.num_adaptors * sz_xvAdaptorInfo)) {
+- /* If there's not enough data for the number of adaptors,
+- then we have a problem. */
+- status = XvBadReply;
+- goto out;
+- }
++ u.buffer = buffer;
++ end = buffer + size;
+
+ size = rep.num_adaptors * sizeof(XvAdaptorInfo);
+ if ((pas = Xmalloc(size)) == NULL) {
+@@ -225,9 +222,12 @@ XvQueryAdaptors(
+ pa++;
+ }
+
+- u.buffer = buffer;
+ pa = pas;
+ for (ii = 0; ii < rep.num_adaptors; ii++) {
++ if (u.buffer + sz_xvAdaptorInfo > end) {
++ status = XvBadReply;
++ goto out;
++ }
+ pa->type = u.pa->type;
+ pa->base_id = u.pa->base_id;
+ pa->num_ports = u.pa->num_ports;
+@@ -239,6 +239,10 @@ XvQueryAdaptors(
+ size = u.pa->name_size;
+ u.buffer += pad_to_int32(sz_xvAdaptorInfo);
+
++ if (u.buffer + size > end) {
++ status = XvBadReply;
++ goto out;
++ }
+ if ((name = Xmalloc(size + 1)) == NULL) {
+ status = XvBadAlloc;
+ goto out;
+@@ -259,6 +263,11 @@ XvQueryAdaptors(
+
+ pf = pfs;
+ for (jj = 0; jj < pa->num_formats; jj++) {
++ if (u.buffer + sz_xvFormat > end) {
++ Xfree(pfs);
++ status = XvBadReply;
++ goto out;
++ }
+ pf->depth = u.pf->depth;
+ pf->visual_id = u.pf->visual;
+ pf++;
+@@ -327,6 +336,7 @@ XvQueryEncodings(
+ size_t size;
+ unsigned int jj;
+ char *name;
++ char *end;
+ XvEncodingInfo *pes = NULL, *pe;
+ char *buffer = NULL;
+ union {
+@@ -364,17 +374,13 @@ XvQueryEncodings(
+ /* GET ENCODINGS */
+
+ if (rep.num_encodings == 0) {
+- /* If there's no encodings, there's nothing more to do. */
++ /* If there are no encodings, there's nothing more to do. */
+ status = Success;
+ goto out;
+ }
+
+- if (size < (rep.num_encodings * sz_xvEncodingInfo)) {
+- /* If there's not enough data for the number of adaptors,
+- then we have a problem. */
+- status = XvBadReply;
+- goto out;
+- }
++ u.buffer = buffer;
++ end = buffer + size;
+
+ size = rep.num_encodings * sizeof(XvEncodingInfo);
+ if ((pes = Xmalloc(size)) == NULL) {
+@@ -391,10 +397,12 @@ XvQueryEncodings(
+ pe++;
+ }
+
+- u.buffer = buffer;
+-
+ pe = pes;
+ for (jj = 0; jj < rep.num_encodings; jj++) {
++ if (u.buffer + sz_xvEncodingInfo > end) {
++ status = XvBadReply;
++ goto out;
++ }
+ pe->encoding_id = u.pe->encoding;
+ pe->width = u.pe->width;
+ pe->height = u.pe->height;
+@@ -405,6 +413,10 @@ XvQueryEncodings(
+ size = u.pe->name_size;
+ u.buffer += pad_to_int32(sz_xvEncodingInfo);
+
++ if (u.buffer + size > end) {
++ status = XvBadReply;
++ goto out;
++ }
+ if ((name = Xmalloc(size + 1)) == NULL) {
+ status = XvBadAlloc;
+ goto out;
+--
+2.10.1
+
diff --git a/gnu/packages/patches/libxvmc-CVE-2016-7953.patch b/gnu/packages/patches/libxvmc-CVE-2016-7953.patch
new file mode 100644
index 0000000000..737abdeb9f
--- /dev/null
+++ b/gnu/packages/patches/libxvmc-CVE-2016-7953.patch
@@ -0,0 +1,42 @@
+Fix CVE-2016-7953:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7953
+
+Patch copied from upstream source repository:
+
+https://cgit.freedesktop.org/xorg/lib/libXvMC/commit/?id=2cd95e7da8367cccdcdd5c9b160012d1dec5cbdb
+
+From 2cd95e7da8367cccdcdd5c9b160012d1dec5cbdb Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 25 Sep 2016 22:34:27 +0200
+Subject: [PATCH] Avoid buffer underflow on empty strings.
+
+If an empty string is received from an x-server, do not underrun the
+buffer by accessing "rep.nameLen - 1" unconditionally, which could end
+up being -1.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
+---
+ src/XvMC.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/XvMC.c b/src/XvMC.c
+index 7336760..3ee4212 100644
+--- a/src/XvMC.c
++++ b/src/XvMC.c
+@@ -576,9 +576,9 @@ Status XvMCGetDRInfo(Display *dpy, XvPortID port,
+ if (*name && *busID && tmpBuf) {
+ _XRead(dpy, tmpBuf, realSize);
+ strncpy(*name,tmpBuf,rep.nameLen);
+- (*name)[rep.nameLen - 1] = '\0';
++ (*name)[rep.nameLen == 0 ? 0 : rep.nameLen - 1] = '\0';
+ strncpy(*busID,tmpBuf+rep.nameLen,rep.busIDLen);
+- (*busID)[rep.busIDLen - 1] = '\0';
++ (*busID)[rep.busIDLen == 0 ? 0 : rep.busIDLen - 1] = '\0';
+ XFree(tmpBuf);
+ } else {
+ XFree(*name);
+--
+2.10.1
+
diff --git a/gnu/packages/patches/metabat-remove-compilation-date.patch b/gnu/packages/patches/metabat-remove-compilation-date.patch
new file mode 100644
index 0000000000..7672205b22
--- /dev/null
+++ b/gnu/packages/patches/metabat-remove-compilation-date.patch
@@ -0,0 +1,16 @@
+Remove the reference to the compilation date so that the build is
+reproducible.
+
+diff --git a/src/metabat.cpp b/src/metabat.cpp
+index 88e06de..c95cb1a 100644
+--- a/src/metabat.cpp
++++ b/src/metabat.cpp
+@@ -49,7 +49,7 @@ int main(int ac, char* av[]) {
+ po::notify(vm);
+
+ if (vm.count("help") || inFile.length() == 0 || outFile.length() == 0) {
+- cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; " << __DATE__ << " " << __TIME__ << ")" << endl;
++ cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; unknown compilation date)" << endl;
+ cerr << "by Don Kang (ddkang@lbl.gov), Jeff Froula, Rob Egan, and Zhong Wang (zhongwang@lbl.gov) \n" << endl;
+ cerr << desc << endl << endl;
+
diff --git a/gnu/packages/patches/rush-CVE-2013-6889.patch b/gnu/packages/patches/rush-CVE-2013-6889.patch
deleted file mode 100644
index 862528a12c..0000000000
--- a/gnu/packages/patches/rush-CVE-2013-6889.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-commit 00bdccd429517f12dbf37ab4397ddec3e51a2738
-Author: Mats Erik Andersson <gnu@gisladisker.se>
-Date: Mon Jan 20 13:33:52 2014 +0200
-
- Protect against CVE-2013-6889 (tiny change).
-
- Reset the effective user identification in testing mode.
-
-diff --git a/src/rush.c b/src/rush.c
-index 45d737a..dc6518e 100644
---- a/src/rush.c
-+++ b/src/rush.c
-@@ -980,6 +980,10 @@ main(int argc, char **argv)
- } else if (argc > optind)
- die(usage_error, NULL, _("invalid command line"));
-
-+ /* Relinquish root privileges in test mode */
-+ if (lint_option)
-+ setuid(getuid());
-+
- if (test_user_name) {
- struct passwd *pw = getpwnam(test_user_name);
- if (!pw)