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