A Landlock ruleset does not implicitly deny every operation known to the running kernel. It first declares which access rights it handles. Once the ruleset is enforced, those handled actions are denied by default unless a matching rule grants them.
That explicit boundary is central to Landlock compatibility. User space can restrict rights it knows and has tested while a newer kernel may expose additional rights that an older binary never named.
Handled rights select the restricted action set
landlock_create_ruleset() accepts a landlock_ruleset_attr whose access masks define the actions controlled by the new ruleset.
struct landlock_ruleset_attr attr = {
.handled_access_fs =
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_WRITE_FILE,
};After this ruleset is enforced, these filesystem actions enter Landlock’s deny-by-default decision. Rights omitted from handled_access_fs are generally outside this ruleset’s restriction boundary.
LANDLOCK_ACCESS_FS_REFER has a historical exception: it is denied by default by a ruleset even when omitted from the handled mask, although granting it still requires explicitly handling it.
Rules grant subsets beneath objects
A filesystem rule can grant handled rights beneath a directory represented by an O_PATH descriptor.
struct landlock_path_beneath_attr path = {
.parent_fd = dirfd,
.allowed_access =
LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR,
};
landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path, 0);The rule’s allowed rights must be a subset of the rights handled by the ruleset. In this example, reads can be granted beneath the selected hierarchy while LANDLOCK_ACCESS_FS_WRITE_FILE remains denied there.
The model is additive restriction. Landlock cannot grant access rejected by ordinary DAC permissions or another active LSM. Its rules add constraints to the system’s existing access controls.
Enforcement creates a domain for the caller
landlock_restrict_self() enforces a completed ruleset on the calling thread. Future children inherit the resulting Landlock domain, so restrictions follow process creation rather than requiring every descendant to rebuild the ruleset.
Unprivileged processes can restrict themselves. The interface is designed around removing ambient authority rather than granting new privilege.
Rulesets can also stack. A later layer adds restrictions; it cannot loosen constraints inherited from earlier layers. The kernel currently limits the number of stacked ruleset layers, making repeated sandbox construction a finite resource rather than an unlimited operation.
ABI negotiation bounds the rights a binary can request
Landlock evolves by adding access rights and rule capabilities across ABI versions. A process can query the highest supported ABI with:
int abi = landlock_create_ruleset(
NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);A binary should only place rights supported by that ABI into its handled masks. Passing unknown access bits can fail ruleset creation with EINVAL.
This negotiation preserves a useful asymmetry. A newer kernel can expose controls that an older program does not use, while the program can still enforce the subset corresponding to the detected ABI. The resulting sandbox is therefore defined by both the program’s requested rights and the running kernel’s supported Landlock ABI.
Open descriptors cross the filesystem boundary differently
Filesystem Landlock checks are attached to specific operations, and descriptors opened before sandboxing are not retroactively converted into newly opened files. Existing descriptors can therefore retain capabilities established before the domain was entered.
This matters for process design. Restricting pathname-based access after opening broad directory or file descriptors does not erase the authority already represented by those descriptors. Landlock narrows future access according to its hooks; it is not a descriptor revocation mechanism.
The same distinction appears in newer rights such as LANDLOCK_ACCESS_FS_IOCTL_DEV, whose restrictions apply to newly opened device files rather than rewriting the status of pre-existing descriptors.
Filesystem coverage is explicit rather than universal
Landlock exposes named filesystem rights such as execute, read, write, truncate, directory removal, file removal, creation operations, and cross-directory refer operations. The set is not equivalent to every filesystem-related syscall.
Operations including some metadata and process-directory actions remain outside current Landlock filesystem controls. A sandbox that requires restrictions beyond Landlock’s available rights must combine it with other kernel mechanisms rather than infer coverage from pathname involvement alone.
This is another consequence of handled-right design: the security boundary is the documented set of kernel actions represented by supported Landlock rights, not an abstract promise that every operation touching a path is confined.
Deny-by-default applies only inside the declared boundary
Landlock’s ruleset construction separates two decisions. The handled masks declare which actions become restricted, and individual rules declare where subsets of those actions are allowed. Enforcement then turns that ruleset into a domain inherited by descendants.
The result is a sandbox that can be installed without privilege and stacked with existing security controls. Its precision comes from explicit scope: handled rights are denied unless granted, unhandled rights are not silently claimed as covered, inherited layers only add constraints, and existing descriptors retain authority that was established before enforcement.