landlock_restrict_self(2)
โจ landlock_restrict_self โ enforce a Landlock ruleset โจ
hiii bestie ๐ซถ welcome to the System Calls Manual, aka the syscall girlies' section of the man pages. This one's about landlock_restrict_self, and honestly? she's giving final boss of sandboxing energy. Let's get into it ๐
๐ NAME ๐
landlock_restrict_self โ enforce a Landlock ruleset. That's the whole job, and she ate.
๐ LIBRARY ๐
Standard C library (libc, -lc). Yes queen, it's right there in libc.
๐ SYNOPSIS ๐
#include <linux/landlock.h> /* Definition of LANDLOCK_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
int syscall(SYS_landlock_restrict_self, int ruleset_fd,
uint32_t flags);
๐ฆ DESCRIPTION ๐ฆ
okay so picture this: you've got a Landlock ruleset, and you've loaded it up with all the rules you want. Once it's populated, calling landlock_restrict_self() is the moment of truth โ it enforces that ruleset on the calling thread. If you want the big-picture lore, go read landlock(7) for a global overview. ๐
A thread can be restricted with multiple rulesets, and those rulesets get composed together to form the thread's Landlock domain. Think of it like a stack of rulesets, but it's implemented in a way more efficient way than literally stacking them (efficiency slay ๐ ). Here's the thing though: a domain can only be updated in a way where the constraints of every past and future composed ruleset will restrict the thread and its future children for their entire life. So you can gradually enforce tailored access control policies with multiple independent rulesets coming from different sources โ for example, init system configuration, user session policy, or built-in application policy. Cute, right?
But lowkey โ most applications should only need ONE call tolandlock_restrict_self(). They should avoid arbitrary numbers of such calls because of the composed rulesets limit. Instead, developers are encouraged to build a single tailored ruleset with multiple calls tolandlock_add_rule(2). Periodt.
So, to actually enforce a ruleset, one of these has to be true:
- the caller must have the
CAP_SYS_ADMINcapability in its user namespace, or - the thread must already have the
no_new_privsbit set.
Same vibe as seccomp(2), and the reason is that this avoids scenarios where unprivileged processes can affect the behavior of privileged children โ like, say, because of set-user-ID binaries. ๐ If that bit was not already set by an ancestor of this thread, the thread has to make the following call:
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ruleset_fd is a Landlock ruleset file descriptor you got from landlock_create_ruleset(2) and fully populated with a set of calls to landlock_add_rule(2). No skipping steps, bestie.
By default, denied accesses originating from programs that sandbox themselves are logged via the audit subsystem. Those events typically mean something unexpected happened โ bugs or exploitation attempts, yikes. But to avoid excessive logging, access requests denied by a domain that was not created by the originating program are not logged by default. The rationale there is that programs should know their own behavior, but not necessarily the behavior of other programs. That default configuration is suitable for most programs that sandbox themselves. For specific use cases though, the following flags let programs modify this default logging behavior โจ
The LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF and LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON flags apply to the newly created Landlock domain.
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF(since Landlock ABI version 7) โ Disables logging of denied accesses originating from the thread creating the Landlock domain, plus its children, as long as they keep running the same executable code (i.e., without an interveningexecve(2)call). This is intended for programs that execute unknown code without invokingexecve(2), like script interpreters. Programs that only sandbox themselves should not set this flag, so users can still be notified of unauthorized access attempts via system logs. ๐LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON(since Landlock ABI version 7) โ Enables logging of denied accesses after anexecve(2)call, giving you visibility into unauthorized access attempts by newly executed programs inside the Landlock domain you created. This flag is recommended only when all potential executables in the domain are expected to comply with the access restrictions, because excessive audit log entries could make it harder to spot the critical events. ๐ญLANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF(since Landlock ABI version 7) โ Disables logging of denied accesses originating from nested Landlock domains created by the caller or its descendants. Set this one according to runtime configuration, not hardcoded, to avoid suppressing important security events. It's useful for container runtimes or sandboxing tools that may launch programs which themselves create Landlock domains and could otherwise generate excessive logs. UnlikeLANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF, this flag only affects future nested domains, not the one being created. Bonus: it can also be used with aruleset_fdvalue of-1to mute subdomain logs without creating a domain. ๐คซ
And the following flag supports policy enforcement in multithreaded processes:
LANDLOCK_RESTRICT_SELF_TSYNC(since Landlock ABI version 8) โ Applies the new Landlock configuration atomically to all threads of the current process, including the Landlock domain and logging configuration. This overrides the Landlock configuration of sibling threads, irrespective of previously established Landlock domains and logging configurations on those threads. Also: if the calling thread is running withno_new_privs, this operation enablesno_new_privson the sibling threads as well. Group chat, but make it security policy. ๐
๐ RETURN VALUE ๐
On success, landlock_restrict_self() returns 0. On error, -1 is returned and errno is set to indicate the error. Simple! We love a clean return value.
๐ ERRORS ๐
landlock_restrict_self() can fail for the following reasons:
E2BIGโ The maximum number of composed rulesets is reached for the calling thread. This limit is currently64.EBADFโruleset_fdis not a file descriptor for the current thread.EBADFDโruleset_fdis not a ruleset file descriptor.EINVALโ Invalid value inflags.EOPNOTSUPPโ Landlock is supported by the kernel but disabled at boot time.EPERMโruleset_fdhas no read access to the underlying ruleset, or the calling thread is not running withno_new_privs, or it doesn't haveCAP_SYS_ADMINin its user namespace.
๐ STANDARDS ๐
Linux. ๐ง She's a Linux girlie, that's the standard.
๐ฐ๏ธ HISTORY ๐ฐ๏ธ
Linux 5.13. So she's been iconic since 5.13.
๐งช EXAMPLES ๐งช
See landlock(7). (Yes bestie, go read it, it's the whole vibe.)
๐ SEE ALSO ๐
and that's the page, bestie ๐ one last thing for the credits scroll: this was brought to you by Linux man-pages 6.20, dated 2026-05-04, for landlock_restrict_self(2). no cap, go sandbox something responsibly ๐โจ๐ธ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 2017-2020, Mickaรซl Salaรผn <mic@digikod.net>
- Copyright 2019-2020, ANSSI
- Copyright 2021, Microsoft Corp
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms