[PATCH] LSM: add SafeSetID module that gates setid calls
Micah Morton
mortonm at chromium.org
Thu Nov 1 16:18:32 UTC 2018
On Thu, Nov 1, 2018 at 8:39 AM Casey Schaufler <casey at schaufler-ca.com> wrote:
>
> On 10/31/2018 11:13 PM, Serge E. Hallyn wrote:
> > On Wed, Oct 31, 2018 at 06:12:46PM -0700, Micah Morton wrote:
> >> On Wed, Oct 31, 2018 at 3:37 PM Casey Schaufler <casey at schaufler-ca.com> wrote:
> >>> On 10/31/2018 2:57 PM, Kees Cook wrote:
> >>>> On Wed, Oct 31, 2018 at 2:02 PM, Serge E. Hallyn <serge at hallyn.com> wrote:
> >>>>> Just to be sure - your end-goal is to have a set of tasks which have
> >>>>> some privileges, including CAP_SETUID, but which cannot transition to
> >>>>> certain uids, perhaps including root?
> >> Correct, only whitelisted uids can be switched to. This only pertains
> >> to CAP_SETUID, other capabilities are not affected.
> >>
> >>>> AIUI, the issue is that CAP_SETUID is TOO permissive. Instead, run
> >>>> _without_ CAP_SETUID and still allow whitelisted uid transitions.
> >> Kees is right that this LSM only pertains to a single capability:
> >> CAP_SETUID (future work could tackle CAP_SETGID in the same fashion)
> >> -- although the idea here is to put in per-user limitations on what a
> >> process running as that user can do even when it _has_ CAP_SETUID. So
> >> it doesn't grant any extra privileges to processes that don't have
> >> CAP_SETUID, only restricts processes that _do_ have CAP_SETUID if the
> >> user they are running under is restricted.
> >>
> >>> I don't like that thought at all at all. You need CAP_SETUID for
> >>> some transitions but not all. I can call setreuid() and restore
> >>> the saved UID to the effective UID. If this LSM works correctly
> >>> (I haven't examined it carefully yet) it should prevent restoring
> >>> the effective UID if there isn't an appropriate whitelist entry.
> >> Yep, thats how it works. The idea here is that you still need
> >> CAP_SETUID for all transitions, regardless of whether whitelist
> >> policies exist or not.
> >>
> >>> It also violates the "additional restriction" model of LSMs.
> > Does it, or does the fact that CAP_SETUID is still required in order
> > to change uids address that?
>
> Yes, it does. Reading Kees' response had me a little concerned.
>
> >>> That has the potential to introduce a failure when a process tries
> >>> to give up privilege. If 0:1000 isn't on the whitelist but 1000:0
> >> As above, if a process drops CAP_SETUID it wouldn't be able to do any
> >> transitions (if this is what you mean by give up privilege). The
> >> whitelist is a one-way policy so if one wanted to restrict user 123
> >> but let it switch to 456 and back, 2 policies would need to be added:
> >> 123 -> 456 and 456 -> 123.
> >>
> >>> is Bad Things can happen. A SUID root program would be unable to
> >>> give up its privilege by going back to the real UID in this case.
> > Yes, this was the root cause of the "sendmail capabilities bug"
>
> I'm very familiar with that particular bug, as Bob Mende's
> work to convert sendmail to using capabilities was done for
> a project I owned. The blowback against all things security
> was pretty intense.
>
> > - a
> > privileged daemon which could be made to run with slightly less
> > privilege in such a way that it failed to drop privilege, then continued
> > ot run with some privilege.
> >
> > But the key trigger there was that an unprivileged task could prevent
> > the more privileged task from dropping its privilege.
> >
> > Is that the case here?
>
> I think it is reasonably safe to assume that there
> are many instances of programs that don't handle errors
> from setreuid() in the reset case. Without privilege
> setreuid() can be used to swap effective and real UIDs.
This LSM won't interfere with any of the one-off transitions allowed
by the set*uid family of syscalls that don't require CAP_SETUID. See
safesetid_task_fix_setuid in lsm.c.
>
> > It might be... If one of the uid-restricted
> > tasks running with CAP_SETUID runs a filter over some malicious data
> > which forces it to run a program which intends to change its uid and
> > fails to detect that that failed. It's not quite as cut-and-dried
> > though, and if we simply do not allow uid 0 to be in the set of uids,
> > that may prevent any such cases.
>
> Alas, UID 0 is not the only case we have to worry about.
> If I run a program owned by tss (Trousers) with the setuid
> bit set it will change the effective UID to tss. If this
> program expects to switch effective UID back to me and
> the SafeSetID whitelist prevents it, Bad Things may happen
> even though no capabilities or root privilege where ever
> involved.
>
> It would be easy for an inexperienced or malicious admin to
> include cschaufler:tss in the whitelist but miss on adding
> tss:cschaufler.
>
Same as above, this LSM will only affect transitions that would need
CAP_SETUID. AFAICT switching the effective UID back after that
setuid-bit scenario is not something that requires CAP_SETUID, and
thus would continue to work as it always has in Linux.
More information about the Linux-security-module-archive
mailing list