userspace capabilities [was Re: caps in elf headers: use the sticky bit!]

Paul Cassella (pwc@andrew.cmu.edu)
Tue, 13 Apr 1999 02:59:42 -0400 (EDT)


I think capabilities can be done almost entirely in userspace. This has
no sticky bit, no executable format changes, no filesystem changes, works
over NFS, through tar/backups/restores, is not dependant on any executable
or script type or format, and involves no setuid/gid anything. Also, it
doesn't treat uid 0 as special.

It seems to me that capabilities have two main uses:
The first is to associate certain privileges with users.
The second is to allow certain programs to run with additional
capabilities, no matter which user is running them.

An example of the first is giving an administrative user root-like
filesystem and process-killing capabilities.

Examples of the second are ping using raw sockets and Xwrapper fiddling
with the video hardware directly.

On Mon, 12 Apr 1999, Al Lipscomb wrote:

> I wonder if you could have a daemon (capsd?) that could hand out the caps
> afer a call. By convention programs would make a call to the daemon and if
> required obtain the required powers.

I think this can be done with one program that can grant arbitrary
capabilities, say /bin/caps, as in your scheme. /bin/caps would take a
command and argument like, say, strace or time, but would just acquire and
relinquish the "right" capabilities and then do the exec().

> In a very simple example you would have a file called /etc/caps.conf that
> would have the user/file information:

> #user:file:caps
> root:*:*
> backup:/bin/tar:READ_ALL,BACKUP,RESTORE
> joe:*:SECURITY

> root would be all powerful. backup could poke around and such. joe could
> create users, set passwords and other things of that nature.

There is no need for a daemon, but I would make the .conf files more
flexible; ie., what you have could become
/etc/caps.user.conf:
#user : caps
root : *
backup : READ_ALL, BACKUP, RESTORE
joe : SECURITY

and
/etc/caps.progs.conf:
#prog : caps : negative caps
/bin/ping.cap : SOCK_RAW :
/usr/X11R6/bin/Xwrapper.cap : VIDEO :
/.../untrusted/proprietary/app : : ROOT_RIGHTS

so that ping and X work as expected, and also no matter who runs the
untrusted program, it will not be able to do more damage than if run by an
"ordinary" user, no matter how poorly coded it is.

It may be that there's some way to use a daemon so that all the
capabilities config files don't need to be read and parsed every time
/bin/caps is invoked.

I think that for the example you gave, you'd probably not want to restrict
backup to only tar or any particular set of tools. For example, if
something "weird" happens, you might need to intervene manually, and you'd
want to be able to READ_ALL with any utility.

On the other hand, you might want to do something like only let certain
users run X, but they still shouldn't have the capability to fiddle with
the video card otherwise. This could be done with regular groups and
permission bits, but it would seem to be more elegant to make the
restriction in the capabilities utilities, and let userland worry about
it. This would probably involve making caps.users.conf look more like
yours.

Obviously, scripts could do the routine work; ie.,
addcap /bin/ping.cap SOCK_RAW
or whatever.

> A simple way to invoke the caps would be to say:
> /sbin/caps /bin/tar

This could be more transparant by doing for all prog's in caps.progs.conf,
for example, ping:

mv /bin/ping /bin/ping.cap
chmod -s /bin/ping.cap
echo exec /bin/caps /bin/ping.cap $rest_of_command_line > /bin/ping

> Later on, programs that needed it could be rewritted (or a patch to the
> libraries made) to call capsd at startup.

Capabilities could be granted in two "flavors", which I think are already
well-understood: automatic, for stuff like the current ping, which does
not understand capabilities, and available, for stuff like a new,
capabilities-aware ping, which will explicitly call getcap(SOCK_RAW), or
whatever, when it needs to.

> Standard backups work and since a program moved from host x to host y
> would not have any special powers due to whats in its header.A

This remains true in this modified version. In addition, /bin/caps could
emulate sudo when a kernel without capabilities is used; ie., the admin
could tell it who can execute what binaries, and it will let them. This
requires that it be setuid 0, which could be done in the startup scripts
for the non-capable kernel.

Also, users could create their own capability-enabled binaries with a
crontab-like setup. /bin/caps would of course check that the user (still)
has that particular capability before granting it.

The only thing left is to let /bin/caps set any capabilities it needs to.
One way would be setuid 0. Another would be

echo /bin/caps > /proc/sys/kernel/caps

at boot, a la /sbin/modprobe. This would need to be done, I suppose,
"before capabilities are turned on", especially if uid 0 is made not to
mean anything special. Alternatively, and less flexibly, it could be done
at kernel compile. Neither of these feels particularly elegent, but it
would seem to be either that or setuid.

The caps.progs.conf file may or may not want to keep timestamps and/or
checksums or whatever.

cp and mv, etc, would create non-privileged executables, unless someone
not only teaches them what to do, but also decides what _should_ be done,
anyway.

Finally, the first main objective (associating capabilities with users)
could be done by having login be run by /bin/caps and inherit the
capability to set all capabilities, which it would do as per the .conf
files before giving up this capability and starting the user shell.

> Just a thought.

It was a pretty good one, actually. I hadn't even thought about doing it
in userland. (Actually, I hadn't really thought about doing it at all, but
your idea made me think of this, which is basically just a minor extension
of yours, with some of the details fleshed out.)

Comments?

Sorry if this is a little incoherent; pine ate my first version, so I may
have skipped something I remember typing. :(

-- 
Paul Cassella    ::  Doctor Who: He's back, and it's About Time.
fortytwo@cmu.edu ::  http://www.contrib.andrew.cmu.edu/~pwc

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