……只为设置触控板手势。

今天尝试把自己从 input 组丢出去,然后发现 libinput-gestrues 不工作了。其实不工作的原因有两个方面:

  • libinput 本身没有了读写 /dev/input/eventX 的权限(在非 root 下)
  • 用于模拟键盘输入的 ydotool 没有了写入 /dev/uinput 的权限。

为了最小化权限,首先解决第一个问题。增加一个 udev 规则,给触摸板加一个 uaccess 的 TAG,然后 sudo udevadm trigger 就可以了:

SUBSYSTEMS<mark>"input", ENV{ID_INPUT_TOUCHPAD}</mark>"1", MODE="0660", TAG+="uaccess"

根据 Wiki

The modern recommended approach for systemd systems is to use a MODE of 660 to let the group use the device, and then attach a TAG named uaccess. This special tag makes udev apply a dynamic user ACL to the device node, which coordinates with systemd-logind(8) to make the device usable to logged-in users.

当然并没有看懂。

对于第二个问题,比较麻烦。ydotool 不能工作的原因是,他依赖于由用户单元启动的 ydotoold 守护进程,而后者作为用户单元自然没有写入 /dev/uinput 的权限(该路径的所有者是 root:input,见下文)。

尝试了官方源中的 wtype,发现他依赖于 virtual-keyboard-unstable-v1 这个 Wayland Protocol,当然可以实现权限最小化。但很遗憾我在用的 KWin 并没有实现他……

还尝试了 AUR 中的 dotool,且不说 PKGBUILD 写的一团糟,把软件包自带的 udev 规则往 /etc 下面扔,而且他和 ydotool 的方案一样,写 udev 规则匹配这个设备然后加上 OPTIONS+="static_node=uinput",所以还是要求我在 input 组里面。

这里先嘴一句 ydotool,要求用户在配置文件里写 keycode 而不是按键名称实在是太抽象了……

言归正传,我能想到的加固方式是,把 ydotoold 变成系统单元,然后加入 input 组并添加一大堆 systemd 的加固选项。

大家都知道(其实不知道),systemd 的文档又多又杂就像天书一样,尝试自己写一个系统单元加上这样的设置:

PrivateDevices=yes
DeviceAllow=/dev/uinput

单元里面 /dev 地下只有这些最基本的设备节点:

assets/Pasted image 20241123233109.png

如果改成:

DevicePolicy=closed
DeviceAllow=/dev/uinput

单元里 /dev 似乎什么都有(群友说能看见但其实不能访问,未证实)。遂放弃。

研究 systemd 从来都是耗费生命,然后开始怀疑自己有阅读障碍。

最后的解决方案是使用 cn 源的 ydotool-git,仙子在里面 ship 了一个 udev 规则给 uinput 打上了 uaccess 的 TAG,和上文一样。

那么问题来了,我为什么没想到呢?🥲

See: