21

To perform a scan for bluetooth LE devices hcitool apparently requires root privileges. For normal users the output is following:

$ hcitool lescan
Set scan parameters failed: Operation not permitted

Why does hcitool need root privileges for a LE scan?

Is it possible to somehow perform a LE scan as non-root?

3 Answers 3

30

The Bluetooth protocol stack for Linux checks two capabilities. Capabilities are a not yet common system to manage some privileges. They could be handled by a PAM module or via extended file attributes. (see https://elixir.bootlin.com/linux/v5.8.10/source/net/bluetooth/hci_sock.c#L1307)

 $> sudo apt-get install libcap2-bin

installs linux capabilities manipulation tools.

 $> sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcitool`

sets the missing capabilities on the executable quite like the setuid bit.

 $> getcap !$
 getcap `which hcitool`
 /usr/bin/hcitool = cap_net_admin,cap_net_raw+eip

so we are good to go:

$>hcitool -i hci0 lescan
Set scan parameters failed: Input/output error

Yeay, your BT adapter does not support BLE

$>hcitool -i hci1 lescan
LE Scan...

This one does, go on and press a button on your device.

2
  • 1
    Thanks four pointing out the missing capabilities. It also helped me to use bluetoothctl as non root user on a Raspberry Pi running Raspbian Stretch! but in my case I added the capability to /lib/systemd/system/bluetooth.service. Commented Feb 21, 2019 at 10:33
  • How to do it via a PAM module? Commented Feb 25, 2021 at 12:01
11

Ok, at least I partially discovered why hcitool requires root privileges for a LE scan but not for a normal scan. Partially means, that I located the system call which fails due to insufficient privileges when running the LE scan as a normal user.

The "Operation not permitted" error is generated by a writev system call, with the call stack locking as follows (all functions implemented in hci.c, see the bluez source code):

hci_le_set_scan_parameters -> hci_send_req -> hci_send_cmd -> writev

The normal scan ("hcitool scan") apparently does not need to send any requests to the controller, but uses a dedicated ioctl request, calling:

ioctl(dd, HCIINQUIRY, (unsigned long) buf);

It seems that write access to the bluetooth controller is restricted, but why and how can I deactivate that?

0
1

I don't have this installed, but a well-written device subsystem usually has a group associated with it. Add a user to the group, and you can access the device (for instance disk group allows raw hard drive access). Just do ls -l in /dev to check this. If that's not the case and the device belongs to root group, you can change this by adjusting the udev rules that govern naming, permissions and actions on hardware at detection (don't ask me how).

This goes for direct device access that you probably need in this case. Normal functionality of bluetooth is usually handled through a daemon with its own configuration, groups, permissions and so on. Check your distribution documentation, the groups may vary slightly.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .