landlock_create_ruleset(2)
Create a Landlock ruleset fd, step one of unprivileged filesystem/network sandboxing.
- Since
- Linux 5.13check your kernel →
- glibc
- none (use syscall(2))
- System
- Linux
- Man page
- landlock_create_ruleset(2)
Synopsis
#include <linux/landlock.h>
#include <sys/syscall.h>
#include <unistd.h>
int syscall(SYS_landlock_create_ruleset,
const struct landlock_ruleset_attr *attr,
size_t size, uint32_t flags);Rod's take
Before Landlock, path-based sandboxing on Linux meant root, a MAC policy some other team wrote, or chroot pretending to be security. Now an unprivileged process builds a ruleset, adds paths, and locks itself in for good. The trap: a right you leave out of handled_access_fs isn't restricted at all, so a hardcoded ABI-1 mask on a newer kernel leaves truncate wide open and never says a word. Ask for the ABI version, handle everything the kernel knows, grant back what you need. unveil does it in four lines. Landlock still got the architecture right.
Flags and arguments that matter
| Name | What it does |
|---|---|
| LANDLOCK_CREATE_RULESET_VERSION | With attr NULL and size 0, return the highest supported Landlock ABI version (starting at 1). |
| LANDLOCK_CREATE_RULESET_ERRATA | With attr NULL and size 0, return a bitmask of Landlock errata fixed in the running kernel. |
| handled_access_fs | Filesystem rights this ruleset handles. Rights not listed here are not restricted at all. |
| handled_access_net | Network rights (TCP bind/connect) this ruleset handles. |
| scoped | Scope flags restricting IPC (abstract UNIX sockets, signals) outside the Landlock domain. |
| LANDLOCK_ACCESS_FS_REFER | Cross-directory rename/link right; always denied by default, even if not set in handled_access_fs. |
Errors you will actually hit
| errno | Meaning |
|---|---|
| EOPNOTSUPP | Landlock is supported by the kernel but disabled at boot. |
| EINVAL | Unknown flags, access right, or scope, or size too small. |
| ENOMSG | attr specifies no access rights to restrict. |
| E2BIG | size is too big. |
| EFAULT | attr is not a valid address. |
Example
int abi = syscall(SYS_landlock_create_ruleset, NULL, 0,
LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0)
err(1, "landlock unavailable"); /* ENOSYS or EOPNOTSUPP */
struct landlock_ruleset_attr attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_WRITE_FILE,
};
int rfd = syscall(SYS_landlock_create_ruleset, &attr, sizeof(attr), 0);
if (rfd < 0)
err(1, "landlock_create_ruleset");
/* landlock_add_rule(2), PR_SET_NO_NEW_PRIVS, landlock_restrict_self(2) */Trimmed from the full walkthrough in landlock: sandbox your process without root.
BSD equivalent
OpenBSD: unveil(2) (OpenBSD 6.4). FreeBSD: Capsicum capability mode via cap_enter(2).
The long version, from the console
Sources
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
