Re: caps in elf: a hybrid approach

Jeremy Fitzhardinge (jeremy@goop.org)
Tue, 13 Apr 1999 10:57:15 -0700 (PDT)


On 13-Apr-99 Richard Gooch wrote:
> Whoever can grant caps is in effect all-powerful.

Not if you can't grant more caps than you have yourself. Anyone should be able
to create a set-cap executable, in the same way anyone can create a suid <me>
executable.

>> Then give root all capabilities. "To cripple root", as you call it, is not
>> _needed_, but it is essential to be _able to do it_, else you can get just
>> a fraction of the security benefits out of this scheme.
>
> What exactly do you see as the benefits of a crippled root? Compare
> that with a system where there is no root account, but euid=0 means
> all caps to the kernel. What are the real benefits?

In a secure environment, like a firewall, I want to be able to say at some
point in the boot process "right, this is it, no process can *ever* get these
caps again, no ifs, no buts". It makes it much easier to assure a secure
environment when you *know* that there's no possible way a process can gain
big-foot all powerful permissions just because of its UID. You simply strip
all unwanted caps from all processes, and that's it.

The ability to create a capability-raising executable itself a capability, and
there's nothing special about it. If I'm an ordinary non-root user with an
extra capability, I should be able to give that away by creating an executable
which runs with that capability - but obviously I shouldn't be able to give away
capabilities I don't have.

When the kernel boots, it gives init all caps. Init can decide to pass on or
not various caps to its children. Programs like login can decide what caps
user processes get, using whatever mechanism it wants, including root logins.
This is all completely orthogonal to user-id - you can create a non uid 0
process which is all-powerful, and make a uid 0 process a nobody. Creating an
arbitary link between capabilities and the 0 uid for just that uid is a pretty
ugly wart.

Some executables will have extraordinary power to set "raise caps" on other
binaries, but they will be rare. Most execuables will want to remove caps from
their set, and perhaps refuse to run if the caller doesn't have suitable caps.

Now, I'm pretty unimpressed with both the u+s root and +t "solutions" to
marking cap-raising executables.

The u+s root approach is just way too fragile if the binary can be seen by a
non-cap system. The ability to raise caps is not a god-like special power,
its something that any user can do, so long as they can't raise caps above
their own level. Hiding the real owner inside the execuable is just plain
ugly, and will cause untold problems when moving executables between systems.

+t is a little cleaner, but it does mean that its pretty easy for people to
forge caps on another system which doesn't control the sticky bit properly.

I think it's best to do this:
- executables can't raise caps without a filesystem extention for caps
- executables can drop caps with a special ELF segment, or via syscall

This will make capablilities generally useful now, since dropping caps is the
most interesting thing right now.

Raising caps is a different beast. I don't see it as too problematic to make
this filesystem-specific, since it will always fail safely if an existing tool
or filesystem drops the extra information - it will never raise caps, and it
will still have the ability to drop them.

J

-
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/