Using POSIX capabilities in Linux, part two

Okay, it has been over half a year since I last got to writing about this topic. And I don’t want to write about what I originally intended – which was capchroot. However, I am going to introduce you to the concept of inheritable file capabilities and inheritable thread capabilities and how to use them with capsudo.

If you read part one and experimented with capabilities, you probably noticed that the set of effective capabilities gets lost whenever you execute a subprocess using one of the exec* system calls. Looking at the capabilities manpage, there is an interesting formula that explains the situation:

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           denotes the value of a thread capability set before the execve(2)
P'          denotes the value of a capability set after the execve(2)
F           denotes a file capability set
cap_bset    is the value of the capability bounding set (described below).

So, to be able to inherit a capability from a parent, the following must be true:

  • The thread must have the capability in its inheritable set.
  • The executable file must have the capability in its inheritable set.
  • The executable file must have the effective bit set (this can be omitted if the executable is aware of capabilities and raises the permitted capability to an effective capability during execution).

For the first point, we’ll have a look at capsudo. It’s a small tool written by yours truly, which requires libcap and iniparser. Get the source, build it with make, install the config file to /etc/capsudoers and put the binary somewhere (/usr/bin in our example). Then, run setcap cap_setpcap=p /usr/bin/capsudo. The CAP_SETPCAP capability allows it to put arbitrary capabilities into the thread’s inheritable set, but does not allow them to become permitted unless you execute a program with the correct file inheritable capability.

Now we’ll use this to allow capturing in tcpdump and wireshark to certain users without setuid and without root:

  • Run setcap cap_net_raw=ei /usr/sbin/tcpdump
  • Add the following section to /etc/capsudoers:
    [tcpdump]
      caps = cap_net_raw
      command = /usr/sbin/tcpdump
      allow_user_args = 1
      users = user1 user2
      groups = group1 group2

    The users user1 and user2 are now allowed to use tcpdump with the CAP_NET_RAW capability, as well as all members of group1 and group2.

  • Run capsudo tcpdump -ni wlan0 and capture traffic.

To do the same with wireshark, we need to do something slightly different: Instead of running the setcap command on /usr/bin/wireshark, run it on /usr/bin/dumpcap. This is because wireshark does not capture itself, but calls dumpcap. The beauty here is that despite the CAP_NET_RAW inheritable capability being in the thread, wireshark has no privileged rights at all until it calls dumpcap, which then only gets the capability to capture, and nothing more.

  • Run setcap cap_net_raw=ei /usr/bin/dumpcap
  • Add the following section to /etc/capsudoers:
    [wireshark]
      caps = cap_net_raw
      command = /usr/bin/wireshark
      allow_user_args = 1
      users = user1 user2
      groups = group1 group2
  • Run capsudo wireshark and capture traffic.

Another use case would be running a http server on port 80 without root:

  • Run setcap cap_net_bind_service=ei /usr/bin/yourhttpserver
  • Add the following section to /etc/capsudoers:
    [yourhttpserver]
      caps = cap_net_bind_service
      command = /usr/bin/yourhttpserver
      allow_user_args = 1
      users = httpd
    
  • Start the service with capsudo yourhttpserver and open a privileged port.

That’s all for today, I hope you enjoyed it and find ways to use this to your advantage, so that we may at some point minimize the number of places where we have to use setuid or become root.

2 Comments

  1. kaaposc says:

    Thanks for this (and part I) tutorial! These POSIX capabilities sound really interesting (never heard of them before). I hope my info-grinding-organ (brain) works out something useful of this.

  2. [...]   http://archlinux.me/brain0/2009/07/28/u … -part-one/    http://archlinux.me/brain0/2010/01/05/u … -part-two/[4] Серж Е. Халлин, «Разрешение POSIX для файлов: разделяем [...]