The landlock LSM: Unprivileged Sandboxing Without a Container

2026-07-21

Every sandbox you've used — Docker, Firejail, bubblewrap — needs privileges. seccomp-bpf can block syscalls but knows nothing about filesystem semantics: it can't say "no writes to /home". SELinux and AppArmor need root to load policy. Landlock, merged in Linux 5.13 (2021) and extended through 6.10, is the LSM that lets an unprivileged process shrink its own filesystem and network access, permanently, for itself and its children.

The model is restrict-only. A process creates a ruleset describing what it wants to allow, then calls landlock_restrict_self(). Anything not explicitly allowed inside the ruleset's handled access classes is denied. Rules are additive across nested rulesets (you can only lose access, never gain it), which is why no privilege is needed — like PR_SET_NO_NEW_PRIVS, which landlock requires.

Three syscalls, all added in 5.13:

Concrete example. A PDF renderer that should read fonts from /usr/share/fonts, read/write its temp dir, and touch nothing else. You open both directories with O_PATH, add two PATH_BENEATH rules — read-only for fonts, read/write for tempdir — and call landlock_restrict_self. Now open("/etc/shadow", O_RDONLY) returns EACCES. No container, no root, no ptrace tricks. The kernel checks paths against the ruleset on every path_walk.

Rule of thumb for ABI versions. Landlock evolves via a monotonic ABI number: query it with landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION). v1 (5.13) = filesystem read/write/exec. v2 (5.19) = refer/rename across mounts. v3 (6.2) = truncate. v4 (6.7) = TCP bind/connect restrictions. v5 (6.10) = ioctl on device files. Always mask your handled_access_fs with what the running kernel supports, or the ruleset creation fails on older kernels.

The cost is negligible: rules live in a trie keyed by inode, and lookups happen alongside the LSM hook the VFS was already calling. The catch: it operates on inodes at rule-add time, so if you allow /tmp/work and someone renames /tmp/work away, your rule follows the inode, not the path.

See it in action: Check out Landlock Workshop: Sandboxing Application for Fun and Protection - Mickaël Salaün, Microsoft by The Linux Foundation to see this theory applied.
Key Takeaway: Landlock lets any process build a filesystem/network jail around itself with three syscalls and zero privileges — the sandbox is monotonic, per-thread, inherited by children, and enforced by the VFS on every path lookup.

All newsletters