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
`. `'` [email protected] / chris-lamb.co.uk
`-
From ceb73c87915ca1e976847c470be4baff3086a507 Mon Sep 17 00:00:00 2001
From: Chris Lamb <[email protected]>
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 <[email protected]> for the report.
Signed-off-by: Chris Lamb <[email protected]>
---
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