Previous Next Table of Contents

3. Capability sets

In this chapter we introduce the concept of sets of capabilities. We also discuss the way in which such sets are maintained by the kernel and their association with system objects.

3.1 Sets of capabilities

Capabilities are independent and an application may have any number of them raised. The total selection of raised capabilities constitutes a capability set.

The capability set type

The kernel represents a capability set with the structure struct __cap_s. and may be thought of as a bitmap. The number of capability bits is currently 128.

There is a special, empty, capabiltiy set. This set has no capabilities raised.

Capability set macros

To manipulate capabilities, a kernel task uses one of the following three macros:

_cap_raise(cap_value_t capability)

This macro raises a capability in a capability set. It is used (with respect to a capability "struct __cap_s c") in the following manner:

   c._cap_raise(CAP_AUDIT_CONTROL);

Note, the macro is used in place of a member of the __cap_s.

_cap_lower(cap_value_t capability);

This macro lowers a capability in a capability set. It is used (with respect to a capability "struct __cap_s c") in the following manner:

   c._cap_lower(CAP_AUDIT_CONTROL);

Note, the macro is used in place of a member of the __cap_s.

_cap_raised(cap_value_t capability);

This macro returns true(!=0) if the capability is raised, and false(=0) if the capability was lowered. It is used in the following manner:

   if (c._cap_raised(CAP_AUDIT_CONTROL)) {

      /* .... action in case that capability is raised .... */

   }

Note, this macro is used as if it were a member of the capability structure.

3.2 Filesystem capabilitiy sets

Files on the system have the following capability sets.

Inheritable (fI)

This is the set of capabilities that the program is permitted to inherit. In this way, the program can be configured to be safe for operation with a fixed number of capabilities. (This has the feature of eliminating the total colapse of system security in the face of an insecurely written game.)

Permitted (fP)

This is the set of capabilities that are explicitly raised when the new process is exec()'d.

Effective (fE)

This is a single valued capability set (0 or  0) that is required to be set if the process (after an exec) is to have all of its capabilities automatically raised. It is intended to be used with programs that were written before the concept of capabilities was introduced. Newly written programs should raise their own capabilities manually.

3.3 Process/task capabilities

Processes (also know as kernel-tasks) have the following capability sets. They are copied unchanged when the process performs a fork() (or more generally, a clone()) function call.

Capability sets for a process are always affected by a call to exec(). Additionally, user level programs can manipulate their own capabilities with system calls to sys_[gs]etproccap().

Capabilities are grouped into sets and come in three forms: Effective; Inheritable; and Permitted.

Effective (pE)

This is the set of capabilities that are currently raised, or in effect.

This is set upon exec() to

   pE' = pP' & fE.

In other words, the new effective set is the new permitted set masked with the exec()uted file's effective set..

Capabilities may be raised in the Effective set only if they are already raised in the Permitted set. Capabilities not in the Effective set are "lowered", or are inactive.

Inheritable (pI)

This is the set of capabilities that can be passed through an exec(). These capabilities do not have to be raised in the predecessor to be passed, just present in the old process sets.

Following an exec(), the Inheritable set becomes

   pI' = pI.

Or in other words, the Inheritable set is passed unchanged thrhough and exec()..

Permitted (pP)

These are the capabilities that are potentially available to the current task.

Following an exec(), the process' Permitted set is constructed from the following combination of the former, and invoked, file's capability sets:

   pP' = fP | ( fI & pI ).

Or in other words, the process' permitted set becomes the combination of the permitted set of the exec()'d file and those inheritable capabilities of the exec()ing file that are also inheritable by the file.

Turning off a capability set in the Permitted set does not affect its status in the Inheritable set. The following is apparently a quote: (draft 13 of POSIX .1e) POSIX B.15.1.9

"The corresponding inheritable flag is not affected, so that privileges can be conditionally transmitted along a process chain whose intermediate processes may themselves have no privileges" (N.B. At this stage in the development of the POSIX standard, capabilities were termed privileges.) So if you want to turn off the capabilities in the Inheritable set, you should explicitly turn it off, not just turn it off in the Permitted set.


Previous Next Table of Contents