From e9f8bbf8e1a3502583b188a32c0b9ab2a4332012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 4 Sep 2025 00:43:45 +0200 Subject: [PATCH] Add device info to qrexec call argument This allows setting policy for individual devices, not only device types. It relies on USB qube (or wherever the device is connected) giving accurate device info, but since it's going to be granted at least partial control it needs to be trusted to some degree anyway. Build the device info based on type/vendor/product/revision (the PRODUCT property) and physical location (USB controller + port in case of USB device). The latter can be disabled, to build a policy that allows given device in any port. Fixes QubesOS/qubes-issues#3604 --- debian/qubes-input-proxy-sender.install | 1 + qubes-rpc/Makefile | 2 ++ qubes-rpc/input-proxy-arg | 29 +++++++++++++++++++ ...qubes-input-sender-keyboard-mouse@.service | 6 +++- .../qubes-input-sender-keyboard@.service | 6 +++- qubes-rpc/qubes-input-sender-mouse@.service | 6 +++- qubes-rpc/qubes-input-sender-tablet@.service | 6 +++- rpm_spec/input-proxy.spec.in | 1 + 8 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 qubes-rpc/input-proxy-arg diff --git a/debian/qubes-input-proxy-sender.install b/debian/qubes-input-proxy-sender.install index 5f69e8f..9978e7a 100644 --- a/debian/qubes-input-proxy-sender.install +++ b/debian/qubes-input-proxy-sender.install @@ -8,3 +8,4 @@ /usr/lib/systemd/system/qubes-input-sender-mouse@.service /usr/lib/systemd/system/qubes-input-sender-keyboard@.service /usr/lib/systemd/system/qubes-input-sender-keyboard-mouse@.service +/usr/lib/qubes/input-proxy-arg diff --git a/qubes-rpc/Makefile b/qubes-rpc/Makefile index ca10079..9c15d1c 100644 --- a/qubes-rpc/Makefile +++ b/qubes-rpc/Makefile @@ -26,6 +26,8 @@ install-vm: $(DESTDIR)$(USRLIBDIR)/udev/rules.d/90-qubes-uinput.rules install -m 0644 -D qubes-uinput.modules \ $(DESTDIR)$(USRLIBDIR)/modules-load.d/qubes-uinput.conf + install -m 0755 -D input-proxy-arg \ + $(DESTDIR)$(USRLIBDIR)/qubes/input-proxy-arg install -d $(DESTDIR)/etc/qubes-rpc install qubes.InputMouse $(DESTDIR)/etc/qubes-rpc install qubes.InputKeyboard $(DESTDIR)/etc/qubes-rpc diff --git a/qubes-rpc/input-proxy-arg b/qubes-rpc/input-proxy-arg new file mode 100644 index 0000000..4591d99 --- /dev/null +++ b/qubes-rpc/input-proxy-arg @@ -0,0 +1,29 @@ +#!/bin/bash + +dev="$1" +output="$2" + +sysfs_path="/sys/class/input/${dev##*/}/device/uevent" + +[ -e "$sysfs_path" ] || exit +product="$(grep ^PRODUCT= "$sysfs_path")" +[ -n "$product" ] || exit +product="${product#*=}" +product="${product//\"/}" +product="${product//\//-}" + +port="$(grep ^PHYS= "$sysfs_path")" +# by default include also physical port (if known), but allow opt-out +if [ -n "$port" ] && ! [ -e /run/qubes-service/input-proxy-exclude-port ]; then + port="${port#*=}" + port="${port//\"/}" + port="${port%/*}" + port="${port//:/_}" + # separate port from device with '+' + port="${port}+" +else + port= +fi + +mkdir -p "${output%/*}" +echo "QREXEC_ARG=+$port$product" > "$output" diff --git a/qubes-rpc/qubes-input-sender-keyboard-mouse@.service b/qubes-rpc/qubes-input-sender-keyboard-mouse@.service index 5b9c2f8..7c8c651 100644 --- a/qubes-rpc/qubes-input-sender-keyboard-mouse@.service +++ b/qubes-rpc/qubes-input-sender-keyboard-mouse@.service @@ -6,4 +6,8 @@ OnFailure=qubes-input-sender-mouse@%i.service [Service] Environment=TARGET_DOMAIN=dom0 EnvironmentFile=-/etc/qubes/input-proxy-target -ExecStart=/usr/bin/qubes-input-sender qubes.InputKeyboard /dev/input/%i "$TARGET_DOMAIN" +EnvironmentFile=-%t/qubes-input-proxy-env/%i +ExecStartPre=/usr/lib/qubes/input-proxy-arg /dev/input/%i %t/qubes-input-proxy-env/%i +ExecStart=/usr/bin/qubes-input-sender qubes.InputKeyboard${QREXEC_ARG} /dev/input/%i "$TARGET_DOMAIN" +ExecStopPost=/bin/rm -f %t/qubes-input-proxy-env/%i +PrivateTmp=yes diff --git a/qubes-rpc/qubes-input-sender-keyboard@.service b/qubes-rpc/qubes-input-sender-keyboard@.service index f8adebd..47e626f 100644 --- a/qubes-rpc/qubes-input-sender-keyboard@.service +++ b/qubes-rpc/qubes-input-sender-keyboard@.service @@ -5,4 +5,8 @@ After=qubes-qrexec-agent.service [Service] Environment=TARGET_DOMAIN=dom0 EnvironmentFile=-/etc/qubes/input-proxy-target -ExecStart=/usr/bin/qubes-input-sender qubes.InputKeyboard /dev/input/%i "$TARGET_DOMAIN" +EnvironmentFile=-%t/qubes-input-proxy-env/%i +ExecStartPre=/usr/lib/qubes/input-proxy-arg /dev/input/%i %t/qubes-input-proxy-env/%i +ExecStart=/usr/bin/qubes-input-sender qubes.InputKeyboard${QREXEC_ARG} /dev/input/%i "$TARGET_DOMAIN" +ExecStopPost=/bin/rm -f %t/qubes-input-proxy-env/%i +PrivateTmp=yes diff --git a/qubes-rpc/qubes-input-sender-mouse@.service b/qubes-rpc/qubes-input-sender-mouse@.service index 309f60f..860a537 100644 --- a/qubes-rpc/qubes-input-sender-mouse@.service +++ b/qubes-rpc/qubes-input-sender-mouse@.service @@ -5,4 +5,8 @@ After=qubes-qrexec-agent.service [Service] Environment=TARGET_DOMAIN=dom0 EnvironmentFile=-/etc/qubes/input-proxy-target -ExecStart=/usr/bin/qubes-input-sender qubes.InputMouse /dev/input/%i "$TARGET_DOMAIN" +EnvironmentFile=-%t/qubes-input-proxy-env/%i +ExecStartPre=/usr/lib/qubes/input-proxy-arg /dev/input/%i %t/qubes-input-proxy-env/%i +ExecStart=/usr/bin/qubes-input-sender qubes.InputMouse${QREXEC_ARG} /dev/input/%i "$TARGET_DOMAIN" +ExecStopPost=/bin/rm -f %t/qubes-input-proxy-env/%i +PrivateTmp=yes diff --git a/qubes-rpc/qubes-input-sender-tablet@.service b/qubes-rpc/qubes-input-sender-tablet@.service index 3266b01..f9e8623 100644 --- a/qubes-rpc/qubes-input-sender-tablet@.service +++ b/qubes-rpc/qubes-input-sender-tablet@.service @@ -5,4 +5,8 @@ After=qubes-qrexec-agent.service [Service] Environment=TARGET_DOMAIN=dom0 EnvironmentFile=-/etc/qubes/input-proxy-target -ExecStart=/usr/bin/qubes-input-sender qubes.InputTablet /dev/input/%i "$TARGET_DOMAIN" +EnvironmentFile=-%t/qubes-input-proxy-env/%i +ExecStartPre=/usr/lib/qubes/input-proxy-arg /dev/input/%i %t/qubes-input-proxy-env/%i +ExecStart=/usr/bin/qubes-input-sender qubes.InputTablet${QREXEC_ARG} /dev/input/%i "$TARGET_DOMAIN" +ExecStopPost=/bin/rm -f %t/qubes-input-proxy-env/%i +PrivateTmp=yes diff --git a/rpm_spec/input-proxy.spec.in b/rpm_spec/input-proxy.spec.in index 96d5f71..d22b5d7 100644 --- a/rpm_spec/input-proxy.spec.in +++ b/rpm_spec/input-proxy.spec.in @@ -85,6 +85,7 @@ rm -rf %{buildroot}/etc/qubes-rpc/policy /usr/bin/qubes-input-trigger %config(noreplace) /etc/xdg/autostart/qubes-input-trigger.desktop /usr/lib/udev/rules.d/90-qubes-input-proxy.rules +/usr/lib/qubes/input-proxy-arg %{_unitdir}/qubes-input-sender-tablet@.service %{_unitdir}/qubes-input-sender-mouse@.service %{_unitdir}/qubes-input-sender-keyboard@.service