Chris Lamb wrote:
> I've been working on an updated patch that detects new devices and
> blocks them too. However, "grabbing" devices during the processing of
> these "device hierarchy changed" events appears to do something funny
> and actually disables all input entirely for me
Whilst I've fixed that bit at least, the new attached patch doesn't
grab devices that are renabled via "xinput enable" although we do
successfully detect that "edge" event now.
That is to say:
$ [find id via xinput list]
$ (xinput disable 10; sleep 10; xinput enable 10) &
$ ./xtrlock
... does not then block multitouch events subsequent to the sleep and
"xinput enable" call.
Antoine, how did you find the right /sys/bus/usb/devices/FOO directory?
I'm only using xinput as I can't seem to locate my touchpad under
/sys/bus. (Perhaps we don't need to care about the "xinput enable" case)
Best wishes,
--
,''`.
: :' : Chris Lamb
`. `'` la...@debian.org 🍥 chris-lamb.co.uk
`-
From a4bc14b34ce924a370eabcc27c495474372497d1 Mon Sep 17 00:00:00 2001
From: Chris Lamb <la...@debian.org>
Date: Wed, 21 Aug 2019 15:26:33 -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 | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 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 2928068..43ebe33 100755
--- a/debian/rules
+++ b/debian/rules
@@ -5,7 +5,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
include /usr/share/dpkg/default.mk
-include /usr/share/dpkg/buildtools.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))
@@ -15,7 +15,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..89d3a12 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"
@@ -71,6 +76,32 @@ int passwordok(const char *s) {
#endif
}
+#if MULTITOUCH
+XIEventMask evmask;
+
+/* (Optimistically) attempt to grab multitouch devices which are not
+ * intercepted via XGrabPointer. */
+void handle_multitouch(Cursor cursor) {
+ XIDeviceInfo *info;
+ int xi_ndevices;
+
+ 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 &&
+ dev->use == XISlavePointer) {
+ XIGrabDevice(display, dev->deviceid, window, CurrentTime, cursor,
+ GrabModeAsync, GrabModeAsync, False, &evmask);
+ }
+ }
+ }
+ XIFreeDeviceInfo(info);
+}
+#endif
+
int main(int argc, char **argv){
XEvent ev;
KeySym ks;
@@ -132,7 +163,32 @@ int main(int argc, char **argv){
program_version);
exit(1);
}
+
+#ifdef MULTITOUCH
+ unsigned char mask[XIMaskLen(XI_LASTEVENT)];
+ int xi_major, xi_minor, xi_opcode, xi_error, xi_event;
+
+ 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 = XIAllDevices;
+ XISetMask(mask, XI_HierarchyChanged);
+ XISelectEvents(display, DefaultRootWindow(display), &evmask, 1);
+#endif
+
attrib.override_redirect= True;
if (blank) {
@@ -216,6 +272,10 @@ int main(int argc, char **argv){
exit(1);
}
+#ifdef MULTITOUCH
+ handle_multitouch(cursor);
+#endif
+
if (fork_after) {
pid_t pid = fork();
if (pid < 0) {
@@ -265,6 +325,15 @@ int main(int argc, char **argv){
break;
}
break;
+#if MULTITOUCH
+ case GenericEvent:
+ if (ev.xcookie.extension == xi_opcode &&
+ XGetEventData(display,&ev.xcookie) &&
+ ev.xcookie.evtype == XI_HierarchyChanged) {
+ handle_multitouch(cursor);
+ }
+ break;
+#endif
default:
break;
}
--
2.23.0