The Linux Security Modules (LSM) framework is the kernel’s infrastructure for pluggable mandatory access control. It was incorporated into the mainline kernel in December 2003, evolving from a joint effort between several security projects — including SELinux, Immunix, SGI, and Janus — in response to a challenge from Linus Torvalds to provide a general-purpose security hook mechanism. By itself LSM adds no restrictions; it provides the substrate on which individual security modules register policy.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DeelerDev/linux/llms.txt
Use this file to discover all available pages before exploring further.
How the LSM framework works
LSM inserts hook calls at security-relevant points throughout the kernel: before a file is opened, before a socket is created, when a process’s credentials change, when an IPC object is accessed, and hundreds of other operations. Each hook call passes relevant context to registered modules, which return a decision (allow or deny) based on their own policy.Hook-based architecture
Hooks are maintained in lists — one list per hook type. When the kernel reaches a hook point, it calls every registered handler for that hook in the order specified byCONFIG_LSM. The operation is denied if any handler returns a non-zero error code.
void * fields in structures like struct task_struct, struct cred, struct inode, struct file, struct super_block, struct sk_buff, and struct kern_ipc_perm. Each LSM manages its own blob layout.
Security hook list registration
An LSM registers its hooks at init time by callingsecurity_add_hooks() with a struct security_hook_list array:
struct lsm_id struct identifies the module by name and a numeric ID from uapi/linux/lsm.h. Hook registration is permanent — once registered, hooks cannot be removed (with the limited deprecated exception of SELinux’s self-removal path, which is no longer supported).
Hook stacking
When multiple LSMs are active, each hook is called in sequence. The capabilities module always runs first. Minor LSMs (Yama, Lockdown) run next, followed by the major MAC module (SELinux, AppArmor, Smack, or TOMOYO). Landlock and BPF LSM can stack alongside a major LSM. The active LSM stack is readable at runtime:The LSM framework requires
CONFIG_SECURITY=y. The capabilities module (security/commoncap.c) is always compiled in and always runs first regardless of other configuration.Enabling LSMs at boot
LSMs are selected at build time and optionally overridden at boot with thelsm= kernel command line parameter. The parameter accepts a comma-separated ordered list:
CONFIG_DEFAULT_SECURITY and CONFIG_LSM build options set the compiled-in default order. To check what the running kernel was built with:
Available LSMs
SELinux — policy-based mandatory access control
SELinux — policy-based mandatory access control
SELinux was originally developed by the NSA and is the reference implementation of mandatory access control in Linux. Every subject (process) and object (file, socket, IPC object) receives a security label called a security context, for example The SELinux policy is typically stored in
system_u:system_r:httpd_t:s0. A policy database — compiled from human-readable policy source — defines which context pairs are allowed to interact for each operation class.SELinux operates in two modes:- Enforcing — policy violations are denied and logged.
- Permissive — policy violations are logged but allowed. Useful for developing or debugging policy.
/etc/selinux/ and loaded by the init system. On RHEL-family systems, the semanage, audit2allow, and restorecon tools are the primary policy management interfaces.AppArmor — path-based confinement
AppArmor — path-based confinement
AppArmor confines programs using per-application profiles that specify which filesystem paths, capabilities, and network operations a program may use. Profiles are simpler to write than SELinux policy because they operate on file paths rather than labels.Check loaded profiles and their modes:A profile can be in one of three modes:AppArmor is the default MAC module on Ubuntu and Debian. The
- enforce — violations are denied and logged.
- complain — violations are logged but allowed. Used for developing profiles.
- disabled — the profile is loaded but not enforced.
/etc/apparmor.d/. Load or reload a profile:aa-genprof and aa-logprof tools help generate profiles from audit logs.Smack — label-based access control
Smack — label-based access control
Smack (Simplified Mandatory Access Control Kernel) assigns short ASCII labels to processes and filesystem objects. A rule table controls which subject labels may read, write, or execute objects with a given label. Smack is used in embedded Linux environments, including Tizen.Labels are stored as extended attributes (
security.SMACK64) on filesystem objects. The active label for a process can be read from /proc/self/attr/smack/current.TOMOYO — pathname learning mode
TOMOYO — pathname learning mode
TOMOYO is a pathname-based MAC system with a distinctive learning mode: it can operate in a training mode that records all access attempts, then enforce only the recorded set. This makes it practical for environments where writing policy by hand is not feasible.Domains in TOMOYO correspond to program execution paths (the sequence of
execve() calls that led to a process). Policy is stored in /etc/tomoyo/.Landlock — unprivileged sandboxing
Landlock — unprivileged sandboxing
Landlock allows any process — including unprivileged ones — to voluntarily restrict its own access to filesystem paths and TCP ports by constructing a ruleset and enforcing it. Unlike other LSMs, Landlock policy is expressed entirely in user space without requiring any kernel policy files.Landlock stacks on top of other LSMs — a Landlock ruleset can only add restrictions, never remove restrictions imposed by DAC or other LSMs.See Landlock usage below.
BPF LSM — runtime-programmable policy
BPF LSM — runtime-programmable policy
BPF LSM (
CONFIG_BPF_LSM) allows eBPF programs to be attached to LSM hook points. This makes it possible to implement and update security policy at runtime without a kernel recompile or reboot. The bpf() syscall with BPF_PROG_TYPE_LSM is used to load hook programs.BPF LSM programs must be loaded by a process with CAP_BPF and CAP_PERFMON or CAP_SYS_ADMIN.Using SELinux
Enable SELinux by adding it to thelsm= boot parameter and ensuring CONFIG_SECURITY_SELINUX=y is set. On most distributions, the init system loads the compiled policy automatically.
The /sys/fs/selinux/ pseudo-filesystem exposes the SELinux policy interface. Process labels are readable from /proc/<pid>/attr/current.
Using AppArmor
AppArmor profiles are plain text files. A minimal profile that confines a hypothetical daemon to read from/etc/myapp/ and write to /var/log/myapp/:
Landlock user-space sandboxing
Landlock lets a process sandbox itself before handling untrusted input. The API involves three steps: create a ruleset, add rules to it, then enforce it withlandlock_restrict_self().
landlock_restrict_self(), the calling thread and all its descendants are subject to the ruleset. The restriction is additive: subsequent landlock_restrict_self() calls can only tighten the policy, never relax it.
Writing a custom LSM
New LSMs are accepted into the kernel when their intent — what they protect against and when a user would choose them — is documented inDocumentation/admin-guide/LSM/. This allows LSM code to be audited against its stated goals.
To write a custom LSM:
Define an lsm_id
Declare a
struct lsm_id with a unique name and an ID from uapi/linux/lsm.h. The name must be approved by LSM maintainers for in-tree modules.Implement hook functions
Write functions matching the hook signatures defined in
security/security.c. Return 0 to allow an operation or a negative errno to deny it.Register hooks
Use
LSM_HOOK_INIT() to build the hook list and call security_add_hooks() from your init function.Security architecture overview
DAC, capabilities, namespaces, and the full security layer stack.
Kernel hardening
KASLR, stack canaries, SMEP/SMAP, and Kconfig hardening options.
