I was recently updating some code that uses fping. Initially it used exec() that was redirected to a temporary file but I changed it to use popen. While it had been a while since I’ve done this sort of thing, I do recall there was an issue with running popen on setuid binary. A later found it is mainly around setuid scripts which are very problematic and there are good reasons why you don’t do this.
Anyhow, the program worked fine which surprised me. Was fping setuid root to get the raw socket?
$ ls -l /usr/bin/fping -rwxr-xr-x 1 root root 31464 May 6 21:42 /usr/bin/fping
It wasn’t which at first all I thought “ok, so that’s why popen is happy”. The way that fping and other programs work is they bind to a raw socket. This socket sits below the normal type sockets such as the ones used for TCP and UDP and normal users cannot use them by default. So how did fping work it’s magic and get access to this socket? It used Capabilities.
Previously getting privileged features had a big problem; it was an all or nothing thing. You want access to a raw socket? Sure, be setuid but that means you also could, for example, read any file on the system or set passwords. Capabilites provide a way of giving programs some better level of access, but not a blank cheque.
The tool getcap is the way of determining what capabilities are found on a file. These capabilities are attributes on the file which, when the file is run, turn into capabilities or extra permissions. fping has the capability cap_net_raw+ep applied to it. This gives access to the RAW and PACKET sockets which is what fping needs. The +ep after the capability name means it is an Effective and Permitted capability, which describes what happens with child processes and dropping privileges.
I hadn’t seen these Capabilities before. They are a nice way to give your programs the access they need, but limiting the risk of something going wrong and having a rouge program running as root.
- Lesser-known tool of the day: getcap, setcap and file capabilities (insecure.ws)
- Using File Capabilities Instead Of Setuid (wiki.archlinux.org)
- Safer suexec: from setuid to Linux capabilities (welldefinedbehaviour.wordpress.com)
- Kees Cook: easy example of filesystem capabilities (outflux.net)
Please note, that using capabilities often is the same as being root:
Thanks for that link Patrick. Capabilities are certainly not the complete answer, but they at least reduce the attack surface for that particular program. For example, fping only gets raw socket capability, which is certainly powerful, but not as powerful as making fping setuid root.
I suppose it’s not a complete solution, but better than where we were. The other thing I did wonder is while a lot of things such as tripwire report setuid files, do they all report on capabilities?
ls really needs to add an indicator to files that have capabilities set, just as it adds a + for acls.