Re: updated proposal for cap in elf

David L. Parsley (kparse@salem.k12.va.us)
Sun, 18 Apr 1999 16:21:34 -0400 (EDT)


Hi Albert,

On Sun, 18 Apr 1999, Albert D. Cahalan wrote:
> David L. Parsley writes:
> > On Sat, 17 Apr 1999, Albert D. Cahalan wrote:
> >> In the "pP' = fP | (fI & pI)" expression you can see that the admin
> >> gets power from the "(fI & pI)" part, while normal users can only get
> >> power from the "fP" part.
> >
> > Exactly. This is an assumption I've been kind of making, but it hasn't
> > been said out loud enough yet. Not to say that a few normal users might
> > not have a few bits set in pI...
>
> Note that this system does not allow an admin to have some power that
> just works with every unmarked executable. It isn't even a config option.
> Such a feature would allow a more secure but still UNIX-like behavior.
>
> >> No, we need a set of bits (I'll call it "pm") that are always added to pP.
> >> The set would be 0 for maximum security or normal users, and ~0 for an
> >> admin on a more normal system. This might be help kill off the ugly hack
> >> in exec.c that pretends an executable has fI and fE full if UID 0 runs it.
> >
> > Well, we should certainly get rid of all uid=0=special code; treatment for
> > fI and fE should be configurable (under /proc somewhere?), as you'll want
> > differnt defaults during development of a new, capability-enhanced distro.
>
> Just how configurable? You would need to have:
>
> 1. some bits that are 0
> 2. some bits that are 1
> 3. some bits that are 1 for root and 0 for others

I'm just thinking of two options for default inheritance on a non-cap
file:
- inherit everything from parent process (compatible; root login must get
all pI set)
- inherit nothing from parent process (paranoid, takes work to set fI on
all needed files)

> Ugh. You still don't kill the special treatment for root. This won't do.

No, I think on login root should have all pI set, and root magic should be
removed from the kernel.

> >> new_pP = fP | (fI & old_pI) | old_pm;
> >> if(new_pP & ~old_pM) return -EPERM; /* getting prohibited caps? */
> >> if((new_pP & fm) != fm) return -EPERM; /* not enough? */
> >
> > OK, I think the min and max values are already implicit in the fI and fP,
>
> Please explain how to do this:
>
> 1. there exists a program called a.out that everyone can run
> 2. there are two admins, avatar and super
> 3. there a capability called CAP_X
> 4. avatar can run everything with CAP_X
so avatar has CAP_X in pI

> 5. super only gets CAP_X when running a.out
and super gets it from fP

> Now add:
>
> 6. there is a restricted user that must _never_ get CAP_X
> (the normal users get CAP_X via fP, but this user can't do that)

OK, so you're wanting to add a mechanism whereby certain users _never_ get
a certain cap, irrespective of fP and fI. I just don't see wide
application for this; if you can give me some good concrete examples, that
would help. Off hand, though, I think it would be most appropriate to
control this in the filesystem as currently. I.e., CAP_X is obviously
dangerous in the wrong hands; so most files w/ CAP_X in fP should be in
some group to which only certain users belong, and world execute bit
should be removed.

> Add this too:
>
> 7. there is a buggy executable called b.out that must never get CAP_X
> (avatar wants to run this executable)

I don't understand this part; I would think just leave CAP_X out of fP and
fI.

> > [...] For the minimum, it's possible the binary will get caps
> > from fP and fI that still won't be sufficient; I say just let it fail,
> > much as 'chown bin myfile' always failed in the past.
>
> This is very bad. When 'chown bin myfile' always failed in the past,
> every single privileged operation failed. With the new system, you
> can have partial failures. This can really make a mess with programs
> that expect to perform multiple operations.

Again, I'd be interested in real-world examples of this.

It seems like, in light of what I'm asking for, a better explanation of my
fM proposal would be in order. So far, it seems like we've pretty much
agreed that the 'shell' of an admin will have a pretty full pI. Now,
let's say this admin uses some random mail reader to read his/her mail.
The mail program has: fP=0, fI=0, fE=0; since all it needs are file
rights. So obviously pP for the mail prog is 0. BUT, pI' = pI; so the
mail program _does_ have a full pI. So somebody could send the admin a
message with a buffer overflow exploit, which could then exec something
with a bigger fI and do some damage.

The same also applies to admin starting named(8) by hand. named(8) only
inherits, say CAP_NET_BIND_SERVICE, but now has a full pI; so the named
exploit is now nearly as potent as before. (assuming /bin/sh has a fairly
large inheritable set)

So basically what I'm saying is, I think it would be really useful to have
a simple mechanism for constraining the inheritable set of the exec'ed
process. Even though it's pP is small, pI can still do a lot of damage.

cheers,
David

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