Re: caps in elf headers: use the sticky bit!

David L. Parsley (kparse@salem.k12.va.us)
Tue, 13 Apr 1999 09:54:53 -0400 (EDT)


Hi Richard,

On Tue, 13 Apr 1999, Richard Gooch wrote:

[snip]
> > We're talking about a transition to a system where the admin can
> > delegate by a means other than 'sudo'. I'm just talking about
> > flexibility and correctness.
>
> I think the suid-root magic marker scheme has all that flexibility.

No, it definitely removes flexibility. And it's starting to get very low
marks for correctness...

wrt many of the 'sticky bit' problems, Eric Biederman made the excellent
(and I believe completely correct) suggestion of requiring both the sticky
bit and the immutable bit, which solves the problem of booting an older
kernel, since users can't set the immutable bit. I've been thinking some
about the best semantics for this, but you can derive them as well. A lot
of the real work can be done in userspace and taken out of the kernel.

What remains is the nfs problem, which may be solvable (for instance, can
nfs return extended file attributes?); or maybe we just have to accept
that nfs won't work with real capabilities support without major
modifications. (capabilities in the fs is considered the ideal, I
believe) In any case, with Eric's suggestion, the sticky-bit solution
gives us the ability to create a complete and true capability-enabled
system _now_. If you're running a system with this security model, you
should probably re-think using nfs anyway.

[snip more, thankfully, since this sucker is getting long]
> > No, execute permissions are in place for the file owner only. I'm
> > jschmoe, a trusted junior admin with a few caps. I wrote a program
> > w/ caps that I don't want anybody else to read, write or execute.
> > The correct way to do this is give the perms I've shown; I could
> > also use my private group, but that just exposes another problem in
> > this hack.
>
> If you have the caps when you log in, why do you need to write a
> binary which gives you those caps? It can't be for the benefit of
> everybody else, since you're taking away rwx access for others.

Because, if I log in remotely, I probably won't have _any_ caps when I log
in, but my executable _will_. This is an added flexibility in the sticky
bit solution.

> I said that because I do think it's broken and it opens up security
> holes. Because of the security holes, I don't think you solution
> should be considered. That's not a personal statement, it's a
> reflection on the idea.

Of two real security problems mentioned, I feel Eric Biederman has already
closed one very satisfactorily. You obviously have much more experience
with nfs than I do, would you mind sparing a few cycles to see if a
satisfactory solution exists?

> > I just prefer to get some real 'show-stopper' examples where you
> > have already asked the question 'can this show stopper be worked
> > around in an easy, clean, UNIX-like way?'
>
> I've given them already:
>
> - NFS/CODA export of cap-enabled binaries

Like I said, please think of a solution. The CODA code may well be very
easily fixable, since it's not in wide deployment yet and there are few
mutli-platform issues to consider. Heck, how many UNIX platforms really
use the sticky bit for it's old intended use? Maybe this could become a
new standard for a compatible way to enable capabilities on multiple
platforms. ;-)

> - non-root access to /usr with < 2.3 kernels.

Fixed.

[snip, snip]
> > That's fine. I think you and I are aiming at different goals.
>
> Probably. I want a good, workable solution that doesn't strip away
> NFS/CODA and also works with tar, cp, cpio and all the rest.

The sticky bit solution can work just fine with tar, cp, cpio ... I've
tried to think through proper semantics, and basically it works like
before: previously, only root could create files with setuid root set;
now, only a process with CAP_SETFCAP can create files with the sticky bit
(and therefore the immutable bit; this must go into kernel).

> > We're not _granting_ capabilities, we're stripping away all the
> > unneeded capabilities. Otherwise it runs 'full bore'. Are you
> > saying that portmap should be run with _all_ capabilities? Or do we
> > need to cripple root before running it? With setuid0, to strip away
> > unneeded caps you need to make it, well, setuid0.
>
> No! I already made this point last week. You only need suid-root to
> *grant* caps. Any binary can have its CAP ELF section with a mask of
> caps that are *removed*. There is no privilege needed for that.

Well, for one, the standard for capabilities doesn't exactly have a 'deny
mask' as such; it would have to be done in the interaction of the current
process' inheritable set and the file's inheritable set. You _could_ just
put a flat 'deny' mask in there, but you get further from true
capabilities, and the file owner can modify them.

[sigh... Snip!]
> > In any event, my portmap binary has a 'permitted' set with only the
> > caps it needs, and an empty 'inheritable' set. So I'm stripping
> > away caps.
>
> Fine. No need for any magic flags, be it suid-root or the sticky bit.

Actually, if we use real capabilities, the inheritable set is important,
too, since it determines what caps the new process can inherit from the
current process. It still needs to be flagged. I've already pointed out
the problem with flagging it 'setuid0'. If you _don't_ flag it, then the
user who owns the file can set the inheritable mask at will. At this
point, we need to decide how far we wish to depart from real capabilities
to implement the setuid0 hack; or, if we want to migrate to real
capabilities, how do we fix the remote fs problem with stickybit/immutable
bit capabilities.

> > Are you saying the kernel can apply some of the privs fields to a
> > non-setuid-root binary? 'Inheritable', I guess? Have you looked at
> > the queer way a new process get's it's caps and how it relates to
> > inheritable?
>
> The kernel can always look at the CAP ELF section and apply the deny
> mask. I don't understand your reference to queer inheritance.

I'm referring to what I read in the 'linux-privs' paper at kernel.org.
Executables just don't _have_ a deny mask in this system. The way a new
process gets it's caps is, IMHO, a bit queer. The more I think about it,
though, the more sense it makes.

To quote the linux-privs document:

"pP' = fP | ( fI & pI ).

Or in other words, the process' permitted set becomes the combination of
the permitted set of the exec()'d file and those inheritable capabilities
of the exec()ing file that are also inheritable by the file."

Where the permitted set is the set of caps legally raisable in the
effective set.

So, though it seems a bit strange at first, the new process can get
permitted caps that are neither present in the parent, nor set in the
file's permitted set. I assume the POSIX spec which I've asked about
ordering will talk more about this; and indeed, there's more info in the
linux-privs doc. For your convenience:
http://www1.us.kernel.org/pub/linux/libs/security/linux-privs/doc/linux-privs.html/linux-privs-3.html

[snip]
> > You've still taken a binary which was formerly _not_ setuid root,
> > and _made_ it setuid root. This is broken for backwards
> > compatibility, across nfs filesystem, ... I think having named now
> > setuid root is a Bad Thing.
>
> Agreed, if you will always run named as root. In which case you just
> fill in the cap deny mask. No magic flags needed.

Same argument applies.

> > I think one fundamental disagreement between us is that you still
> > think of root as all powerful. To me, setuid root just means 'give
> > this program root's rights in the fs'. I reallize that, if Linux
> > ever goes to a true implementation of capabilities, this will be a
> > bit of an ugly transition in thinking.
>
> I do indeed think of root as all-powerful. It is effectively the same
> as CAP_GRANT. Whoever has that privilege is all-powerful. We may as
> well call that UID=0.

It is possible that root may log in remotely with no caps, but still have
fs rights. I reallize the implications of this with current systems, but
this is an inherent flexibility in the capabilities-based system. It also
allows for the possibility of say, the security officer (from Ted's
example) having CAP_SETFCAP and being uid!=0.

> > Well, this is a consideration for the lead admin; anyone with junior
> > admins beneath her should understand what she's doing when she checks
> > 'capelf hack' in the kernel configuration.
>
> No he doesn't. It's quite resonable to give junior admins access to a
> FS which is mounted with the "sticky-means caps" option. But he
> doesn't want to check up on the juniors. With the suid-root scheme, it
> doesn't matter. Juniors can write as much as they like but can't ever
> grant caps.

Like I said, this appears to be the only remaining problem to be solved;
or discarded w/o major nfs mods, which would be required for true fs
capabilities anyway.

[snip]
> I think the assumption you've been making is that a file needs to be
> suid-root in order to *deny* caps. That is not the case. You only need
> suid-root to *grant* caps.

Same argument about the ways caps should actually work applies. A 'deny'
mask isn't part of the spec, and the file owner can still modify it at
will.

[snip]
> > > And let me say it again: we *can't* use the sticky bit, because it's
> > > insecure.
> >
> > Are you referring to the older kernel problem? Have you considered
> > possible user-space solutions?
>
> That and other problems. Even for the older kernel problem, I don't
> see any workable solutions. Please explain how you solve this
> situation:
> - some FS is mounted with "sticky means caps" option
> - FS has write access to some directories for junior sysadmins
> - reboot to 2.0
> - junior creates file with CAP ELF header and does chmod +t file
> - reboot to 2.3
> - junior runs file. Oops.

Are you happy with the immutable bit solution to this?

[snip more about nfs problems]

I have no good solution in mind for nfs, unless nfs can return extended
file attributes, in which case, problem solved. Otherwise... well, ideas?

> Regards,
>
> Richard....

Geez, this has gotten long. I'll say, though, that I'm thoroughly
enjoying our discussion, and enjoy being made to _think_ and _read_ and
_learn_. I don't think I've been this happy since the last time I took
quantum mechanics.

- --
David L. Parsley
Network Specialist
City of Salem Schools

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/