ChangeLog | 20 ++++++++++++ configure.ac | 2 - debian/changelog | 10 ++++++ debian/control | 10 +++--- debian/copyright | 2 - debian/upstream/signing-key.asc | 64 ++++++++++++++++++++++++++++++++++++++++ debian/watch | 2 - 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 +++-- 17 files changed, 201 insertions(+), 31 deletions(-)
New commits: commit 49310859c869dab1eb2f50ff296ae0e65488318d Author: Andreas Boll <andreas.boll....@gmail.com> Date: Fri Oct 7 13:33:30 2016 +0200 Bump Standards-Version to 3.9.8, no changes needed. diff --git a/debian/changelog b/debian/changelog index 2896723..aed45a9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ libxi (2:1.7.7-1) UNRELEASED; urgency=medium - Fixes CVE-2016-7945 and CVE-2016-7946. * Update d/upstream/signing-key.asc with Matthieu Herrb's key. * Update a bunch of URLs in packaging to https. + * Bump Standards-Version to 3.9.8, no changes needed. -- Andreas Boll <andreas.boll....@gmail.com> Fri, 07 Oct 2016 13:19:05 +0200 diff --git a/debian/control b/debian/control index b40d21e..f8ef4dc 100644 --- a/debian/control +++ b/debian/control @@ -24,7 +24,7 @@ Build-Depends: xorg-sgml-doctools (>= 1:1.8), xsltproc, w3m, -Standards-Version: 3.9.6 +Standards-Version: 3.9.8 Vcs-Git: https://anonscm.debian.org/git/pkg-xorg/lib/libxi.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-xorg/lib/libxi.git Homepage: https://www.x.org/ commit 91587b757c163f8bbc2e9cfa1453ce045f9b36c9 Author: Andreas Boll <andreas.boll....@gmail.com> Date: Fri Oct 7 13:22:12 2016 +0200 Update a bunch of URLs in packaging to https. diff --git a/debian/changelog b/debian/changelog index 0015ee0..2896723 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ libxi (2:1.7.7-1) UNRELEASED; urgency=medium * New upstream release. - Fixes CVE-2016-7945 and CVE-2016-7946. * Update d/upstream/signing-key.asc with Matthieu Herrb's key. + * Update a bunch of URLs in packaging to https. -- Andreas Boll <andreas.boll....@gmail.com> Fri, 07 Oct 2016 13:19:05 +0200 diff --git a/debian/control b/debian/control index aa5f529..b40d21e 100644 --- a/debian/control +++ b/debian/control @@ -27,7 +27,7 @@ Build-Depends: Standards-Version: 3.9.6 Vcs-Git: https://anonscm.debian.org/git/pkg-xorg/lib/libxi.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-xorg/lib/libxi.git -Homepage: http://www.x.org/ +Homepage: https://www.x.org/ Package: libxi6 Section: libs @@ -43,7 +43,7 @@ Description: X11 Input extension library and hotplugging of input devices (to be added and removed on the fly). . More information about X.Org can be found at: - <URL:http://www.X.org> + <URL:https://www.X.org> . This module can be found at git://anongit.freedesktop.org/git/xorg/lib/libXi @@ -73,7 +73,7 @@ Description: X11 Input extension library (debug package) Non-developers likely have little use for this package. . More information about X.Org can be found at: - <URL:http://www.X.org> + <URL:https://www.X.org> . This module can be found at git://anongit.freedesktop.org/git/xorg/lib/libXi @@ -103,7 +103,7 @@ Description: X11 Input extension library (development headers) libxi6. Non-developers likely have little use for this package. . More information about X.Org can be found at: - <URL:http://www.X.org> + <URL:https://www.X.org> . This module can be found at git://anongit.freedesktop.org/git/xorg/lib/libXi diff --git a/debian/copyright b/debian/copyright index 561c972..74d612a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,5 +1,5 @@ This package was downloaded from -http://xorg.freedesktop.org/releases/individual/lib/ +https://xorg.freedesktop.org/releases/individual/lib/ Copyright 1989, 1998 The Open Group diff --git a/debian/watch b/debian/watch index 919d93a..d55b672 100644 --- a/debian/watch +++ b/debian/watch @@ -1,4 +1,4 @@ #git=git://anongit.freedesktop.org/xorg/lib/libXi version=3 opts=pgpsigurlmangle=s/$/.sig/ \ -http://xorg.freedesktop.org/releases/individual/lib/ libXi-(.*)\.tar\.gz +https://xorg.freedesktop.org/releases/individual/lib/ libXi-(.*)\.tar\.gz commit 6783f21403450ad4ab270e09b24ad3017ff97eaa Author: Andreas Boll <andreas.boll....@gmail.com> Date: Fri Oct 7 13:20:53 2016 +0200 Update d/upstream/signing-key.asc with Matthieu Herrb's key. diff --git a/debian/changelog b/debian/changelog index a8779e9..0015ee0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ libxi (2:1.7.7-1) UNRELEASED; urgency=medium * New upstream release. - Fixes CVE-2016-7945 and CVE-2016-7946. + * Update d/upstream/signing-key.asc with Matthieu Herrb's key. -- Andreas Boll <andreas.boll....@gmail.com> Fri, 07 Oct 2016 13:19:05 +0200 diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc index 767d86a..649f1ba 100644 --- a/debian/upstream/signing-key.asc +++ b/debian/upstream/signing-key.asc @@ -21,3 +21,67 @@ ipEzOo5vdKOow/qIRgQYEQIABgUCPxvTCAAKCRDiO35wtGfwv68jAKCDvL2gkrg1 4NfV7rNc057K1nL2GgCeKApWRgGVzaOkAp0P5tQulaDD6zM= =7uBX -----END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBFeKY50BEADAX0lod3IVceb/IWJn3kTAcO2P7PWlcBiyUDaq5b2kFkliKleZ +ec4LoCHakQBlkRBMPNwOOxvADNk3tLQjBDpbYr6lQIrN+AxMGkXBhJ82T3bsDvlj +3Z1wRJ1zVA7eMIktsk0FAoJxV1y7e3sBKcP0eTlXqXvR2djhi+FW+ueJDAJIFSkb +uFirgwtX5t8nt8jCmIl75KNUKOakoENY3hLWtr16W8fO1JGkEhghI2mXcz664KTd +MPZp6JH0/8UHTHzmATOCTqNxoDtMTi2l5059Lh/nhmso9moTYqyKmaJP2rnZUr62 +97sRMG4WcxaYfWpPyO3MCmDyGeh4sW0OC06PpED3i9xMzf/kMkMdY4ZIFcLRcPtf +LIJhw+lc/GE1Rqe961IB5xCgnZezB7ZIL+ZlOAMwKGkq7lLbcZr2QZn84lpABKF0 +AvxECoJ4etmIcdbDVmsw18AhA3u9sr98hS5IXDyeos3Xwz6Abml8aPrhqhkKvo+J +Kcq9FNYHg0RRlos0TqocjDzGnUjEYrmIopLcwIu2SnsNSJTygZGtqrpT+2sGEqvm +k6Oyk95QCa580zqldvxe3CG0vrAfPvoG7irllM68TS4JcqqDHTq6eupUv9ZdIzXf +eyTHa5cytGahgVtUcui1lzqcCBkqwN8TKl+0wCcEnxRasHJy3A2Gp+AG3wARAQAB +tCJNYXR0aGlldSBIZXJyYiA8bWF0dGhpZXVAaGVycmIuZXU+iQI+BBMBAgAoBQJX +imOdAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBoc5PuN9Eo ++PF1EACldzZPNYaC9H5E9sMn9pMsJTucBYVUy74Aw6MWAiAzRpxb9DmySmC2oEYW +JJkwDTwv6M0Na0ed6zD79GKtAalORz2GppZpS7uoINClElWoM5TCYph6linyv9Wj +OTlcbpX0Jqw0tdHNI2UOEjvBP3vW9kVYpEhfnHET8Ncp55j1hzoqxOhGIBE/67zc +cLAenONAvA3YN3tHTGaOaFv+vuCFRJx9FpKbGHmdUPd3MtLqtaA4EQvDvDEholEI +eWrjmdXJibSet6Amc5AIdFaQevZiADjjMh8MINw/6OEy9OB4s+z1RzgOrHgLiIZm +dlP6WrNjXQwl2gmNPhctGaSHM+j2+3gckNGlI4LQYxNtKvI4iv/CoHDYmwgrcrZO +TwFHfqt0LwqjpsU203Hw609oWYcxLeGZdITBjDz20UcfsmKQDqrBq3P1FuC5GBW3 +5bEa3wAhyE+/WKhJ94bXiHmpKsp50va3bEe17uQcYd8+E8L53aR7XP87qaHx//Mu ++OQa5Wc2d1OFHf1Mi62nbzr7pws/Mf7OSf/tnhRthuwtlfYnsUVo8usUKL/xStqo +Ul4kc/Q81AlyaZfr7dbxsQWm2q3ksLaMaAxnk0p+kMXVzXZ9GKNOgUOJdbahORs5 +RU2f44xzfNavb63u3McADtaXskl+KHB4uDbGbGESVhm5PULk37QnTWF0dGhpZXUg +SGVycmIgPG1hdHRoaWV1LmhlcnJiQGxhYXMuZnI+iQI+BBMBAgAoBQJXlJ63AhsD +BQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBoc5PuN9Eo+PKID/wM +II+2d11clp1X7eZgkxkAHUhI2W3NSesuFnjkkQRKQoVMokDdeSOkBhMJuWoFfbZk +jYs2VHU9029rDqcoDSqGwo2IffvrXXJ4SjOTjlvXS1lr/H2VdWRbq8ImnDwSsoiD +dWB3dZyqzf7ABKZ7ccA+NMSs6NxeEN/0+0sTJ386Zp480ByNX0uPqYSq5lX/VEke +nI8r02u2ZfuykhGkT0sM013VprfYLa+6HvF+QT9KfP220mqRbonaDkYvCxwjCMzd +rUmvyqw3VsooUpg/W/PmDNeShSuOxebaGnFyGTNvTarElCBdynFD01dqOecOqfY8 +gy+PJ1aF1qjmf+RQD/SZq+gvgyXqyBhJy7zgJnzzNWzDlUIw0ZOLyZxzFR7lRV79 +2mrGgczlQr5rLAgBy2pgwsCmP7nFx50r4ft2juugnQixoOBU/YfhBplM76EROaCc +MTs5nPEqzJ9p4SNkPcK8AroR2Ka3+f7t+XOoHpx/XhJOBYlPaUmoFkWKr0Y8BWWh +1nJxyFKrSNbwUgam8ypZzwzbI1vDiX8Ol6NpEeOLwzFNT0pyTdC9UN93M1VIyKWC +1vaeMogUREKT6SmDjRn3fISktZ0IGVf2AnFMhtgZ46TJO4BZgDdZAjTkZc/lP0yF +Nl6MpGwnaymmL50ckT77OdlfIcXFwvNPFwWlFPlcyrkCDQRXimOdARAA4otssvZm +sKg+g0bVyJHhn/YOHLYMih+Xf07xJHyalH0UCGnGdHZwl0B97G950SwQ7yVXtGa9 +CAPe97clE6dPD6jaumQ13BHavXM+ThgjCe8V56ayYcdzqFkxlCx0Uocoa63G0/cE +TiOqeqhNZs8JY+D7l83jCa4lU/1pLusbkCpCQ7d5/FFLz7QSihzJWp+UTsjbNik5 +spaseEMGFRKUcB3SZ/l1dTgc0wBQ1hlvLX+h4/sG0iUs1pVpo5ORC+bUfWRokl96 +uj5QZz5rY21FaNSP1rB1HKHNkwhxifBCHQMhYGTXvD7GH+JNyF2TdRmo7eBCfAPJ +aP3mX9t2SkCipdSsUs+Uuyib9MLA71ApW90AGiRm6HtOCxR0c3+qQRNIdFVm8mnM +hCxXRexf6Z2wZdXXy6uY0LVRgI0o31NPJPk8l2Hnb/kHGxjyUFzEWh65J/eA368d +4m8uF+Rr7WWlpQjwgWHU12kGThEVFFBFh2gmeIjYZdDDVhCi2mQ6lGSV2Pt7pZYL +/PPChWLBqrVBkIUQ0GV22nRYvGdaIv2LVPu8PggbPs/wwh35nJ3rUQyJF55CFV5y +WIWAWXfRYTKG9jkt+ncjZLEBxDO26zzO/MjIVPZxGyYryXEOgr6xp38xbyX9FpjL +KBaIueLWEyphVjBb1uUpDGx+UDYe9vbJjPUAEQEAAYkCJQQYAQIADwUCV4pjnQIb +DAUJA8JnAAAKCRBoc5PuN9Eo+D8dEACa60Q3ta6BWyHG0SOgfYGHE15LodACVHNI +N6Ou+JtmLarMW/AvPclNC25mxZV0ywLbun4CnJ9qYbt/Kx7djn48mrNa0rKN8Q+V +K5RvQA1kD890yzwu5jH6r5BQ8VBcfsPvsvatgbquzFn+NNiH9U4xRf/9BSY2Zk3G +yA15xG0T9zoklOMg8MWbeRaJPkDELyaHPWerbO7rebynePENSFPz3o3g+K9WcCM2 +xkEL571SmT4z3Mp/p0pwemWBCP2WoKCnSjAGiiHpCFru3SlZhRIvNJyK5jeS/IU6 +d5qeTBse6TXzp6Q4xkzACIN66P5SG/YY3/ONbfs6wB3lIkvVC9n7jEXjMK1T0fK8 +9DBDjzvAkJcKLLuIljjkMhRWSCED74sn+MlaWm0xMeo276EnaVILNcrHecSr8+eX +pVXSWEJ1+ErzZladJC+CrqUm0QljPV8Smtmk9MvOLHZ4qL4bI4Hu7MywuGNrLSol +qO0pAT1AjaYTRuH2MhZ6mJe/EtSl0EHXEkcDteE4jbYj3lwVhA1c/So0CdayImmD +/0tdqUfekw4va8PpbQ0wroL0XUvf3wl6HOhFhahWSqqb1fVr2slVttkaMb8M4MPt +Ka2m4qiiuGYivPIAVapSEA4DYc+krVqVXV/yDd3T7XcNtnClVo+rmOn5WiGq24am +79+hF4bWyw== +=WW1Z +-----END PGP PUBLIC KEY BLOCK----- commit 93eba51b931b2d401952605b202efeb2bc68bf33 Author: Andreas Boll <andreas.boll....@gmail.com> Date: Fri Oct 7 13:20:25 2016 +0200 Bump changelogs diff --git a/ChangeLog b/ChangeLog index 760b132..bf3e809 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +commit 8e0476653dd134cee84f4e893f656b2f93c4e3b0 +Author: Matthieu Herrb <matthieu.he...@laas.fr> +Date: Tue Oct 4 21:14:01 2016 +0200 + + libXi 1.7.7 + + Signed-off-by: Matthieu Herrb <matthieu.he...@laas.fr> + +commit 19a9cd607de73947fcfb104682f203ffe4e1f4e5 +Author: Tobias Stoeckmann <tob...@stoeckmann.org> +Date: Sun Sep 25 22:31:34 2016 +0200 + + 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 <tob...@stoeckmann.org> + Reviewed-by: Matthieu Herrb <matth...@herrb.eu> + commit 2286282f965064176b3b1492646c6e2e0f4ab7dd Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Dec 22 11:20:01 2015 +1000 diff --git a/debian/changelog b/debian/changelog index 1709d14..a8779e9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libxi (2:1.7.7-1) UNRELEASED; urgency=medium + + * New upstream release. + - Fixes CVE-2016-7945 and CVE-2016-7946. + + -- Andreas Boll <andreas.boll....@gmail.com> Fri, 07 Oct 2016 13:19:05 +0200 + libxi (2:1.7.6-1) unstable; urgency=medium * New upstream release. commit 8e0476653dd134cee84f4e893f656b2f93c4e3b0 Author: Matthieu Herrb <matthieu.he...@laas.fr> Date: Tue Oct 4 21:14:01 2016 +0200 libXi 1.7.7 Signed-off-by: Matthieu Herrb <matthieu.he...@laas.fr> diff --git a/configure.ac b/configure.ac index 64033be..f7d322c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) -AC_INIT([libXi], [1.7.6], +AC_INIT([libXi], [1.7.7], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXi]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([src/config.h]) commit 19a9cd607de73947fcfb104682f203ffe4e1f4e5 Author: Tobias Stoeckmann <tob...@stoeckmann.org> Date: Sun Sep 25 22:31:34 2016 +0200 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 <tob...@stoeckmann.org> Reviewed-by: Matthieu Herrb <matth...@herrb.eu> 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))); }