Replacing setuid with file capabilities

Serge Hallyn serge.hallyn at canonical.com
Thu Mar 29 23:22:42 UTC 2012


Quoting Kees Cook (kees at ubuntu.com):
> Hi Andrea,
> 
> On Thu, Mar 29, 2012 at 04:29:29PM +0200, Andrea Corbellini wrote:
> > As many of you already know, there are some setuid executables in Ubuntu
> > that perform very specific tasks and do not need many special privileges
> > (ping and traceroute are just two examples). My proposal is to remove
> > their setuid flag and set the file capabilities they need through
> > setcap(8). This will indeed reduce the risk of privilege escalation.
> 
> The good news is that the bulk of these tools immediately drop their
> privs. A while back, some source checking was done to see where things
> stood, and this was produced to help track it, and needs further work:
> https://wiki.ubuntu.com/Security/Investigation/Setuid
> 
> While dropping privs early helps mitigate target binary flaws, it doesn't
> help loader flaws:
> http://people.canonical.com/~ubuntu-security/cve/2010/CVE-2010-3856.html
> 
> And while it looks like a good idea to use filesystem capabilities,
> there are, unfortunately, a number of things blocking that adoption:
> https://wiki.ubuntu.com/Security/FilesystemCapabilties
> 
> As Serge mentioned, filesystem support is a big deal. While a package
> manager could be taught to retain setuid bits for programs that can run
> in 'dual mode' (detecting either fscaps or setuid), if those file systems
> are exported on NFS to clients, we lose. I think that's a small use-case,
> though. A big use-case is overlay filesystems, which are heavily used
> (like, in the Ubuntu installer), and if those don't pass the attrs
> correctly, we lose again.
> 
> Beyond that, there are the package management blockers (outlined in
> the URL above). Various tools need to support the attrs correctly,
> and dpkg needs to grow an entire chunk of logic for dealing with it.
> 
> And for the reasons Marc pointed to (Brad's run down on how almost all
> capabilities are equivalent to full root access, and Solar's point that

As per the recent LWN article, I do hope to start keeping a closer eye
on this, and perhaps go further in the direction of CAP_SYSLOG (with
small distinct capabilities which continue to be implied by the larger
capabilities).

> adding caps to a tool without its knowledge can be dangerous), changing

As can taking caps away without its knowledge :)  Absolutely, we need
to audit every program we consider switching over.

> the tools correctly is important too. Holding caps should be treated
> as being just as dangerous as being setuid. I think, if it's to be done
> right, every setuid tool needs to operate in a dual-mode where it examines
> its state and retains only the caps it needs, and then drops those as soon
> as possible, in addition to dropping setuidness after keeping the caps
> it needs. In this way, they can run either as setuid or as fscap-using
> tools, which will likely be up to the package manager at install time.
> 
> > I think this is the right time to start discussing about this feature
> > because 12.10 is four releases away from the next LTS and the risk of
> > committing serious mistakes is lower.
> > 
> > So, what do you think? Is it something that we could do for the
> > Q-series?
> 
> In my opinion, it's been discussed a great deal already. Without the
> filesystem support and the archiving tool support, it's not fruitful to
> start on the package manager support.
> 
> Beyond those things, I think it would be cool to see the "dual-mode"
> logic added to all the tools so that if system owners choose to drop
> the setuid bit and add the fscaps, the program will behave as safely as
> possible. And that work doesn't need a session -- it needs patches. :)

Agreed.

I wonder if a simple API might be helpful.  Top of my head while in the
midst of a long unrelated debugging session; probably has holes, might
even be completely wrong.  But:

/*
 * @caps is a list of capabilites which the caller will need
 * at some point
 *
 * If caller is setuid-root, it will store @caps in its permitted
 * set, request keeping its capability, clear pE, and switch all uids
 * to its real uid.
 *
 * If caller is non-root, and does not have all the capabilities in
 * @caps, return with error
 *
 * If caller is non-root and has at least all the capabilities in
 * @caps, drop all capabilities from pE, drop all capabilities not
 * int @caps from pP.
 *
 * Do we want this to take an optional uid to switch to, instead of
 * the real uid?
 */
int cap_temp_drop_caps(int ncaps, cap_t *caps);

/*
 * activate the capabilities in @caps in pE.
 * @caps must be a subset of pP, else return error.
 */
int cap_regain_caps(int ncaps, cap_t *caps);

/*
 * clear pE
 */
void cap_redrop_caps(void);

/*
 * drop all capabilities permanently
 */
void cap_perm_drop_caps(void);

Because I'm plenty familiar with how unwieldy libcap2 API is
otherwise.

But then, maybe we're just re-inventing capng.

And there is one more problem - much of this software wants to work
on systems other than linux.  See the old usenix login; article about
safe setuid...  It's complicated enough as is, without adding
linux-specific hacks.  I'm not sure how we cleanly finagle the
above API into such software.

-serge




More information about the ubuntu-server mailing list