Skip to main content
  1. Index/

seccomp (Secure Computing Mode)

seccomp (Secure Computing Mode) is a Linux kernel facility, activated by the seccomp(2) syscall, that restricts which system calls a process may subsequently invoke. In its original SECCOMP_SET_MODE_STRICT form (2005) it was a blunt instrument: the process could call only read, write, _exit, and sigreturn. The operationally useful form is SECCOMP_SET_MODE_FILTER, introduced in kernel 3.5 (2012), which accepts a BPF (classic BPF, predating eBPF) filter program that receives each syscall’s number and arguments and returns one of several verdicts: ALLOW (continue normally), ERRNO (return a specified error to the process), KILL_PROCESS or KILL_THREAD (terminate immediately without giving the process a chance to handle signals), TRAP (deliver SIGSYS), or TRACE (notify a ptracer). Once installed, a seccomp filter cannot be removed, and child processes created by fork() or threads created by clone() inherit it. Filters may only add restrictions, never loosen them — so a chain of filters is the intersection of all their allowlists. The filter runs entirely in the kernel, in BPF bytecode verified for safety, before the syscall implementation is entered, making it extremely low-overhead relative to the security it provides.

A seccomp profile in practice is a list of permitted syscalls (an allowlist) rather than a denylist, because the Linux syscall surface is large and new dangerous syscalls are added with kernel releases. Container runtimes generate and apply seccomp profiles automatically: containerd, CRI-O, and Docker all ship a default seccomp profile — a curated allowlist of roughly 300 syscalls sufficient for the vast majority of containerised workloads — which blocks a targeted set of dangerous calls including kexec_load, ptrace, mount, unshare, setns, perf_event_open, bpf, userfaultfd, and the full set of privileged clock operations. Kubernetes 1.27+ enables RuntimeDefault seccomp by default in the Restricted PSA profile. Custom profiles are specified in the pod spec via securityContext.seccompProfile.type: Localhost with a node-local profile path, or distributed across nodes via the Security Profiles Operator (SPO), which manages seccomp (and AppArmor) profiles as Kubernetes CRDs and syncs them to nodes. The SPO can also run in recording mode: it attaches a BPF program to the pod’s syscall path, records every syscall the workload actually makes, and synthesises a minimal allowlist profile, dramatically reducing the effort of profile authoring for existing applications.

seccomp is complementary to and layered with the other Linux isolation mechanisms in this glossary. Namespaces restrict what a process can see; cgroups restrict what it can consume; LSM (AppArmor, SELinux) restricts what it can access based on MAC policy; seccomp restricts which kernel operations it can invoke at all — each layer addresses a different dimension of the attack surface. The interaction between seccomp and LSM is precisely ordered: seccomp runs before LSM hooks, so a syscall blocked by seccomp never reaches the LSM check. eBPF programs loaded via bpf(2) are themselves subject to the seccomp filter of the loading process — the default container seccomp profile blocks bpf() for this reason. In the context of Kata Containers and KubeVirt, seccomp is applied to the QEMU or virt-launcher host process, constraining the hypervisor’s own syscall surface to limit the damage from a QEMU vulnerability, independently of whatever seccomp profile the workload inside the VM uses.

Related

AppArmor (Application Armor)

AppArmor (Application Armor) is a Mandatory Access Control (MAC) system implemented as a major LSM (Linux Security Module), developed originally by Immunix and now maintained by Canonical. It is the default MAC system on Ubuntu, Debian, and their derivatives, and the default container confinement mechanism for containerd and Docker on those distributions. Where SELinux assigns security labels to every object on the system and enforces policy based on label interactions, AppArmor takes a fundamentally different approach: it confines programs by filesystem path. A profile for nginx lists the specific file paths that nginx is allowed to read, write, and execute, the network operations it may perform, and the Linux capabilities it may use — anything not listed is denied. No relabelling of the filesystem is required and no extended attributes are set: AppArmor’s confinement decisions are made purely from the path of the file being accessed and the identity of the confined process. This path-based model makes AppArmor profiles far simpler to read, write, and audit than SELinux policy, and eliminates the mislabelled-file failure mode that is the most common SELinux operational problem.

SELinux (Security-Enhanced Linux)

SELinux (Security-Enhanced Linux) is a Mandatory Access Control (MAC) implementation developed by the NSA and released as open source in 2000, merged into the mainline Linux kernel in 2.6 via the LSM framework in 2003. Its defining characteristic is default deny: unlike the standard Linux Discretionary Access Control model (file permission bits), where anything not explicitly forbidden is permitted, SELinux refuses all access that is not explicitly allowed by policy. Every process and every object — every file, socket, pipe, device node, and IPC object — carries a security context (also called a label) of the form user:role:type:level. The policy is a compiled set of rules, loaded at boot, that defines precisely which combinations of process context and object context may interact and how. An Apache web server process running in the httpd_t domain can read files labelled httpd_sys_content_t but is denied access to files labelled user_home_t or shadow_t, regardless of what Unix file permission bits say. If the web server is compromised, the attacker is confined to what httpd_t permits — typically a narrow, well-defined set of files and network operations — rather than having the full access of the user account running Apache.

Syscall (System Call)

A system call (syscall) is the formal interface through which a user-space process asks the kernel to perform a privileged operation on its behalf — opening a file, allocating memory, creating a process, establishing a network connection, sending a signal, or any other action that requires kernel mediation. User-space code runs at CPU privilege level 3 (ring 3) and cannot directly access hardware, manipulate kernel data structures, or perform I/O; the kernel runs at ring 0 with unrestricted access. A syscall is the crossing point: the process places its request in a defined register convention and issues a syscall instruction (on x86-64) that atomically switches the CPU to ring 0 and transfers control to the kernel’s syscall dispatch table. The kernel validates the request, performs the operation if permitted by standard Unix permissions and any active LSM hooks, and returns the result. From a security perspective, the syscall boundary is the complete list of what a process can ask the kernel to do — and therefore the complete list of operations that security controls like seccomp and BPF LSM can police.