Skip to content
LinuxDeep Dive Published Updated 3 min readViews unavailable

Landlock on Linux: Unprivileged Filesystem Sandboxing with Backward-Compatible Rulesets

A version-aware explanation of Linux Landlock rulesets, handled rights, parent-directory policy, process inheritance, probing, and safe fallback behavior.

Landlock is a stackable Linux Security Module that lets a process restrict its future access to kernel objects, especially file-system hierarchies, without requiring global administrative policy. It is designed for application self-sandboxing: after opening the resources needed to define policy, a process creates a ruleset, adds allowed hierarchy roots, and restricts itself and its descendants.

“Handled” rights define the deny universe

A ruleset declares which access rights it handles. Once enforcement begins, handled operations are denied unless a rule grants them. Rights that the running kernel or ruleset does not handle remain governed by ordinary DAC, capabilities, and other LSMs. This distinction is essential: omitting a right from handled_access_fs does not mean “deny it”; it means Landlock is not making that decision.

The available ABI and rights have grown over kernel releases. Query the supported Landlock ABI at runtime and build the handled mask from rights supported by that ABI. Passing newer flags blindly can fail policy creation; silently removing all unsupported rights can also reduce protection below the application’s minimum.

int abi = landlock_create_ruleset(NULL, 0,
    LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0) {
    /* Distinguish unsupported kernel from an unexpected failure. */
}

Use the official kernel headers or compatibility definitions as documented by the Landlock guide. A production wrapper should log the negotiated ABI and exact effective rights so operators can distinguish “sandbox active” from “binary started on an unsupported kernel.”

Hierarchy rules have directory semantics

Rules grant a subset of handled rights beneath a file or directory descriptor. Open policy roots with a path-only descriptor, add them to the ruleset, and close the descriptors after rules are installed. Grant read/execute to immutable runtime trees and narrower write/remove/create rights only to the application’s data directory.

Operations that modify directory entries may require rights on the relevant parent directories. Renames and links crossing hierarchy boundaries are deliberately constrained; granting access to the source file alone is not equivalent to granting namespace mutation. Build tests for create, rename, link, remove, and replacement, not only open().

Already-open descriptors retain authority that was obtained before restriction. Close unintended descriptors and avoid opening a broad directory solely to create a narrower rule. Landlock limits future kernel access; it cannot revoke bytes already mapped into memory or secrets already read.

Restriction is inherited and composes

Before calling landlock_restrict_self(), an unprivileged process sets no_new_privs. Threads should coordinate so policy is installed before untrusted work begins. Children inherit restrictions, and additional Landlock layers can only reduce effective access. This makes it possible for a launcher to set an outer boundary and a component to narrow itself further.

A secure fallback depends on the application. If Landlock is a promised security boundary, an unavailable ABI or failed rule must stop execution. If it is defense in depth for a historically unrestricted desktop tool, the program may continue only with an explicit, observable policy and without claiming confinement. Never interpret ENOSYS, EOPNOTSUPP, or an empty handled mask as success.

Test the negative space

Create a matrix per supported ABI: allowed read, denied read, allowed output creation, denied sibling creation, rename within a tree, rename across trees, symlink traversal, inherited child behavior, and access through pre-opened descriptors. Combine it with seccomp, namespaces, and privilege dropping, because Landlock is not a network, process, or syscall sandbox by itself.

Landlock’s backward-compatible interface is valuable precisely because applications can probe and adapt. The safe adaptation is measurable negotiation against a documented minimum—not a catch-all retry that starts the program with less policy than its user expects.

Related:

Sources:

Comments