蓝牙 LE 以非 root 身份扫描?

kas*_*eia 17 bluetooth not-root-user

要对蓝牙 LE 设备执行扫描,hcitool显然需要 root 权限。对于普通用户,输出如下:

$ hcitool lescan
Set scan parameters failed: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

为什么hcitool需要 root 权限才能进行 LE 扫描?

是否有可能以非 root 用户身份执行 LE 扫描?

小智 26

Linux 的蓝牙协议栈检查两个功能。Capabilities 还不是一个用于管理某些特权的通用系统。它们可以由 PAM 模块或通过扩展文件属性处理。(见https://elixir.bootlin.com/linux/v5.8.10/source/net/bluetooth/hci_sock.c#L1307

 $> sudo apt-get install libcap2-bin
Run Code Online (Sandbox Code Playgroud)

安装 linux 功能操作工具。

 $> sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcitool`
Run Code Online (Sandbox Code Playgroud)

像 setuid 位一样设置可执行文件上缺少的功能。

 $> getcap !$
 getcap `which hcitool`
 /usr/bin/hcitool = cap_net_admin,cap_net_raw+eip
Run Code Online (Sandbox Code Playgroud)

所以我们很高兴:

$>hcitool -i hci0 lescan
Set scan parameters failed: Input/output error
Run Code Online (Sandbox Code Playgroud)

是的,您的 BT 适配器不支持 BLE

$>hcitool -i hci1 lescan
LE Scan...
Run Code Online (Sandbox Code Playgroud)

这样做,继续并按下设备上的按钮。


kas*_*eia 9

好的,至少我部分地发现了为什么hcitool需要 root 权限才能进行 LE 扫描而不是普通扫描。部分意味着,当我以普通用户身份运行 LE 扫描时,我找到了由于权限不足而失败的系统调用。

“操作不允许”错误是由writev系统调用生成的,调用堆栈锁定如下(在hci.c 中实现的所有函数,请参阅 bluez 源代码):

hci_le_set_scan_parameters -> hci_send_req -> hci_send_cmd -> writev
Run Code Online (Sandbox Code Playgroud)

正常扫描(“hcitool scan”)显然不需要向控制器发送任何请求,而是使用专用的ioctl请求,调用:

ioctl(dd, HCIINQUIRY, (unsigned long) buf);
Run Code Online (Sandbox Code Playgroud)

似乎对蓝牙控制器的写访问受到限制,但为什么以及如何停用它?