首页 文章

udev规则中的无条件GOTO(和Medion RC-0617)

提问于
浏览
0

我在一些Debian 8.8衍生物(antix16)下对Medion RC-0617遥控器(带USB加密狗)进行了逆向工程 .

它注册了3个不同的HID设备(/ dev / hidraw *),我希望这些设备符号链接到/ dev / mdremote0,1和2,与相关的hidraw设备的数量无关(hidraw1,2和3大部分是时间,但这取决于插入的输入设备),以便用脚本查询它们以执行远程控制按钮的自定义操作 . (同时将其文件模式设置为666以便以普通用户身份访问它们)

udevadm info -a / dev / hidraw1的输出看起来像这样(缩短):

// The actual hidraw device (top level)
  looking at device '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/usb3/3-1/3-1:1.0/0003:04F2:0618.002B/hidraw/hidraw1':
    KERNEL=="hidraw1"
    SUBSYSTEM=="hidraw"
    DRIVER==""
//...

// The last point at which the 3 individual hidraw devices differed from each other
  looking at parent device '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/usb3/3-1/3-1:1.0':
    KERNELS=="3-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbhid"
    //...
    ATTRS{bInterfaceProtocol}=="01"
    // This entry distinguished the 3 individual hidraw devices from each other
    //...

// The dongle itself, parent device of all 3 hidraw devices
  looking at parent device '/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/usb3/3-1':
    KERNELS=="3-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{idVendor}=="04f2"
    ATTRS{idProduct}=="0618"
    ATTRS{product}=="USB Wireless HID Receiver"
    // The dongle can be uniquely identified by idVendor and idProduct
    //...
//...

因此,我需要编写的udev规则需要:

  • 通过idVendor和idProduct标识一个父设备

  • 检查另一个父设备中的bInterfaceProtocol属性

  • 将正确的符号链接/ dev / mdremote *分配给设备并设置正确的权限

我的第一次尝试是这样的:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"

(打算使用bInterfaceProtocol属性的顺序)

简而言之,这不起作用,udev manpage说:

某些键还与sysfs中父设备的属性匹配,而不仅仅是生成事件的设备 . 如果在单个规则中指定了与父设备匹配的多个密钥,则所有这些密钥必须在同一个父设备上匹配 .

所以,我开始了另一种方法:首先匹配加密狗,然后跳过单个规则,如果此检查不匹配,如下所示:

SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
GOTO="end"
LABEL="match"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
LABEL="end"

这在第一学期看起来是正确的 . 但是,猜猜是什么,它也不起作用,mdremote *符号链接只是指向任何具有bInterfaceProtocol键集的设备 .

2 回答

  • 2

    实际上,第二行(GOTO =“结束”)被忽略了 . 我花了一些时间来解决这个问题,但解决方案实际上非常简单:

    如果没有匹配的条件,udev将规则视为“始终不匹配”,因此根本不执行GOTO .

    我的工作udev规则文件看起来像这样:

    # Test if the wanted dongle is a parent device
    SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="0618", GOTO="match"
    # If not, skip the next 3 rules. The test against SUBSYSTEM=="hidraw" is there to produce a rule match
    SUBSYSTEM=="hidraw", GOTO="end"
    LABEL="match"
    # Those 3 rules actually assign the right symlink depending on the bInterfaceProtocol property.
    # Note that ALL of those rules contain the SUBSYSTEM=="hidraw" check, because the GOTO in the second line
    # does not get executed for non-hidraw devices and the rules get evaluated for any non-hidraw device.
    SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="01", SYMLINK="mdremote0", MODE="0666"
    SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="00", SYMLINK="mdremote1", MODE="0666"
    SUBSYSTEM=="hidraw", SUBSYSTEMS=="usb", ATTRS{bInterfaceProtocol}=="02", SYMLINK="mdremote2", MODE="0666"
    LABEL="end"
    

    事实证明这很好 . 它仍然可以通过为GOTO =“end”语句提供更好的匹配规则来改进,但我就这样离开了 .

  • 0

    @orwell我偶然发现了这个,并且有点困惑为什么这对你不起作用 . 我试图做一些类似的事情,并且在无条件的GOTO和debian延伸以及Arch Linux上都没有问题 . 检查一下:

    [c0d3@z3r0 tmp]$ cat /etc/udev/rules.d/45-test.rules
    GOTO="end"
    IMPORT{program}=="/bin/touch /tmp/noend"
    LABEL="end"
    IMPORT{program}=="/bin/touch /tmp/end"
    [c0d3@z3r0 tmp]$ sudo udevadm control --reload 
    [c0d3@z3r0 tmp]$ sudo udevadm trigger
    [c0d3@z3r0 tmp]$ ls /tmp/*end
    /tmp/end
    [c0d3@z3r0 tmp]$
    

相关问题