gnu: libxi: Update to 1.7.7.
* gnu/packages/xorg.scm (libxi): Update to 1.7.7. [replacement]: Remove field. (libxi/fixed): Remove variable. * gnu/packages/patches/libxi-CVE-2016-7945-CVE-2016-7946.patch: Delete file. * gnu/local.mk (dist_patch_DATA): Remove it.
This commit is contained in:
parent
3e1ed70f74
commit
571fa535cd
@ -668,7 +668,6 @@ 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/libxi-CVE-2016-7945-CVE-2016-7946.patch \
|
||||
%D%/packages/patches/libxrandr-CVE-2016-7947-CVE-2016-7948.patch \
|
||||
%D%/packages/patches/libxrender-CVE-2016-7949.patch \
|
||||
%D%/packages/patches/libxrender-CVE-2016-7950.patch \
|
||||
|
@ -1,420 +0,0 @@
|
||||
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
|
||||
|
@ -4912,8 +4912,7 @@ new API's in libXft, or the legacy API's in libX11.")
|
||||
(define-public libxi
|
||||
(package
|
||||
(name "libxi")
|
||||
(replacement libxi/fixed)
|
||||
(version "1.7.6")
|
||||
(version "1.7.7")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
@ -4923,7 +4922,7 @@ new API's in libXft, or the legacy API's in libX11.")
|
||||
".tar.bz2"))
|
||||
(sha256
|
||||
(base32
|
||||
"1b5p0l19ynmd6blnqr205wyngh6fagl35nqb4v05dw60rr9aachz"))))
|
||||
"0c70n4aq0ba628wr88ih4740nci9d9f6y3v96sx376vvlm7q6vwr"))))
|
||||
(build-system gnu-build-system)
|
||||
(propagated-inputs
|
||||
`(("inputproto" ,inputproto)
|
||||
@ -4939,14 +4938,6 @@ new API's in libXft, or the legacy API's in libX11.")
|
||||
(description "Library for the XInput Extension to the X11 protocol.")
|
||||
(license license:x11)))
|
||||
|
||||
(define libxi/fixed
|
||||
(package
|
||||
(inherit libxi)
|
||||
(source (origin
|
||||
(inherit (package-source libxi))
|
||||
(patches (search-patches
|
||||
"libxi-CVE-2016-7945-CVE-2016-7946.patch"))))))
|
||||
|
||||
(define-public libxrandr
|
||||
(package
|
||||
(name "libxrandr")
|
||||
|
Loading…
Reference in New Issue
Block a user