Fix crash when calling XListInputDevices on devices without classes
This commit is contained in:
parent
4c3a6bbf3c
commit
0d388fb26a
98
0001-SizeClassInfo-can-return-0-even-without-an-error.patch
Normal file
98
0001-SizeClassInfo-can-return-0-even-without-an-error.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 5010fe92202e98f3117be319aae268c5ab82c8ef Mon Sep 17 00:00:00 2001
|
||||
From: Niels Ole Salscheider <niels_ole@salscheider-online.de>
|
||||
Date: Fri, 7 Oct 2016 21:46:44 +0200
|
||||
Subject: [PATCH v2 libXi 1/2] SizeClassInfo can return 0 even without an error
|
||||
|
||||
Catch the error case separately. Commit 19a9cd607d added length checking to
|
||||
SizeClassInfo but re-used the return value of 0 for an error. A device without
|
||||
classes (as is initialized by xf86-input-libinput for tablets) can
|
||||
legitimately return 0 and erroneously triggers an error.
|
||||
Fix this by using a separate value for the error.
|
||||
|
||||
Reproducible by calling XListInputDevices() with a tablet attached.
|
||||
|
||||
This fixes a regression introduced in commit 19a9cd607d.
|
||||
|
||||
Signed-off-by: Niels Ole Salscheider <niels_ole@salscheider-online.de>
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
---
|
||||
Changes to v1:
|
||||
- don't touch *size until we're sure.
|
||||
- expand commit message
|
||||
|
||||
Niels:
|
||||
I left you as author and your signed-off-by since it's essentially your
|
||||
patch with a minor change.
|
||||
|
||||
src/XListDev.c | 24 +++++++++++++-----------
|
||||
1 file changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/XListDev.c b/src/XListDev.c
|
||||
index f850cd0..e4bd3d5 100644
|
||||
--- a/src/XListDev.c
|
||||
+++ b/src/XListDev.c
|
||||
@@ -73,27 +73,28 @@ static int pad_to_xid(int base_size)
|
||||
return ((base_size + padsize - 1)/padsize) * padsize;
|
||||
}
|
||||
|
||||
-static size_t
|
||||
-SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes)
|
||||
+static int
|
||||
+SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes, size_t *size)
|
||||
{
|
||||
- int size = 0;
|
||||
int j;
|
||||
+ size_t sz = 0;
|
||||
+
|
||||
for (j = 0; j < num_classes; j++) {
|
||||
switch ((*any)->class) {
|
||||
case KeyClass:
|
||||
- size += pad_to_xid(sizeof(XKeyInfo));
|
||||
+ sz += pad_to_xid(sizeof(XKeyInfo));
|
||||
break;
|
||||
case ButtonClass:
|
||||
- size += pad_to_xid(sizeof(XButtonInfo));
|
||||
+ sz += pad_to_xid(sizeof(XButtonInfo));
|
||||
break;
|
||||
case ValuatorClass:
|
||||
{
|
||||
xValuatorInfoPtr v;
|
||||
|
||||
if (len < sizeof(v))
|
||||
- return 0;
|
||||
+ return 1;
|
||||
v = (xValuatorInfoPtr) *any;
|
||||
- size += pad_to_xid(sizeof(XValuatorInfo) +
|
||||
+ sz += pad_to_xid(sizeof(XValuatorInfo) +
|
||||
(v->num_axes * sizeof(XAxisInfo)));
|
||||
break;
|
||||
}
|
||||
@@ -101,11 +102,13 @@ SizeClassInfo(xAnyClassPtr *any, size_t len, int num_classes)
|
||||
break;
|
||||
}
|
||||
if ((*any)->length > len)
|
||||
- return 0;
|
||||
+ return 1;
|
||||
*any = (xAnyClassPtr) ((char *)(*any) + (*any)->length);
|
||||
}
|
||||
|
||||
- return size;
|
||||
+ *size = sz;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -220,8 +223,7 @@ XListInputDevices(
|
||||
sav_any = any;
|
||||
end = (char *)list + rlen;
|
||||
for (i = 0; i < *ndevices; i++, list++) {
|
||||
- s = SizeClassInfo(&any, end - (char *)any, (int)list->num_classes);
|
||||
- if (!s)
|
||||
+ if(SizeClassInfo(&any, end - (char *)any, (int)list->num_classes, &s))
|
||||
goto out;
|
||||
size += s;
|
||||
}
|
||||
--
|
||||
2.7.4
|
||||
|
||||
132
0002-XListInputDevices-don-t-touch-ndevices-in-case-of-er.patch
Normal file
132
0002-XListInputDevices-don-t-touch-ndevices-in-case-of-er.patch
Normal file
@ -0,0 +1,132 @@
|
||||
From e821996b443e926a2cbab0eae38b33bad73e6060 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 13 Oct 2016 13:33:11 +1000
|
||||
Subject: [PATCH v2 libXi 2/2] XListInputDevices: don't touch ndevices in case of
|
||||
error
|
||||
|
||||
We used to always set *ndevices to the number of devices returned by the
|
||||
server. This magically worked because we pretty much never returned an error
|
||||
except on faulty server or library implementations. With 19a9cd60 we now have
|
||||
more chances of getting an error, so the polite thing is to just leave *ndevices
|
||||
alone when we error out.
|
||||
|
||||
Document it as such in the man page, just in case someone accidentally reads
|
||||
it.
|
||||
|
||||
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
CC: Niels Ole Salscheider <niels_ole@salscheider-online.de>
|
||||
---
|
||||
Changes to v1:
|
||||
- Niels' first patch set ndevices to 0, this one leaves it untouched
|
||||
|
||||
man/XListInputDevices.txt | 12 ++++++++++--
|
||||
src/XListDev.c | 21 ++++++++++++---------
|
||||
2 files changed, 22 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/man/XListInputDevices.txt b/man/XListInputDevices.txt
|
||||
index 276660d..450f377 100644
|
||||
--- a/man/XListInputDevices.txt
|
||||
+++ b/man/XListInputDevices.txt
|
||||
@@ -220,5 +220,13 @@ DESCRIPTION
|
||||
Floating. If the device is a master device, attached specifies
|
||||
the device ID of the master device this device is paired with.
|
||||
|
||||
- To free the XDeviceInfo array created by XListInputDevices, use
|
||||
- XFreeDeviceList.
|
||||
+RETURN VALUE
|
||||
+------------
|
||||
+
|
||||
+ XListInputDevices returns a pointer to an array of XDeviceInfo
|
||||
+ structs and sets ndevices_return to the number of elements in
|
||||
+ that array. To free the XDeviceInfo array created by
|
||||
+ XListInputDevices, use XFreeDeviceList.
|
||||
+
|
||||
+ On error, XListInputDevices returns NULL and ndevices_return is
|
||||
+ left unmodified.
|
||||
diff --git a/src/XListDev.c b/src/XListDev.c
|
||||
index e4bd3d5..dda6011 100644
|
||||
--- a/src/XListDev.c
|
||||
+++ b/src/XListDev.c
|
||||
@@ -175,7 +175,7 @@ ParseClassInfo(xAnyClassPtr *any, XAnyClassPtr *Any, int num_classes)
|
||||
XDeviceInfo *
|
||||
XListInputDevices(
|
||||
register Display *dpy,
|
||||
- int *ndevices)
|
||||
+ int *ndevices_return)
|
||||
{
|
||||
size_t s, size;
|
||||
xListInputDevicesReq *req;
|
||||
@@ -190,6 +190,7 @@ XListInputDevices(
|
||||
int i;
|
||||
unsigned long rlen;
|
||||
XExtDisplayInfo *info = XInput_find_display(dpy);
|
||||
+ int ndevices;
|
||||
|
||||
LockDisplay(dpy);
|
||||
if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1)
|
||||
@@ -205,8 +206,8 @@ XListInputDevices(
|
||||
return (XDeviceInfo *) NULL;
|
||||
}
|
||||
|
||||
- if ((*ndevices = rep.ndevices)) { /* at least 1 input device */
|
||||
- size = *ndevices * sizeof(XDeviceInfo);
|
||||
+ if ((ndevices = rep.ndevices)) { /* at least 1 input device */
|
||||
+ size = ndevices * sizeof(XDeviceInfo);
|
||||
if (rep.length < (INT_MAX >> 2)) {
|
||||
rlen = rep.length << 2; /* multiply length by 4 */
|
||||
slist = list = Xmalloc(rlen);
|
||||
@@ -219,17 +220,17 @@ XListInputDevices(
|
||||
}
|
||||
_XRead(dpy, (char *)list, rlen);
|
||||
|
||||
- any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo)));
|
||||
+ any = (xAnyClassPtr) ((char *)list + (ndevices * sizeof(xDeviceInfo)));
|
||||
sav_any = any;
|
||||
end = (char *)list + rlen;
|
||||
- for (i = 0; i < *ndevices; i++, list++) {
|
||||
+ for (i = 0; i < ndevices; i++, list++) {
|
||||
if(SizeClassInfo(&any, end - (char *)any, (int)list->num_classes, &s))
|
||||
goto out;
|
||||
size += s;
|
||||
}
|
||||
|
||||
Nptr = ((unsigned char *)list) + rlen;
|
||||
- for (i = 0, nptr = (unsigned char *)any; i < *ndevices; i++) {
|
||||
+ for (i = 0, nptr = (unsigned char *)any; i < ndevices; i++) {
|
||||
if (nptr >= Nptr)
|
||||
goto out;
|
||||
size += *nptr + 1;
|
||||
@@ -245,10 +246,10 @@ XListInputDevices(
|
||||
}
|
||||
sclist = clist;
|
||||
Any = (XAnyClassPtr) ((char *)clist +
|
||||
- (*ndevices * sizeof(XDeviceInfo)));
|
||||
+ (ndevices * sizeof(XDeviceInfo)));
|
||||
list = slist;
|
||||
any = sav_any;
|
||||
- for (i = 0; i < *ndevices; i++, list++, clist++) {
|
||||
+ for (i = 0; i < ndevices; i++, list++, clist++) {
|
||||
clist->type = list->type;
|
||||
clist->id = list->id;
|
||||
clist->use = list->use;
|
||||
@@ -261,7 +262,7 @@ XListInputDevices(
|
||||
clist = sclist;
|
||||
nptr = (unsigned char *)any;
|
||||
Nptr = (unsigned char *)Any;
|
||||
- for (i = 0; i < *ndevices; i++, clist++) {
|
||||
+ for (i = 0; i < ndevices; i++, clist++) {
|
||||
clist->name = (char *)Nptr;
|
||||
memcpy(Nptr, nptr + 1, *nptr);
|
||||
Nptr += (*nptr);
|
||||
@@ -270,6 +271,8 @@ XListInputDevices(
|
||||
}
|
||||
}
|
||||
|
||||
+ *ndevices_return = ndevices;
|
||||
+
|
||||
out:
|
||||
XFree((char *)slist);
|
||||
UnlockDisplay(dpy);
|
||||
--
|
||||
2.7.4
|
||||
|
||||
10
libXi.spec
10
libXi.spec
@ -5,7 +5,7 @@
|
||||
Summary: X.Org X11 libXi runtime library
|
||||
Name: libXi
|
||||
Version: 1.7.7
|
||||
Release: 1%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
|
||||
Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
|
||||
License: MIT
|
||||
Group: System Environment/Libraries
|
||||
URL: http://www.x.org
|
||||
@ -17,6 +17,9 @@ Source1: make-git-snapshot.sh
|
||||
Source0: ftp://ftp.x.org/pub/individual/lib/%{name}-%{version}.tar.bz2
|
||||
%endif
|
||||
|
||||
Patch01: 0001-SizeClassInfo-can-return-0-even-without-an-error.patch
|
||||
Patch02: 0002-XListInputDevices-don-t-touch-ndevices-in-case-of-er.patch
|
||||
|
||||
BuildRequires: autoconf automake libtool
|
||||
BuildRequires: xorg-x11-util-macros
|
||||
BuildRequires: xorg-x11-proto-devel
|
||||
@ -43,6 +46,8 @@ X.Org X11 libXi development package
|
||||
|
||||
%prep
|
||||
%setup -q -n %{tarball}-%{?gitdate:%{gitdate}}%{!?gitdate:%{version}}
|
||||
%patch01 -p1
|
||||
%patch02 -p1
|
||||
|
||||
%build
|
||||
autoreconf -v --install || exit 1
|
||||
@ -78,6 +83,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{_mandir}/man3/*.3*
|
||||
|
||||
%changelog
|
||||
* Thu Oct 13 2016 Peter Hutterer <peter.hutterer@redhat.com> 1.7.7-2
|
||||
- Fix crash when calling XListInputDevices on devices without classes
|
||||
|
||||
* Wed Oct 05 2016 Benjamin Tissoires <benjamin.tissoires@redhat.com> 1.7.7-1
|
||||
- libXi 1.7.7
|
||||
- fixes CVE-2016-7945, CVE-2016-7946
|
||||
|
||||
Loading…
Reference in New Issue
Block a user