【发布时间】:2014-01-08 01:04:17
【问题描述】:
我需要在 linux(确切地说是 debian)中编写一个程序,如果它没有通过特定的过滤器,它会禁用 USB 设备。例如,该程序可能被设置为禁止使用网络摄像头、USB 记忆棒和键盘,启用鼠标和打印机(通过 USB)。过滤器可能会在运行时更改。例如,程序可能会收到一条启用 USB 记忆棒的消息,它应该在不重新启动系统的情况下做出响应。该程序是用 python 编写的,但嵌入 c 代码(或其他代码)也是可以接受的。
我的尝试
我尝试了很多方法,但其中一些与编程无关。
首先,我试图弄乱 udev。我可以监控插入设备时的活动并编写过滤器。曾经有一个选项“ignore_device”忽略过滤的设备。例如,要忽略属于 usb 子系统成员的所有设备,我会将其编写为 udev 规则:
ACTION=="add", SUBSYSTEM=="usb", OPTIONS+="ignore_device"
但是这个选项是在 udev 的this 版本中发布的。到目前为止,我得到的是 udev 目前主要用于监控。当然,我可以为上面运行脚本的规则编写额外的规则,但我必须在其他地方进行禁用。
其次,我尝试使用 ioctl 向设备句柄发送 DISCONNECT 信号。我正在用 USB 鼠标对此进行测试。这是python代码:(我也在C中尝试过,没有任何改变)
import fcntl
import sys
USBDEVFS_RESET = ord('U') << (4*2) | 20
USBDEVFS_DISCONNECT = ord('U') << (4*2) | 22
raw_name = "/dev/bus/usb/{:03d}/{:03d}"
filename = raw_name.format(1,2)
fd = open(filename, "wb")
fcntl.ioctl(fd, USBDEVFS_DISCONNECT, 0)
在这里,如果我发送 USBDEVFS_RESET,它会起作用,鼠标输入会被忽略一两秒。但是断开信号会引发错误:
IOError: [Errno 25] Inappropriate ioctl for device
我从这里得到的是,我无法向鼠标发送断开信号。也许 USB 棒或打印机或其他一些设备可以工作,我没有尝试过。我想开发尽可能通用的程序,以防止编写额外的设备特定代码,所以这种方法对我来说似乎没用。这里的另一点是,当我手动断开/连接鼠标时,我会在 udev 监视器中看到事件。但是当我发送复位信号时,没有发送任何事件。
udev 监视器显示鼠标已安装到此路径:/sys/bus/usb/devices/1-3(这是/sys/devices/pci0000:00/0000:00:14.0/usb1/1-3 的符号链接)。一些文件告诉我,此文件夹包含设备的设置,将 /power/level 设置为“关闭”或“暂停”将关闭设备电源。但我无法操作 /power 中的任何文件。仔细想想,这毕竟不是一个好主意。
问题
那么,问题是,完成这项任务的最佳方法是什么?我有一个想法,但我不确定它是否会起作用,即使它起作用,也可能是矫枉过正。我的想法是编写一个“包装驱动程序”,将自己标识为 linux 内核作为所有 USB 设备的驱动程序。 “包装器驱动程序”读取设备信息,如果设备运行良好,它充当内核中真实驱动程序的包装器,调用它们的函数。如果不是,“包装器驱动程序”将忽略该设备。
我什至不确定它是否可以完成,我在内核或驱动程序编程方面没有经验。
另一种方法是,以某种方式 - 以编程方式获取设备的句柄并告诉它关闭电源(或让它永远忙,无论什么工作)。我也做了一些小研究,但找不到合适的简单方法。他们说所有设备都被视为“文件”,但我根本无法访问这些文件。
注意: 这个问题主要是关于 linux 内部的,但它也涉及内核编程。我阅读了很多关于 USB 操作/监控程序的内容,我阅读了 udevadm 的手册页。但是这些方法对我一点帮助都没有。我认为我需要以编程方式更改内核或设备内部。
我还尝试操作位于/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4 中的authorized 文件(用于键盘)。它的默认值为 1。将其更改为 0 成功禁用总线(不是设备,而是物理 USB 端口。插入另一个端口时仍然可以使用相同的设备)。但是将其设为 0 也会阻止来自此 USB 端口的 udev 事件。因此,如果用户插入禁用的设备,我可以禁用该端口,但我无法决定何时启用它,因为我无法在 udev 中侦听 remove 事件。如果我深入研究较低级别的代码(可能是内核)并以其他方式监听 USB 事件,这是否有意义?
【问题讨论】:
-
删除内核驱动程序并从系统中删除模块,然后锁定原始设备节点以阻止未授权的用户空间客户端。但是考虑到整个想法对某个坚定的人的保护很弱。
-
@ChrisStratton 嘿,讨厌游戏,而不是玩家......
-
对不起,这正在变成一场纯粹的配置辩论,它属于超级用户,而不是这里。
标签: linux linux-kernel usb kernel linux-device-driver