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

Richard Gooch (rgooch@atnf.csiro.au)
Tue, 13 Apr 1999 15:24:32 +1000


David L. Parsley writes:
> Hi Richard,
> First off, I got a bit hot-headed because the first thing I hear
> from you is to just say my idea is 'just plain broken' 'just cannot be
> used' 'end of story.' I prefer more colorful expressions, like 'broken
> ass' ;-) In any event, I think there are still issues to be discussed.

Actually, I prefer to avoid colourful expressions (that doesn't mean I
*never* use them, of course), because it is more emotive. Better to
avoid emotional content when having a technical debate, IMO.

> > I fundamentally question the need for this. Once a binary grants
> > privileges, it is no longer an ordinary file. It is a system file. Who
> > cares if jbloggs was the originator? We have the same setup now with
> > suid-root binaries. The "originator" (whoever compiled it) is
> > different than the "owner" (root) if the binary grants
> > privileges. This is not causing a problem.
>
> 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.

> > > Quota is just a symptom of the deeper problem: storing 'setuid 0' in the
> > > fs is just a lie in many cases; it might not be setuid, it might not be
> > > owned by root. What about the case of '-rws------ root root ...
> > > mybinary', where _I_ am the actual owner of the file, but I can't even
> > > execute the darn thing?!?
> >
> > Now why would root (or the capabilities granting utility) remove
> > execute permission in the first place?
>
> 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.

The solution to giving certain *users* caps is to write a PAM.

> > > > > Please give a little bit of thought to the sticky bit idea, and look at
> > > > > the problems with it and solutions suggested.
> > > >
> > > > Overloading the sticky bit is just plain broken. It opens up a
> > > > whopping big security hole. It just cannot be used. End of story.
>
> I thought this was kind of rude. I probably should have waited an
> hour or so before responding. Oh well, lessons learned.

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.

> 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

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

Basically, anywhere the sticky bit can leak in is a show
stopper. Also, anywhere you can modify a file with the sticky bit is
also a problem.

> > No, I've read the various posts on this topic and thought about the
> > issues. I just don't agree with your view. Deal with it.
>
> 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.

> > > -rwsr-xr-x 1 root root 28240 Mar 24 23:55 portmap*
> > >
> > > Cool, we've modified portmap and crippled it's capabilities! Now, every
> > > binary that was formerly just _run_ by root is now setuid root! Sound
> > > good?
> >
> > Strange idea to grant capabilities to a binary which is only run by
> > root.
>
> 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.

So, if you feel you must run portmap as UID=0 but are worried portmap
could be hacked, then add ~CAP_PORT to the deny mask.

> > > with my broken ass system:
> See, at least I'm fair.
> > >
> > > -rwxr-xr-t 1 root root 28240 Mar 24 23:55 portmap*
> > >
> > > My portmap is completely harmless under older kernels.
>
> and under the modified kernel will only run with the caps it needs.
>
> > What's this 't' bit needed for? Oh, I get it. You want to grant
> > capabilities!
>
> Not grant, strip.

Exactly my point! You don't need any magic flags to tell the kernel to
strip caps. The algorithm is this:

1) kernel ELF loader checks for CAP section
2) if found, apply deny mask
3) if found and if uid=0 and suid set, apply grant mask.

> > Wow. How useful, since root already has those
> > capabilities. Oh well. Just a few more cycles doing nothing useful.
>
> Admit it, you can be rude too.

Well, you did ask for it. But apologies anyway.

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

> > Instead, why not run portmap under a special account? Then it makes
> > sense granting privileges.
> >
> > Alternately, if you *really* want to run this as root, just fill in
> > the section of the ELF header which removes all but the required
> > capabilities. *Note that this does not require privileged filesystem
> > bits, since you can always reduce 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.

> [snip bad named example]
>
> Hrm; I made an error in logic here. Sorry to have wasted your cycles on
> this one. But you still bring up a point:
>
> > > I prefer:
> > > -rwsr-xr-t 1 syssvc root 432880 Jan 4 01:07 named*
> >
> > I prefer:
> > named: inode: euid=0, suid
> > caps: ports

This is only required if you want to run named under another account.

> > and then run named under the daemon account.
<
> 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.

> > > Yes, I reallize your case is fixable as well, but think about all
> > > the repercussions. For instance, what if root wants to mark a
> > > binary setuid root that has no caps? Should this require some cap?
> >
> > Why on earth would you want to do that anyway? Marking a binary
> > suid-root means "give executor all privileges".
>
> 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.

You can always strip away caps and be left with a diminished
root. Take away CAP_SUID and that process (with UID=0) can no longer
grant privileges.

And don't worry about the root account: you can always disable logins
or use PAM to reduce capabilities. That will strip root.

> > > Worried about /home being full of sticky bit binaries? Mount it
> > > with caps off! So far, the sticky bit problems are _EASY_, and the
> > > solution gives us a _lot_ of flexibility and compatibility just not
> > > present in the setuid 0 solution.
> >
> > Doesn't help me when there are files with the sticky bit in /usr. Oh,
> > yeah, I forgot to mention, we have junior administrators who can write
> > to certain parts of /usr but who don't have root access. I don't want
> > them hacking in either.
>
> 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.

> > > Keep looking, and you'll keep seeing why using 'setuid 0' is at
> > > _least_ as broken, if not a lot _more_ broken, than using the sticky
> > > bit.
> >
> > No, you've just made assumptions about the suid-root scheme which
> > create these non-problems.
>
> I've made, as far as I know, two assumption: if a file has
> capabilities in the headers, it will be marked setuid-root. It
> looks as if this assumption may be wrong? Also, I assume we want
> something pretty darn close to _true_ capabilities support. So I
> may be wrong in both cases.

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.

> > > Just because I don't have any patches in the kernel doesn't make me
> > > a jackass.
> >
> > Interesting point. Erm, so why did you raise it?
>
> Because your first response to me was to wave off my ideas with
> impunity and somewhat rudely. So I thought, geez, do I need a patch
> in the kernel before this guy will give me a second thought?

I've actually thought about the issues. And I'm sorry if you felt I
was being rude. I'm trying to be matter-of-fact. I'm interested in the
idea, not who came up with it.

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

Please don't tell me to run a find and kill all new files with sticky
bits. That's just slow and ugly.

> > And disabling over NFS is no good, because I *want* NFS
> > support for capability-granting binaries. All the world is not
> > Linux-2.2.
>
> Ok, you want an IRIX machine (for example) to be nfs-serving elf
> binaries to a Linux machine, and you want the Linux machine to
> respect setuid 0 (and therefore your capability scheme) on the nfs
> mount.

Yes. Actually, my NFS server is running Linux 2.0.

> I guess the problem is, the IRIX machine actually makes _use_ of the
> sticky bit for something else? But, in the traditional use of
> sticky bits, the IRIX machine probably won't be executing the Linux
> binaries, so won't keep them in virtual mem. Maybe with binary
> compatibility, but this is starting to get a bit far out for me. Or
> maybe I misunderstand what you're saying...

Forget IRIX. Think Linux 2.0. Or even Linux 2.2. The sticky bit means
nothing and anybody can set it. The point is I stick a whole lot of
binaries (maybe even a shared /usr) on the NFS server. As far as the
server is concerned, they're just files. Binary compatibility has
nothing to do with it.

Regards,

Richard....

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