capset(2)
Raw syscall to set a thread's permitted, effective and inheritable capability sets.
- Since
- Linux 2.2check your kernel →
- glibc
- none (use syscall(2))
- System
- Linux
- Man page
- capset(2)
Synopsis
#include <linux/capability.h> /* Definition of CAP_* and
_LINUX_CAPABILITY_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
int syscall(SYS_capget, cap_user_header_t hdrp,
cap_user_data_t datap);
int syscall(SYS_capset, cap_user_header_t hdrp,
const cap_user_data_t datap);Rod's take
Five per-thread capability sets, and the execve transformation between them is where everybody's mental model falls apart. Permitted is the ceiling, effective is what the kernel actually checks, inheritable and ambient decide what survives exec, and bounding caps what file capabilities can hand out. Don't drive capset(2) by hand; the header versioning has bitten people and libcap's cap_set_proc exists for a reason. Drop what you don't need, clear ambient, lock the securebits so root can't quietly get everything back on the next setuid exec. Kerrisk spends a whole chapter on this. Read it.
Flags and arguments that matter
| Name | What it does |
|---|---|
| _LINUX_CAPABILITY_VERSION_3Linux 2.6.26 | Header version for 64-bit capability sets (datap[0] and datap[1]). V2 (2.6.25) was a glitch; V1 is 32-bit. |
| Permitted | Limiting superset of what the thread may make effective. Can be dropped, not regained without exec of a privileged file. |
| Effective | The set the kernel actually checks for permission decisions. |
| Inheritable | Caps preserved across execve; only useful combined with file inheritable caps or ambient. |
| BoundingLinux 2.6.25 (per-thread) | Caps file capabilities can grant at exec. Shrink with PR_CAPBSET_DROP (needs CAP_SETPCAP); can't be restored. |
| AmbientLinux 4.3 | Caps kept across execve of unprivileged binaries; always a subset of permitted and inheritable. Set via prctl. |
| SECBIT_NOROOT / SECBIT_KEEP_CAPS | Securebits: stop UID 0 getting caps on exec; KEEP_CAPS keeps permitted (not effective) caps across a UID switch. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EPERM | Tried to add a cap to permitted, or make effective a cap not in permitted. |
| EPERM | Tried to add to inheritable a cap outside the bounding set, or outside permitted without CAP_SETPCAP. |
| EINVAL | One of the arguments was invalid (e.g. an unsupported header version). |
| EFAULT | Bad memory address; hdrp must not be NULL. |
| ESRCH | No such thread. |
Example
/* still root here: lock securebits, switch UID, then drop the rest */
if (prctl(PR_SET_SECUREBITS,
SECBIT_NOROOT | SECBIT_NOROOT_LOCKED, 0, 0, 0) < 0)
err(1, "PR_SET_SECUREBITS");
if (setgroups(0, NULL) < 0 ||
setresgid(gid, gid, gid) < 0 ||
setresuid(uid, uid, uid) < 0)
err(1, "drop uid/gid");
cap_t empty = cap_init(); /* libcap; calls capset(2) */
if (cap_set_proc(empty) < 0)
err(1, "cap_set_proc");
cap_free(empty);
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);Trimmed from the full walkthrough in Linux capabilities: what the five sets actually do.
BSD equivalent
FreeBSD: no POSIX.1e-style process capability sets; Capsicum (cap_enter(2), cap_rights_limit(2)) restricts per-fd rights instead. OpenBSD: none; pledge(2).
The long version, from the console
Sources
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
