linuxlinux-capabilities

Why can't you drop a capability from the bounding set without CAP_SETPCAP?


I have a Linux service that runs as a non-root user and holds a set of a few capabilities. When it starts, I want to fork off a child process. That child process should drop one of its capabilities (let's say CAP_DAC_OVERRIDE). The idea is that in case there's a security vulnerability in the child process, an exploit will be less scary as it can't abuse that capability. The parent process is just a broker process, which retains CAP_DAC_OVERRIDE and will perform some actions on behalf of the unprivileged child process when it receives IPC messages from the child.

I'm able to remove this capability from every capability set in the child (inheritable, permitted, effective, and ambient) except for bounding. The call to prctl(PR_CAPBSET_DROP) of course requires CAP_SETPCAP (otherwise, you get prctl(PR_CAPBSET_DROP): Operation not permitted). I know that I can make my process spawn with CAP_SETPCAP initially and then remove it after I've changed the bounding set. My question is why does Linux not allow removing a capability from your bounding set unless you hold the CAP_SETPCAP capability? It seems odd that the Linux kernel prevents a process from reducing its own privileges.


Solution

  • There is a write up here for why dropping capabilities from what root receives requires some privilege: https://sites.google.com/site/fullycapable/thesendmailcapabilitiesissue .

    The example discussed there points out that if an unprivileged user can drop CAP_SETUID from the bounding set, then setuid-root programs can no longer drop privileges by changing UID from root to some other user.

    If you can trick one of these applications into leaking a process running as root, minus that one capability, then you can probably use one of the other available capabilities for some exploit. Either that, or overwrite some system file owned by root and do something nasty to the OS.

    As that write up mentions, this was used a long time ago to exploit sendmail. The kernel developers considered that exploit trivial enough to exploit, that dropping root's capabilities needed to require some privilege.