Thread (88 messages) 88 messages, 7 authors, 2019-02-12

Re: [PATCH] LSM: add SafeSetID module that gates setid calls

From: Micah Morton <mortonm@chromium.org>
Date: 2018-11-01 16:18:46

On Thu, Nov 1, 2018 at 8:39 AM Casey Schaufler [off-list ref] wrote:
On 10/31/2018 11:13 PM, Serge E. Hallyn wrote:
quoted
On Wed, Oct 31, 2018 at 06:12:46PM -0700, Micah Morton wrote:
quoted
On Wed, Oct 31, 2018 at 3:37 PM Casey Schaufler [off-list ref] wrote:
quoted
On 10/31/2018 2:57 PM, Kees Cook wrote:
quoted
On Wed, Oct 31, 2018 at 2:02 PM, Serge E. Hallyn [off-list ref] wrote:
quoted
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.
quoted
quoted
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.
quoted
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.
quoted
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.
quoted
quoted
quoted
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.
quoted
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.
quoted
 - 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.
quoted
  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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help