Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Capabilities

A capability is one bit of a 64-bit mask. The kernel tests the effective set of the credentials of the thread at each privileged operation. The bits of the Linux capabilities keep their Linux numbers, so a mask moves between the two systems without a change of meaning. The Vex-only bits start at 48.

The check is cred_capable(). It reads one bit of cap_effective, and nothing else.

The bits

BitNameWhat it allows
0CAP_CHOWNChange the owner or the group of a file
1CAP_DAC_OVERRIDEBypass the read, write and execute permission checks
3CAP_FOWNERAct as the owner: chmod, timestamps, and removal from a sticky directory
4CAP_FSETIDKeep the setuid and setgid bits that a change would clear
5CAP_KILLSignal a process of another user
6CAP_SETGIDChange any group id, and set the supplementary groups
7CAP_SETUIDChange any user id
14CAP_IPC_LOCKLock memory beyond RLIMIT_MEMLOCK
18CAP_SYS_CHROOTChange the root directory
21CAP_SYS_ADMINRead and write trusted.* extended attributes, write the other security.* ones, set the host name, and force a session on a terminal
23CAP_SYS_NICESet the nice value of a process of another user, and lower its own past the floor
24CAP_SYS_RESOURCERaise a hard resource limit
25CAP_SYS_TIMEStep the realtime clock
26CAP_SYS_TTY_CONFIGChange the line settings of a serial port, and bind or unbind its terminal
27CAP_MKNODMake a device node
31CAP_SETFCAPSet or remove the security.capability extended attribute
34CAP_SYSLOGWrite to /dev/kplog
48CAP_MOUNTMount and unmount a filesystem
49CAP_DEVICEWrite to /dev/hwtree, which rescans, unbinds and ejects devices
50CAP_VM_NORESERVEMap memory with MAP_NORESERVE, and use the part of the commit limit that is kept for this capability

The unused bits stay unused. Vex does not move a Linux bit to a different number, so a check that a program makes against a Linux mask keeps its answer.

CAP_DAC_OVERRIDE still fails an execute check on a file that has no execute bit for any user. Linux does the same, and it keeps a data file from becoming executable through the capability alone.

The sets

struct __k_caps holds four masks and a word of flags: effective, permitted, ambient, bounding and flags. The capget(2) and capset(2) calls copy this structure.

  • The effective set gates the checks.
  • The permitted set is the ceiling of the effective and ambient sets.
  • The ambient set survives the exec of a program that has no setuid or setgid bit and no file capabilities.
  • The bounding set limits what an exec may grant. Only a lower mask is accepted, so it can shrink and never grow.

capset(2) needs no capability of its own. The subset rules are the whole check. It accepts a permitted set that is not larger than the current one, and a bounding set that is not larger. It accepts effective and ambient sets that are subsets of the new permitted set. A reserved field or a flag other than CAPS_KEEP fails with EINVAL.

CAPS_KEEP (0x0001) keeps the permitted set when the last user id 0 goes away. Without it, that change clears the permitted and ambient sets. A change of the effective id away from 0 clears the effective set. A change to 0 sets the effective set to the permitted set.

Program start

An exec works out the new capability sets in this order:

  1. It clears the flags. It also clears the ambient set when the program has a setuid or setgid bit, or when the file has capabilities.
  2. If the new effective id is 0, the permitted set becomes the bounding set, and the effective set becomes the permitted set.
  3. Otherwise the permitted set becomes the ambient set masked by the bounding set, and the effective set becomes the permitted set.
  4. The file capabilities add the file permitted set, masked by the bounding set. When the file effective flag is set, the effective set becomes the permitted set. A file that asks for an effective set with a bit outside the bounding set fails the exec with EPERM.

Vex has no inheritable capability set, so the inheritable mask of a file never grants anything.

The kernel sets AT_SECURE for the new program when an id differs from the real id. It also sets it when the real id is not 0 and the permitted set has a bit that is not ambient. A C library uses it to discard the environment of the caller.

File capabilities

The capabilities of a program live in the security.capability extended attribute. The layout is the Linux one, and the fields are little-endian:

FieldBytesMeaning
magic_etc4Revision in the top byte, flags in the low byte
data[0]8Low halves of permitted and inheritable
data[1]8High halves of permitted and inheritable
rootid4Revision 3 only

Three revisions exist, and the size tells them apart:

RevisionSizeSets
11232-bit, no rootid
22064-bit, no rootid
32464-bit, with rootid

VFS_CAP_FLAGS_EFFECTIVE (0x0001) in magic_etc asks for the permitted set to be effective at the start. A revision 3 attribute with a rootid that is not 0 names a user namespace, and Vex has none. It reads as no capabilities, as Linux does.

The VFS removes the attribute when the file is written or truncated, and when a chown changes its owner. A caller without CAP_SETFCAP cannot set it or remove it.

Source

  • capability.h — the bits, the sets and the xattr layout
  • cred.c — cred_capable, capset rules, exec and the parsing of the xattr
  • cred.h — the interface of the credential code
  • sys_cred.c — capget(2) and capset(2)
  • vnode.c — the xattr permissions and the VFS checks
  • sys_process.c — the file capabilities at exec
  • commit.c — the reserve for CAP_VM_NORESERVE