Linux Security Modules

Standard Linux permissions (rwx bits, capabilities) are discretionary — the file owner decides who can access files. LSM (Linux Security Modules) adds mandatory access control: a policy administrator defines rules that override even root. SELinux and AppArmor are the two major LSM implementations.

DAC vs MAC — Two Security Models

DAC (Discretionary)MAC (Mandatory)
Who sets policyFile ownerSystem administrator / policy
Can root bypass?Yes — root ignores DACNo — MAC applies to root too
Exampleschmod, chown, file permissionsSELinux, AppArmor
GranularityUser/group/other, capabilitiesPer-process, per-file, per-operation
Default behaviorAllow unless deniedDeny unless explicitly allowed

How LSM Hooks Work

How does SELinux intercept operations without modifying every system call? LSM defines ~200 hook points in the kernel — one for every security-sensitive operation. "Check before opening this file." "Check before sending this signal." "Check before creating this socket." Each hook calls LSM's security_* function. The active LSM (SELinux or AppArmor) implements these functions. If the LSM denies the operation, it returns -EACCES and the operation fails — even for root.
LSM hook example (simplified kernel code): int vfs_open(const struct path *path, struct file *file) { /* ... normal VFS checks ... */ error = security_file_open(file); // LSM hook if (error) return error; // denied by SELinux/AppArmor /* ... proceed with open ... */ } # Active LSM: cat /sys/kernel/security/lsm # lockdown,yama,apparmor (Ubuntu default) # selinux (RHEL/Fedora default) # Multiple LSMs can stack: # lockdown = prevents root from modifying running kernel # yama = restricts ptrace (parent can only trace children) # apparmor = MAC profiles per process

LSM Stacking

# Modern kernels support stacking multiple LSMs # Order matters: each LSM is consulted, all must allow # Typical Ubuntu stack: # 1. lockdown - prevents kexec, /dev/mem access, etc. # 2. yama - ptrace scope restriction # 3. apparmor - per-profile file/network/cap rules # Typical RHEL stack: # 1. lockdown # 2. yama # 3. selinux # View what's loaded: cat /sys/kernel/security/lsm # Check if SELinux is enforcing: getenforce # Enforcing / Permissive / Disabled # Check AppArmor status: aa-status

Lockdown LSM

What does the lockdown LSM protect against? Lockdown prevents even root from tampering with the running kernel — loading unsigned modules, accessing physical memory via /dev/mem, or bypassing Secure Boot. It has two levels: "integrity" (prevent kernel modification) and "confidentiality" (also prevent kernel memory reads). Enabled automatically when Secure Boot is active.
# Check lockdown level: cat /sys/kernel/security/lockdown # [none] integrity confidentiality # Lockdown prevents: # - kexec_load() when set to integrity # - /dev/mem and /dev/kmem access # - Loading unsigned kernel modules # - Hibernation (could bypass integrity checks) # - PCI BAR access from userspace