landlock_add_rule(2)

πŸ’– landlock_add_rule(2) β€” the System Calls Manual glow-up πŸ’–

okay bestie, so this is the page for landlock_add_rule from the Linux System Calls Manual, and it's about adding a brand new Landlock rule to a ruleset you already made. yes it's a syscall, yes it's giving main character energy, no you cannot skip the details, let's go πŸ¦‹


✨ NAME ✨

landlock_add_rule β€” add a new Landlock rule to a ruleset

πŸ“š LIBRARY πŸ“š

Standard C library (libc, -lc)

πŸŽ€ SYNOPSIS πŸŽ€

#include <linux/landlock.h>  /* Definition of LANDLOCK_* constants */
#include <sys/syscall.h>     /* Definition of SYS_* constants */

int syscall(SYS_landlock_add_rule, int ruleset_fd,
            enum landlock_rule_type rule_type,
            const void *rule_attr, uint32_t flags);

like, that's the whole vibe right there πŸ‘‘

🌸 DESCRIPTION 🌸

So. A Landlock rule describes an action on an object that the process intends to perform. A whole set of rules gets aggregated into a ruleset, and that ruleset can then restrict the thread enforcing it, plus all its future children. found family, but make it sandboxing 🫢

The landlock_add_rule() system call adds a new Landlock rule to an existing ruleset. For the big-picture overview, go read landlock(7). Literally go read it, iykyk.

ruleset_fd is a Landlock ruleset file descriptor that you got from landlock_create_ruleset(2).

rule_type tells you which structure type rule_attr is pointing at. Currently, Linux supports these rule_type values:

LANDLOCK_RULE_PATH_BENEATH

For these rules, the object is a file hierarchy, and the related filesystem actions are defined with filesystem access rights.

In this case, rule_attr points to the following structure:

struct landlock_path_beneath_attr {
    __u64 allowed_access;
    __s32 parent_fd;
} __attribute__((packed));
  • allowed_access holds a bitmask of allowed filesystem actions, and those can be applied on the given parent_fd (peep Filesystem actions in landlock(7)).
  • parent_fd is an opened file descriptor, preferably with the O_PATH flag, which identifies the parent directory of the file hierarchy β€” or just a file. no biggie.

LANDLOCK_RULE_NET_PORT (since Landlock ABI version 4)

For these rules, the object is a TCP port, and the related actions are defined with network access rights.

In this case, rule_attr points to the following structure:

struct landlock_net_port_attr {
    __u64 allowed_access;
    __u64 port;
};
  • allowed_access holds a bitmask of allowed network actions, which can be applied on the given port.
  • port is the network port in host endianness. yes, host. write it down.
⚠️ ok important: port 0 passed to bind(2) will bind to an available port from the ephemeral port range. That range can be configured in the /proc/sys/net/ipv4/ip_local_port_range sysctl (which is also used for IPv6, cute of it).

A Landlock rule with port 0 and the LANDLOCK_ACCESS_NET_BIND_TCP right means that requesting to bind on port 0 is allowed, and it will automatically translate to binding on the related port range. slay, automatic ✨


flags is a bit mask of the following optional flags:

  • LANDLOCK_ADD_RULE_QUIET (since Landlock ABI version 10) β€” together with the quiet_* fields in struct landlock_ruleset_attr, this flag controls whether Landlock will log audit messages when access to the objects covered by this rule is denied by this layer.

If logging is enabled, when Landlock denies an access, it will suppress the log if all of the following are true:

  • this layer is the innermost layer that denied the access;
  • all accesses denied by this layer are part of the quiet_* fields in the related struct landlock_ruleset_attr;
  • the object (or one of its parents, for filesystem rules) is marked as "quiet" via LANDLOCK_ADD_RULE_QUIET.

Because logging is only suppressed by a layer if the layer denies access, a sandboxed program cannot use this flag to "hide" access denials without denying itself the access in the first place. no sneaky business πŸ’…

The effect of this flag does not depend on the value of allowed_access in the passed-in rule_attr. When this flag is present, the caller is also allowed to pass in an empty allowed_access. fun.

🫢 RETURN VALUE 🫢

On success, landlock_add_rule() returns 0. On error, -1 is returned and errno is set to indicate the error. the classic.

πŸ’€ ERRORS πŸ’€

landlock_add_rule() can fail for the following reasons:

  • EAFNOSUPPORT β€” rule_type is LANDLOCK_RULE_NET_PORT, but TCP is not supported by the running kernel. the kernel said no 🚫
  • EBADF β€” ruleset_fd is not a file descriptor for the current thread, or a member of rule_attr is not a file descriptor as expected.
  • EBADFD β€” ruleset_fd is not a ruleset file descriptor, or a member of rule_attr is not the expected file descriptor type.
  • EFAULT β€” rule_attr was not a valid address.
  • EINVAL β€” flags is not valid.
  • EINVAL β€” The rule accesses are inconsistent (i.e., rule_attr->allowed_access is not a subset of the ruleset handled accesses).
  • EINVAL β€” In struct landlock_path_beneath_attr, the rule accesses are not applicable to the file (i.e., some access rights in rule_attr->allowed_access are only applicable to directories, but rule_attr->parent_fd does not refer to a directory).
  • EINVAL β€” In struct landlock_net_port_attr, the port number is greater than 65535.
  • EINVAL β€” LANDLOCK_ADD_RULE_QUIET is passed but the ruleset has no quiet access bits set for the corresponding rule type.
  • ENOMSG β€” Empty accesses (i.e., rule_attr->allowed_access is 0) and no flags.
  • EOPNOTSUPP β€” Landlock is supported by the kernel but disabled at boot time. 😭 so close
  • EPERM β€” ruleset_fd has no write access to the underlying ruleset.

🌈 STANDARDS 🌈

Linux.

πŸ‘‘ HISTORY πŸ‘‘

Linux 5.13.

🧚 EXAMPLES 🧚

See landlock(7). (yes really, that's the whole section, it's a vibe.)

⭐ SEE ALSO ⭐

landlock_create_ruleset(2), landlock_restrict_self(2), landlock(7)


and that's the whole page bestie, you ate πŸ’… this was Linux man-pages 6.20, dated 2026-09-11, for landlock_add_rule(2) β€” go forth and sandbox responsibly, ily, mwah πŸŽ€πŸ’–

πŸ“¦ 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
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms