Capabilities and PAM

Most of our current ~arch users most likely noticed an update in libcap to version 2. They noticed because it had some conflicts on the first revision out there and thus crapped out after build. Not much of a problem though, it’s now fixed.

Interstingly, libcap 2 has a pam USE flag that should build a pam_cap PAM module that allows you to set stuff via PAM, akin to the way it’s already possible to set limits through pam_limits. Unfortunately it did not install it, so it was quite useless.

But fear not, 2.06-r1 now installs the PAM module, and the configuration file, so it’s now possible to use it. Unfortunately it doesn’t seem to work.

For those of you who don’t know what capabilities are, they are a way to provide an user, a file, a process with some privileges (capabilities) that would otherwise be limited to root, without having to provide the full blown root privileges. It’s a way to tighten security: you allow a process (or user, or file) just to do what it has to do.

The usual way that capabilities are used, up to now, is to use libcap in setuid root programs: the program starts, uses libcap to get itself just the capabilities it needs, and then it drops root privileges, keeping just what it really needs. This is what PulseAudio does for instance, as well as the setuid root helper of wireshark. This allows to tighten a bit the security, but only works with setuid root programs, which requires thus to lax security, although for a limited time (a code execution after the root privileges are dropped is less dangerous, but there is still a chance that there is exploitable code before they are dropped).

Since kernel 2.6.24, it’s finally possible to set capabilities on files (without kernel patches at least, I think there were enough laying around before to do that), this means you can replace a setuid root program with a capability-set program. Let’s take for instance the ping command. A very basic command. On a default system, ping is setuid root:

-rws--x--x 1 root root 35480 Nov 12 17:26 /bin/ping

After launching it and setting up to be able to access RAW sockets, the privileges are tuned down to the actual user calling ping. It works, it reduces the risk, but using capabilities it should be even simpler:

flame@enterprise ~ % ls -l /bin/ping
-rwx--x--x 1 root root 38256 26 gen 13:15 /bin/ping
flame@enterprise ~ % /sbin/getcap /bin/ping
/bin/ping = cap_net_raw+ep
flame@enterprise ~ % ping -c1 localhost
PING localhost ( 56(84) bytes of data.
64 bytes from localhost ( icmp_seq=1 ttl=64 time=0.028 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.028/0.028/0.028/0.000 ms

Interesting, isn’t it? The ping command is no more setuid, there is no need to drop privileges as it only has the privileges it needs: access to the raw socket.

This works nice for stuff like ping and other network commands, and for sniffers, although it works for all the users in the system, so while it replaces well the setuid root executables, it doesn’t work well to give generic capabilities to programs. For instance you might not want all users access to sniffers, so instead of giving the RAW access to the sniffer files (and then setting groups like it’s done now for wireshark) you would probably prefer to give RAW access to a particular user, which could then do whatever she wants with sniffing software.

This is the idea behind pam_cap: you get a capability.conf file, similar to limits.conf, that allows you to give particular capabilities to particular users, rather than executables. Unfortunately it doesn’t seem to work here. Even setting it up properly, it seems to be plainly ignored. If I don’t give ping the file capabilities for RAW packets, it doesn’t work, even if my processes have inheritable RAW capabilities. I’ll have to dig up a bit on this.

Anyway, now that we have a nice implementation with PAM, and file-based access, I hope the future will see us moving toward more tight security by using file-based capabilities rather than setuid root programs. I’m now planning how to handle capabilities in PAM in an easy way for users… you’ll see more blogs on the matter in the next weeks.