33

I would like to set up wpa_supplicant and openvpn to run as non-root user, like the recommended setup for wireshark. I can't find any documentation for what +eip in this example means:

sudo setcap cap_net_raw,cap_net_admin,cap_dac_override+eip /usr/bin/dumpcap
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
T0m4t0s4uc3
  • 433
  • 1
  • 4
  • 5
  • 15
    The one answer this question has so far is very difficult to understand. I think an additional answer is still needed. – Rebroad Jan 27 '20 at 01:00

2 Answers2

30

The way capabilities work in Linux is documented in man 7 capabilities.

Processes' capabilities in the effective set are against which permission checks are done. File capabilities are used during an execv call (which happens when you want to run another program1) to calculate the new capability sets for the process.

Files have two sets for capabilities, permitted and inheritable and effective bit.

Processes have three capability sets: effective, permitted and inheritable. There is also a bounding set, which limits which capabilities may be added later to a process' inherited set and affects how capabilities are calculated during a call to execv. Capabilities can only be dropped from the bounding set, not added.

Permissions checks for a process are checked against the process' effective set. A process can raise its capabilities from the permitted to the effective set (using capget and capset syscalls, the recommended APIs are respectively cap_get_proc and cap_set_proc).

Inheritable and bounding sets and file capabilities come into play during an execv syscall. During execv, new effective and permitted sets are calculated and the inherited and bounding sets stay unchanged. The algorithm is described in the capabilities man page:

P'(permitted) = (P(inheritable) & F(inheritable)) |
                (F(permitted) & cap_bset)

P'(effective) = F(effective) ? P'(permitted) : 0

P'(inheritable) = P(inheritable)    [i.e., unchanged]

Where P is the old capability set, P' is the capability set after execv and F is the file capability set.

If a capability is in both processes' inheritable set and the file's inheritable set (intersection/logical AND), it is added to the permitted set. The file's permitted set is added (union/logical OR) to it (if it is within the bounding set).

If the effective bit in file capabilities is set, all permitted capabilities are raised to effective after execv.

Capabilities in kernel are actually set for threads, but regarding file capabilities this distinction is usually relevant only if the process alters its own capabilities.

In your example capabilities cap_net_raw , cap_net_admin and cap_dac_override are added to the inherited and permitted sets and the effective bit is set. When your binary is executed, the process will have those capabilities in the effective and permitted sets if they are not limited by a bounding set.

[1] For the fork syscall, all the capabilities and the bounding set are copied from parent process. Changes in uid also have their own semantics for how capabilities are set in the effective and permitted sets.

jezza
  • 138
  • 5
sebasth
  • 14,332
  • 4
  • 50
  • 68
  • So is P(inherited, bounding) like a template stored with the files or just user wide? (how would a new process (before execv) have any capabilities) Also what is the syntax for removing I'm guessing '-e' removes effective bit , 'setcap capabilities_name -ip' to remove inherent & permitted capabilities – T0m4t0s4uc3 Sep 02 '17 at 05:16
  • Process before doesn't necessarily have any. If the file has `+ep` the process will gain those capabilities. Usually bounding set is full by default; no capabilities are masked, otherwise no process could ever get any capabilities. – sebasth Sep 02 '17 at 05:23
  • But then what's the point in P'(permitted) = (P(inheritable) & F(inheritable). Thanks a ton btw! – T0m4t0s4uc3 Sep 02 '17 at 05:25
  • A process can regain a capability it had previously. It can drop capabilities from *permitted* and *effective* sets and gain them again if the file has `+i` for those capabilities. – sebasth Sep 02 '17 at 05:30
  • Oh a security feature? so say ' ip r add default 192.168.1..1 via nic' needs cap_net_admin where as 'ip r list' doesn't – T0m4t0s4uc3 Sep 02 '17 at 05:33
  • If the file has only `+i`, only processes which already have the same capability in *inheritable* set can gain it as *permitted* (or *effective* if `+ie`) via *execv*. For processes without capabilities it doesn't add any capabilities. – sebasth Sep 02 '17 at 05:43
  • 4
    This answer and the docs it references do not depart from the grand tradition of unintelligible man pages, useful only as reminders to readers who already attended Un*x summer camp. The answers at https://unix.StackExchange.com/questions/298893/why-are-not-all-permitted-capabilities-of-a-linux-process-effective-all-the-time are more useful. – Devon Mar 13 '20 at 13:46
  • You should have shown an example command instead of pasting from the man pages, in my opinion. – Gregg Leventhal Sep 09 '21 at 15:03
  • 1
    i think i need to go to one of those summer camps – placid chat Oct 20 '21 at 10:58
4

Setting a capability on a file

sudo setcap 'cap_net_bind_service=ep' file_name

Setting multiple capabilities on a file

sudo setcap 'cap_net_bind_service=ep cap_sys_admin=ep' file_name

Removing all capabilities from a file

sudo setcap -r file_name

Checking capabilities for a file

getcap file_name

List of possible capabilities (some are really interesting)

https://linux.die.net/man/7/capabilities

Pitfall: setting capabilities does not really work for scripts. If you want your Python script to work, you need to set the capabilities on the Python executable itself. It's not ideal.

Note: setcap always overwrites the entire capability set when you run it. Most of the time, you see examples using setcap with + or - syntax, which I believe is a confusing piece of junk and does NOT work as you would expect from other tools like chmod. You can't use setcap multiple times to add different capabilities, it needs to be done in a single command.