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

David L. Parsley (kparse@salem.k12.va.us)
Fri, 9 Apr 1999 17:48:14 -0400 (EDT)


Hi all,
OK, I think I know a good way to improve 3 aspects of my previous
solution:
1) It should be possible for a user with elevated capabilities to create a
binary with elevated capabilities, iff that user has the capability raised
for setting capabilities in the fs. (CAP_SETCAP ?)
2) The ability to mark a binary setuid root should not equate to the
ability to grant all capabilities.
3) File owner semantics should remain (mostly) intact, so that a program
with elevated capabilities can still be edited by their 'owner'.

This gets a bit hairy, but to do this we need to modify the
kernel's understanding of 'setuid 0'. To the kernel, being setuid 0 would
mean that the program has elevated capabilities, and that not only the
capability bitmasks are found in the elf header, but
_also_the_file_owner_, and that the binary is _immutable_. Confused? I
don't think _I'm_ confused so let me explain:

1) 'setuid 0' is _just_ a filesystem flag that alerts the kernel to a
program that has capabilities + uid + gid in the elf headers. (putting
uid & gid in the headers was Albert's idea, and now seems to me a must)

2) A file flagged with capability support is immutable untill that flag is
unset; this prevents the file owner from directly modifying the binary to
set all cap flags.

3) when a user attempts to _set_ the capability flag (setuid 0), the
kernel checks: A) that the user has the capability for granting
capabilities to a program (CAP_SETCAP) B) That the capability flags raised
in the elf header are no more than those the user (process) currently
posseses, C) that the uid and gid in the elf header are legally settable
by the user. The syscall fails if any of these tests fail.

4) when a user attempts to _unset_ the capability flag, the kernel checks:
A) that the user has CAP_SETCAP for the fs, i.e., the ability to grant is
also the ability to remove B) that the file's uid and gid in the elf
headers are legally settable by the user. If either test fails, the
syscall fails, otherwise the kernel removes the setuid bit and (_most_
_importantly_) sets the file owner and group to those present in the elf
headers.

5) when the kernel exec's an elf binary, the effect is exactly as in my
previous itteration:
- checks capability flag (setuid 0) and if set uses caps + uid + gid from
elf headers
- if calling process has no caps, process runs with no caps
- if calling process has elevated caps, kernel applies the permittable and
inheritable cap flags from the binary (which can only be modified by the
owner in any event)

I _think_ this covers all the bases to give us a very flexible and
UNIX-ish capability system for elf binaries, but I won't go as far as
calling this a 'final' itteration yet. Add the notion of user cabilities
granted by 'login' from /etc/shadow or wherever...

It's a bit hairy, but I think there's some ellegance to it, not to
mention the most excellent property of remaining compatible with current
tools. I have _no_doubt_ that there are more details to be worked out,
but I hope that other details will become obvious in light of the above.

later...

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