Linux Capability FAQ v0.1 [was Re: Stack Smashing and no-exec]

Alexander Kjeldaas (astor@guardian.no)
Sat, 8 Aug 1998 21:49:40 +0200


On Fri, Aug 07, 1998 at 06:42:54PM -0700, Jon M. Taylor wrote:
>
> Would this be done, or would you have a user that has the
> additional priv of being able to bind to that specific port? That is,
> would capabilities be bound to a specific user like group membership is
> now? Or would capabilities be bound to a group instead? Also, how would
> these capabilities be defined? Would there be categories and/or any sort
> of hierarchy to subcategorize the set of all possible capabilities, or
> would it just be one long list of stuff, each capability standing alone?
>

Instead of answering this mail, I sat down and made a perliminary FAQ
about this issue.

Linux Capabilities FAQ 0.1
==========================

This FAQ was written and is maintained by:
Alexander Kjeldaas <astor@guardian.no>

1) What is a capability?

The name "capabilities" as used in the Linux kernel can be confusing.
First there are Capabilities as defined in computer science. A
capability is a token used by a process to prove that it is allowed to
do an operation on an object. The capability identifies the object
and the operations allowed on that object. A file descriptor is a
capability. You create the file descriptor with the "open" call and
request read or write permissions. Later, when doing a read or write,
the kernel uses the file descriptor as an index into a datastructure
that indicates what operations are allowed. This is an efficient way
to check permissions - you create the necessary datastructures to
check permissions once during the "open" call. Later read and write
calls only have to do a table lookup. Other operations on
capabilities include copying capabilities, giving a capability to
another process, modifying a capability, and revoking a capability.
Modifying a capability can be something like taking a read-write
filedescriptor and making it read-only. A capability often has a
notion of an "owner" which is able to invalidate all copies and
derived versions of a capability. Entire OSes are based on this
"capability" model, with varying degrees of purity. There are other
ways of implementing capabilities than the file descriptor model -
traditionally special hardware has been used, but recently the memory
management unit of the CPU is often used.

Then there is something quite different called "POSIX capabilities"
which is what Linux uses. Capabilities here are a partitioning of the
all powerful root privilege into a set of distinct privileges. Users
familiar with VMS or "Trusted" versions of other UNIX variants will
know this under the name "privileges". The reason we use the name
"capabilities" in Linux is that this is what the POSIX draft uses.

2) So what is a "POSIX capability"?

A process has three sets of bitmaps called the Inheritable(I),
Permitted(P), and Effective(E) capabilities. Each capability is
implemented as a bit in each of these bitmaps which is either set or
unset. When a process tries to do a privileged operation, the
operating system will check the appropriate bit in the Effective set
of the process (instead of checking whether the effective uid of the
process i 0 as is normally done). The Permitted set of the process
indicates the capabilities the process can use. The process can have
capabilities set in the permitted set that are not in the effective
set. This means that the process has temporarily lowered this
capability. A process is allowed to set a bit in its Effective set
only if it is available in the Permitted set. The distinction between
Effective and Permitted exists so that processes can "bracket"
operations that need privilege. The Inheritable capabilities are the
capabilities of the current process that should be inherited by child
processes. The Permitted set of a process is masked against the
Inheritable set before being transferred to another process. "Another
process" means a process image after an exec() call. Capabilities are
copied to child processes or threads. The capability rules (see own
question) are only enforced during exec().

3) What about other entities in the system? Users, Groups, Files?

Files have capabilities. Conseptually they have three bitmaps just as
processes, but we call them by other names to avoid confusion. Only
executable files have capabilities, libraries don't have capabilities
(yet). They three sets are called the Allowed set, the Forced set, and
the Effective set. The Allowed set indicates what capabilities the
executable is allowed to receive from an execing process. The Forced
set is a set of capabilities created out of thin air and given to the
process after execing the executable. The forced set is similar in
nature to the setuid feature. In fact, the setuid bit from the
filesystem is "read" as a full Forced set by the kernel. The
Effective set is acutally not a set, but a single bit. It indicates
which bits set in the permitted set of the new process should be set
in the effective set of the new process. However, transferring only a
few bits from the Permitted set to the Effective bit doesn't seem to
be useful. The Effective set is best thought of as a "capability
aware" bit. Only if the executable is aware of the capability API can
it start with an empty Effective set.
NOTE: Filesystem support for capabilities is not part of Linux 2.2

Users and Groups don't have associated capabilities from the kernel's
point of view, but it is entirely reasonable to associate users with
capabilities. By letting the "login" program set some capabilities it
is possible to make a "backup" user for example. This could be
implemented as a PAM module. However, this is not done yet. Also see
question about capability policies.

4) What capabilities exist?

The capabilities available in Linux are listed and documented in the
file /usr/src/linux/include/linux/capability.h.

5) Are Linux capabilities hierarchical?

No, you cannot make a "subcapability" out of a Linux capability as in
capability-based OSes.

6) What about passing capabilities between processes?

Currently this is done by a systemcall setcap which can set the
capability of another process. This requires the CAP_SETPCAP
capability which you will only grant to a _few_ processes.
CAP_SETPCAP was intended as a workaround to be able to implement
filesystem support for capabilities using a daemon outside the kernel.

There has been discussions about implementing socket-level capability
passing. This means that you can pass a capability over a socket. No
support for this exists in the normal kernel however.

7) I see securelevel has been removed from 2.2 and are superceeded by
capabilities. How do I emulate securelevel using capabilities?

The setcap system call can remove a capability from _all_ processes on
the system in one atomic operation. The setcap utility from the
libcap distribution will do this for you. The utility requires the
CAP_SETPCAP privilege to do this. The CAP_SETPCAP capability is not
enabled by default.

libcap is available from
ftp://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.1/

8) Seems I need a CAP_SETPCAP capability that I don't have to make use
of capabilities. How do I enable this capability?

Well no, but for some uses such as emulating securelevel you need it.
What you do is you change the definition of CAP_INIT_EFF_SET and
CAP_INIT_INH_SET to the following in include/linux/capability.h:

#define CAP_INIT_EFF_SET { ~0 }
#define CAP_INIT_INH_SET { ~0 }

This will start init with a full capability set and not with
CAP_SETPCAP removed.

9) How do I start a process with a limited set of capabilities?

Get the libcap library and use the execcap utility. The following
example starts the update daemon with only the CAP_SYS_ADMIN
capability.

execcap 'cap_sys_admin=eip' update

10) How do I start a process with a limited set of capabilities under
another uid?

Use the sucap utility which changes uid from root without loosing any
capabilities. Normally all capabilities are cleared when changing uid
from root. The sucap utility requires the CAP_SETPCAP capability.
The following example starts updated under uid updated and gid updated
with CAP_SYS_ADMIN raised in the Effective set.

sucap updated updated execcap 'cap_sys_admin=eip' update

[ Sucap is currently available from
ftp://ftp.guardian.no/pub/free/linux/capabilities/sucap.c. It is
intended to be put in the progs directory of libcap.]

11) What are the "capability rules"

The capability rules are the rules used to set the capabilities of the
new process image after an exec. They work like this:

pI' = pI
(***) pP' = fP | (fI & pI)
pE' = pP' & fE [NB. fE is 0 or ~0]

I=Inheritable, P=Permitted, E=Effective // p=process, f=file
' indicates post-exec().

Now to make any sense of the equations think of fP as the Forced set
of the executable, and fI as the Allowed set of the executable.
Notice how the Inheritable set isn't touched at all during exec().

12) What are the laws for setting capability bits in the Inheritable,
Permitted, and Effective sets?

Bits can be transferred from Permitted to either Effective or
Inheritable set.

13) Where is the standard on which the Linux capabilities are based?

There used to be a POSIX draft called POSIX.6 and later POSIX 1003.1e.
However after the committee had spent over 10 years, POSIX decided
that enough is enough and dropped the draft. There will therefore not
be a POSIX standard covering this aspect anytime soon. This may lead
to that the POSIX draft is available for free, however.

astor

-- 
 Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway
 http://www.guardian.no/

- 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.altern.org/andrebalsa/doc/lkml-faq.html