Messages in this thread | | | Date | Sat, 8 Aug 1998 21:49:40 +0200 | From | Alexander Kjeldaas <> | Subject | Linux Capability FAQ v0.1 [was Re: Stack Smashing and no-exec] |
| |
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
| |