tags 830726 + patch thanks Chris Lamb wrote:
> CVE-2016-10894[0]: > | xtrlock through 2.10 does not block multitouch events. Consequently, > | an attacker at a locked screen can send input to (and thus control) > | various programs such as Chromium via events such as pan scrolling, > | "pinch and zoom" gestures, or even regular mouse clicks (by depressing > | the touchpad once and then clicking with a different finger). Patch attached that works for me on my Dell XPS 13: $ xinput --list | head -n4 ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ ELAN25B5:00 04F3:25B5 id=12 [slave pointer (2)] ⎜ ↳ DELL07E6:00 06CB:76AF Touchpad id=13 [slave pointer (2)] (The second in this list is my multitouch touchscreen device.) Regards, -- ,''`. : :' : Chris Lamb `. `'` la...@debian.org / chris-lamb.co.uk `-
From ceb73c87915ca1e976847c470be4baff3086a507 Mon Sep 17 00:00:00 2001 From: Chris Lamb <la...@debian.org> Date: Tue, 13 Aug 2019 13:32:11 -0700 Subject: [PATCH] Attempt to grab multitouch devices which are not intercepted via XGrabPointer. (Closes: #830726) xtrlock did not block multitouch events so an attacker could still input (and thus control) various programs such as Chromium, etc. via so-called multitouch events such as pan scrolling, "pinch and zoom" or even being able to provide regular mouse clicks by depressing the touchpad once and then clicking with a secondary finger. Thanks to Antoine Amarilli <a...@a3nm.net> for the report. Signed-off-by: Chris Lamb <la...@debian.org> --- debian/control | 1 + debian/rules | 4 ++-- xtrlock.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 33582b1..19f88dd 100644 --- a/debian/control +++ b/debian/control @@ -6,6 +6,7 @@ Priority: optional Build-Depends: debhelper-compat (= 12), libx11-dev, + libxi-dev, x11proto-core-dev, Vcs-Git: https://salsa.debian.org/debian/xtrlock.git Vcs-Browser: https://salsa.debian.org/debian/xtrlock diff --git a/debian/rules b/debian/rules index 8c6893c..9b03511 100755 --- a/debian/rules +++ b/debian/rules @@ -4,7 +4,7 @@ DPKG_EXPORT_BUILDFLAGS = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all include /usr/share/dpkg/default.mk -CFLAGS += -DSHADOW_PWD +CFLAGS += -DSHADOW_PWD -DMULTITOUCH ifeq (,$(findstring ^$(DEB_VERSION_UPSTREAM),^$(shell cut -d'"' -f2 patchlevel.h))) $(error (patchlevel.h out of sync with Debian version)) @@ -14,7 +14,7 @@ endif dh $@ override_dh_auto_build: - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) xtrlock.c -o xtrlock -lcrypt -lX11 + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) xtrlock.c -o xtrlock -lcrypt -lX11 -lXi override_dh_fixperms: dh_fixperms -X/usr/bin/xtrlock diff --git a/xtrlock.c b/xtrlock.c index 6117c6f..389df08 100644 --- a/xtrlock.c +++ b/xtrlock.c @@ -41,6 +41,11 @@ #include <shadow.h> #endif +#ifdef MULTITOUCH +#include <X11/extensions/XInput.h> +#include <X11/extensions/XInput2.h> +#endif + #include "lock.bitmap" #include "mask.bitmap" #include "patchlevel.h" @@ -87,6 +92,12 @@ int main(int argc, char **argv){ #endif struct timeval tv; int tvt, gs; +#ifdef MULTITOUCH + XIEventMask evmask; + XIDeviceInfo *info; + int xi_major=2, xi_minor=2, xi_opcode, xi_error, xi_event, xi_ndevices; + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; +#endif while (argc > 1) { if ((strcmp(argv[1], "-b") == 0)) { @@ -132,7 +143,27 @@ int main(int argc, char **argv){ program_version); exit(1); } + +#ifdef MULTITOUCH + if (!XQueryExtension(display,INAME,&xi_opcode,&xi_event,&xi_error)) { + fprintf(stderr,"xtrlock (version %s): No X Input extension\n", + program_version); + exit(1); + } + if (XIQueryVersion(display, &xi_major, &xi_minor) != Success|| + xi_major * 10 + xi_minor < 22) { + fprintf(stderr,"xtrlock (version %s): Need XI 2.2\n", + program_version); + exit(1); + } + + evmask.mask = mask; + evmask.mask_len = sizeof(mask); + memset(mask, 0, sizeof(mask)); + evmask.deviceid = XIAllMasterDevices; +#endif + attrib.override_redirect= True; if (blank) { @@ -216,6 +247,20 @@ int main(int argc, char **argv){ exit(1); } +#ifdef MULTITOUCH + // (Optimistically) attempt to grab multitouch devices which are not + // intercepted via XGrabPointer + info = XIQueryDevice(display, XIAllDevices, &xi_ndevices); + for (int i=0; i < xi_ndevices; i++) { + XIDeviceInfo *dev = &info[i]; + for (int j=0; j < dev->num_classes; j++) { + if (dev->classes[j]->type == XITouchClass) + XIGrabDevice(display, dev->deviceid, window, CurrentTime, cursor, + GrabModeAsync, GrabModeAsync, False, &evmask); + } + } +#endif + if (fork_after) { pid_t pid = fork(); if (pid < 0) { -- 2.23.0.rc1