Re: caps in elf, next itteration (the hack get's bigger)

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


tytso@mit.edu writes:
> Date: Tue, 13 Apr 1999 08:28:58 +1000
> From: Richard Gooch <rgooch@atnf.csiro.au>
>
> This to me is one of the real blind-spots of some people who are
> pushing capabilities. There is absolutely no need to remove the
> privileges of the root account. By default root has all capabilities.
>
> Nope, not in a true capabilities based system. Root has *no*
> special privileges in a capabilites system.

True, in an ideologically pure capabilities system.

> Think about it: you will need *some* account* with the abilility to
> grant caps anyway. So root is it.
>
> Nope, in a full capabilities based system, you don't give *accounts*
> the ability to grant caps. Accounts have no capabilities
> whatsoever. *Programs* have privileges, and some accounts may have
> the right to run certain programs which have capabilities to do
> certain things.

UID=0 is not the same as the root account. You can have UID=0 mean
"all caps" but still not allow root logins. In such a system, you have
to use programmes to do anything, there is no special account.

root:*:0:0::/root:/bin/false

For the paranoid:
# set -e "s/^root//" /etc/passwd > /etc/p
# mv /etc/p /etc/passwd

> The major practical benefit that capabilities provide is that you can
> have privileged binaries that have *only* the privileges that they
> need, and no more. Having a root account with full privileges is
> completely orthogonal to this.
>
> What you are describing is not a full capabilities based system. It
> is a system with some practical value, but it still means that if an
> attacker cracks root, you're finished.

Can you please explain what you mean by "crack root"? Does that mean
"run crack on the password file, or use a sniffer, etc."? If so, just
don't have a root account.

> Capabilities are a good thing, as they give more flexibility. But
> there simply is no need to cripple root.
>
> Yes there is. It's a fundamental security principle called the
> "principle of least privilege". An account with full privileges to
> do anything violates this fundamental security design principle.

OK, let me be more explicit. There is no need to cripple UID=0 in the
kernel. Whether or not there is a root account is a separate matter.

> You might have one account (the security officer's account) which
> has the right to install capabilities on executables. However, this
> account may not have rights to override filesystem permissions, and
> all actions taken by the security officer's account may be logged to
> hell and back on a separate machine which isn't accessible by the
> security officer. So the security officer could in theory give
> permissions to a program which he could run that would override
> descretional access controls on a filesystem, but such a thing would
> be logged and caught by someone else. Note that in such a system,
> no one person has the equivalent of "root" access! And this is a
> feature!!

Sure. That's fine by me. But I see such a setup as separate from
whether UID=0 means "all caps" to the kernel.

Please also note that even if there is a fundamental problem with
suid-root being a magic flag for an ELF cap header, that doesn't mean
that using the sticky bit is the answer. That's even worse.

If you really want to completely remove UID=0 tests from the kernel,
then we have to put caps into the FS as metadata, because using the
sticky bit on ordinary user files is too insecure. At the moment the
debate is about ELF cap headers and whether to use suid-root or the
sticky bit as the magic flag. In that debate, I think suid-root wins
by default.

BTW: I even question whether setting/denying caps even belongs in the
kernel. It could also be done in the dynamic linker. The algorithm
would be:

1) check for CAP ELF header
2) if found, apply deny mask
3) if found and euid=0, apply grant mask.

To satisfy those who worry about booting a cap-less kernel and thus
granting all caps to a suid-root binary, modify the algorithm:

1) check for CAP ELF header
2) if found, apply deny mask
3) if found and euid=0 and cap-less kernel, scream and exit
4) otherwise, apply grant mask.

You could even have a special flag in the header to fine-tune whether
or not a binary works or fails on a cap-less kernel.

And as for static binaries, include the above code when statically
linking.

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/