From: "Günther Noack" <gnoack@google.com>
To: "Mickaël Salaün" <mic@digikod.net>
Cc: Christian Brauner <brauner@kernel.org>,
Paul Moore <paul@paul-moore.com>,
"Serge E . Hallyn" <serge@hallyn.com>,
Justin Suess <utilityemal77@gmail.com>,
Lennart Poettering <lennart@poettering.net>,
Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>,
Nicolas Bouchinet <nicolas.bouchinet@oss.cyber.gouv.fr>,
Shervin Oloumi <enlightened@google.com>,
Tingmao Wang <m@maowtm.org>,
kernel-team@cloudflare.com, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org
Subject: Re: [RFC PATCH v1 06/11] landlock: Enforce capability restrictions
Date: Fri, 8 May 2026 17:54:57 +0200 [thread overview]
Message-ID: <af4HUS2lRC2eUPnm@google.com> (raw)
In-Reply-To: <20260312100444.2609563-7-mic@digikod.net>
On Thu, Mar 12, 2026 at 11:04:39AM +0100, Mickaël Salaün wrote:
> Add Landlock enforcement for capability use via the LSM capable hook.
> This lets a sandboxed process restrict which Linux capabilities it can
> exercise, using LANDLOCK_PERM_CAPABILITY_USE and per-capability rules.
>
> The capable hook is purely restrictive: it runs after cap_capable()
> (LSM_ORDER_FIRST), so it can deny capabilities that commoncap would
> allow, but it can never grant capabilities that commoncap denied.
>
> Add hook_capable() that uses landlock_perm_is_denied() to perform a pure
> bitmask check: if the capability is not in the layer's allowed set, the
> check is denied. No domain ancestry bypass, no cross-namespace
> discriminant, just a flat per-layer allowed-caps bitmask, matching the
> same pattern used by LANDLOCK_PERM_NAMESPACE_ENTER.
>
> Adding the 41-bit capability bitfield to struct perm_rules brings it to
> 49 out of 64 bits used (41 caps + 8 namespace types, 15 bits padding),
> keeping struct layer_rights at 16 bytes (8 bytes perm_rules + 4 bytes
> access_masks + 4 bytes tail padding) and the layers[] array at 256 bytes
> maximum. The caps bitfield is placed first in struct perm_rules (before
> the ns bitfield) because capabilities use a direct BIT_ULL(cap) mapping
> that benefits from starting at bit 0 of the storage unit.
>
> Non-user namespace operations require both LANDLOCK_PERM_NAMESPACE_ENTER
> (type allowed) and LANDLOCK_PERM_CAPABILITY_USE (CAP_SYS_ADMIN allowed)
> when both permissions are handled. This follows naturally from the
> kernel calling capable(CAP_SYS_ADMIN) before namespace operations: both
> hooks fire independently and audit logs identify which permission was
> denied.
>
> The enforcement is purely at exercise time via the capable hook, not by
> modifying the credential's capability sets. Stripping denied
> capabilities would give processes an accurate capget(2) view of their
> usable capabilities, but no LSM other than commoncap modifies capability
> sets; Landlock follows this convention and restricts use without
> altering what the process holds. A sandboxed process inside a user
> namespace will see all capabilities via capget(2) but will receive
> -EPERM when attempting to use any denied capability.
>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Günther Noack <gnoack@google.com>
> Cc: Paul Moore <paul@paul-moore.com>
> Cc: Serge E. Hallyn <serge@hallyn.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> ---
> include/uapi/linux/landlock.h | 31 ++++++++
> security/landlock/Makefile | 1 +
> security/landlock/access.h | 15 +++-
> security/landlock/audit.c | 4 +
> security/landlock/audit.h | 1 +
> security/landlock/cap.c | 142 ++++++++++++++++++++++++++++++++++
> security/landlock/cap.h | 49 ++++++++++++
> security/landlock/cred.h | 3 +
> security/landlock/limits.h | 4 +-
> security/landlock/setup.c | 2 +
> security/landlock/syscalls.c | 58 +++++++++++++-
> 11 files changed, 302 insertions(+), 8 deletions(-)
> create mode 100644 security/landlock/cap.c
> create mode 100644 security/landlock/cap.h
>
> diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> index b76e656241df..0e73be459d47 100644
> --- a/include/uapi/linux/landlock.h
> +++ b/include/uapi/linux/landlock.h
> @@ -166,6 +166,11 @@ enum landlock_rule_type {
> * landlock_namespace_attr .
> */
> LANDLOCK_RULE_NAMESPACE,
> + /**
> + * @LANDLOCK_RULE_CAPABILITY: Type of a &struct
> + * landlock_capability_attr .
> + */
> + LANDLOCK_RULE_CAPABILITY,
> };
>
> /**
> @@ -237,6 +242,24 @@ struct landlock_namespace_attr {
> __u64 namespace_types;
> };
>
> +/**
> + * struct landlock_capability_attr - Capability definition
> + *
> + * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_CAPABILITY.
> + */
> +struct landlock_capability_attr {
> + /**
> + * @allowed_perm: Must be set to %LANDLOCK_PERM_CAPABILITY_USE.
> + */
> + __u64 allowed_perm;
> + /**
> + * @capabilities: Bitmask of capabilities (``1ULL << CAP_*``) that
> + * should be allowed for use under this rule. Bits above
> + * ``CAP_LAST_CAP`` are silently ignored for forward compatibility.
> + */
> + __u64 capabilities;
> +};
> +
> /**
> * DOC: fs_access
> *
> @@ -432,9 +455,17 @@ struct landlock_namespace_attr {
> * Landlock domain that handles this permission is denied from entering
> * namespace types that are not explicitly allowed by a
> * %LANDLOCK_RULE_NAMESPACE rule.
> + * - %LANDLOCK_PERM_CAPABILITY_USE: Restrict the use of specific Linux
> + * capabilities. A process in a Landlock domain that handles this
> + * permission is denied from exercising capabilities that are not
> + * explicitly allowed by a %LANDLOCK_RULE_CAPABILITY rule. This hook
> + * is purely restrictive: it can deny capabilities that the kernel
> + * would otherwise grant, but it can never grant capabilities that the
> + * kernel already denied.
> */
> /* clang-format off */
> #define LANDLOCK_PERM_NAMESPACE_ENTER (1ULL << 0)
> +#define LANDLOCK_PERM_CAPABILITY_USE (1ULL << 1)
> /* clang-format on */
>
> #endif /* _UAPI_LINUX_LANDLOCK_H */
> diff --git a/security/landlock/Makefile b/security/landlock/Makefile
> index 734aed4ac1bf..63311d556f93 100644
> --- a/security/landlock/Makefile
> +++ b/security/landlock/Makefile
> @@ -9,6 +9,7 @@ landlock-y := \
> task.o \
> fs.o \
> ns.o \
> + cap.o \
> tsync.o
>
> landlock-$(CONFIG_INET) += net.o
> diff --git a/security/landlock/access.h b/security/landlock/access.h
> index 9c67987a77ae..65227b3064db 100644
> --- a/security/landlock/access.h
> +++ b/security/landlock/access.h
> @@ -72,6 +72,13 @@ static_assert(sizeof(typeof_member(union access_masks_all, masks)) ==
> * a single 64-bit storage unit.
> */
> struct perm_rules {
> + /**
> + * @caps: Allowed capabilities. Each bit corresponds to a
> + * ``CAP_*`` value (e.g. ``CAP_NET_RAW`` = bit 13). Bits are
> + * stored directly (sequential mapping) and masked with
> + * ``CAP_VALID_MASK`` at rule-add time.
> + */
> + u64 caps : LANDLOCK_NUM_PERM_CAP;
> /**
> * @ns: Allowed namespace types. Each bit corresponds to a
> * sequential index assigned by the ``_LANDLOCK_NS_*`` enum
> @@ -93,10 +100,10 @@ static_assert(sizeof(struct perm_rules) == sizeof(u64));
> * landlock_ruleset.layers FAM.
> *
> * Unlike filesystem and network access rights, which are tracked per-object
> - * in red-black trees, namespace types use a flat bitmask because their
> - * keyspace is small and bounded (~8 namespace types). A single rule adds
> - * to the allowed set via bitwise OR; at enforcement time each layer is
> - * checked directly (no tree lookup needed).
> + * in red-black trees, namespace types and capabilities use flat bitmasks
> + * because their keyspaces are small and bounded (~8 namespace types, 41
> + * capabilities). A single rule adds to the allowed set via bitwise OR; at
> + * enforcement time each layer is checked directly (no tree lookup needed).
> */
> struct layer_rights {
> /**
> diff --git a/security/landlock/audit.c b/security/landlock/audit.c
> index 46a635893914..24b7800ec479 100644
> --- a/security/landlock/audit.c
> +++ b/security/landlock/audit.c
> @@ -82,6 +82,10 @@ get_blocker(const enum landlock_request_type type,
> case LANDLOCK_REQUEST_NAMESPACE:
> WARN_ON_ONCE(access_bit != -1);
> return "perm.namespace_enter";
> +
> + case LANDLOCK_REQUEST_CAPABILITY:
> + WARN_ON_ONCE(access_bit != -1);
> + return "perm.capability_use";
> }
>
> WARN_ON_ONCE(1);
> diff --git a/security/landlock/audit.h b/security/landlock/audit.h
> index e9e52fb628f5..fe5d701ea45d 100644
> --- a/security/landlock/audit.h
> +++ b/security/landlock/audit.h
> @@ -22,6 +22,7 @@ enum landlock_request_type {
> LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
> LANDLOCK_REQUEST_SCOPE_SIGNAL,
> LANDLOCK_REQUEST_NAMESPACE,
> + LANDLOCK_REQUEST_CAPABILITY,
> };
>
> /*
> diff --git a/security/landlock/cap.c b/security/landlock/cap.c
> new file mode 100644
> index 000000000000..536e579f63a9
> --- /dev/null
> +++ b/security/landlock/cap.c
> @@ -0,0 +1,142 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Landlock - Capability hooks
> + *
> + * Copyright © 2026 Cloudflare
> + */
> +
> +#include <linux/capability.h>
> +#include <linux/cred.h>
> +#include <linux/lsm_audit.h>
> +#include <linux/lsm_hooks.h>
> +#include <uapi/linux/landlock.h>
> +
> +#include "audit.h"
> +#include "cap.h"
> +#include "cred.h"
> +#include "limits.h"
> +#include "ruleset.h"
> +#include "setup.h"
> +
> +static const struct access_masks cap_perm = {
> + .perm = LANDLOCK_PERM_CAPABILITY_USE,
> +};
> +
> +/**
> + * hook_capable - Deny capability use for Landlock-sandboxed processes
> + *
> + * @cred: Credentials being checked.
> + * @ns: User namespace for the capability check.
> + * @cap: Capability number (CAP_*).
> + * @opts: Capability check options. CAP_OPT_NOAUDIT suppresses audit logging.
> + *
> + * Pure bitmask check: denies the capability if it is not in the layer's
> + * allowed set. This hook is purely restrictive: it runs after
> + * cap_capable() (LSM_ORDER_FIRST), so it can deny capabilities that
> + * commoncap would allow, but it can never grant capabilities that
> + * commoncap denied.
> + *
> + * Return: 0 if allowed, -EPERM if capability use is denied.
> + */
> +static int hook_capable(const struct cred *cred, struct user_namespace *ns,
> + int cap, unsigned int opts)
> +{
> + const struct landlock_cred_security *subject;
> + size_t denied_layer;
> +
> + subject = landlock_get_applicable_subject(cred, cap_perm, NULL);
> + if (!subject)
> + return 0;
> +
> + denied_layer = landlock_perm_is_denied(subject->domain,
> + LANDLOCK_PERM_CAPABILITY_USE,
> + landlock_cap_to_bit(cap));
> + if (!denied_layer)
> + return 0;
> +
> + /*
> + * Respects CAP_OPT_NOAUDIT to suppress audit records for
> + * capability probes (e.g., ns_capable_noaudit(),
> + * has_capability_noaudit()).
> + */
> + if (!(opts & CAP_OPT_NOAUDIT))
> + landlock_log_denial(subject,
> + &(struct landlock_request){
> + .type = LANDLOCK_REQUEST_CAPABILITY,
> + .audit.type = LSM_AUDIT_DATA_CAP,
> + .audit.u.cap = cap,
> + .layer_plus_one = denied_layer,
> + });
> +
> + return -EPERM;
> +}
> +
> +static struct security_hook_list landlock_hooks[] __ro_after_init = {
> + LSM_HOOK_INIT(capable, hook_capable),
> +};
> +
> +__init void landlock_add_cap_hooks(void)
> +{
> + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
> + &landlock_lsmid);
> +}
> +
> +#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
> +
> +#include <kunit/test.h>
> +
> +static void test_cap_to_bit(struct kunit *const test)
> +{
> + KUNIT_EXPECT_EQ(test, BIT_ULL(0), landlock_cap_to_bit(0));
> + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_NET_RAW),
> + landlock_cap_to_bit(CAP_NET_RAW));
> + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_SYS_ADMIN),
> + landlock_cap_to_bit(CAP_SYS_ADMIN));
> + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_LAST_CAP),
> + landlock_cap_to_bit(CAP_LAST_CAP));
> +}
> +
> +static void test_cap_to_bit_invalid(struct kunit *const test)
> +{
> + KUNIT_EXPECT_EQ(test, 0ULL, landlock_cap_to_bit(-1));
> + KUNIT_EXPECT_EQ(test, 0ULL, landlock_cap_to_bit(CAP_LAST_CAP + 1));
> +}
> +
> +static void test_caps_to_bits_valid(struct kunit *const test)
> +{
> + KUNIT_EXPECT_EQ(test, (u64)CAP_VALID_MASK,
> + landlock_caps_to_bits(CAP_VALID_MASK));
> + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_NET_RAW),
> + landlock_caps_to_bits(BIT_ULL(CAP_NET_RAW)));
> +}
> +
> +static void test_caps_to_bits_unknown(struct kunit *const test)
> +{
> + KUNIT_EXPECT_EQ(test, 0ULL,
> + landlock_caps_to_bits(BIT_ULL(CAP_LAST_CAP + 1)));
> +}
> +
> +static void test_caps_to_bits_zero(struct kunit *const test)
> +{
> + KUNIT_EXPECT_EQ(test, 0ULL, landlock_caps_to_bits(0));
> +}
> +
> +static struct kunit_case test_cases[] = {
> + /* clang-format off */
> + KUNIT_CASE(test_cap_to_bit),
> + KUNIT_CASE(test_cap_to_bit_invalid),
> + KUNIT_CASE(test_caps_to_bits_valid),
> + KUNIT_CASE(test_caps_to_bits_unknown),
> + KUNIT_CASE(test_caps_to_bits_zero),
> + {}
> + /* clang-format on */
> +};
> +
> +static struct kunit_suite test_suite = {
> + .name = "landlock_cap",
> + .test_cases = test_cases,
> +};
> +
> +kunit_test_suite(test_suite);
> +
> +#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
> diff --git a/security/landlock/cap.h b/security/landlock/cap.h
> new file mode 100644
> index 000000000000..334b6974fb95
> --- /dev/null
> +++ b/security/landlock/cap.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Landlock - Capability hooks
> + *
> + * Copyright © 2026 Cloudflare
> + */
> +
> +#ifndef _SECURITY_LANDLOCK_CAP_H
> +#define _SECURITY_LANDLOCK_CAP_H
> +
> +#include <linux/bitops.h>
> +#include <linux/bug.h>
> +#include <linux/capability.h>
> +#include <linux/compiler_attributes.h>
> +#include <linux/types.h>
> +
> +/**
> + * landlock_cap_to_bit - Convert a capability number to a compact bitmask
> + *
> + * @cap: Capability number (CAP_*).
> + *
> + * Return: BIT_ULL(@cap), or 0 if @cap is invalid (with a WARN).
> + */
> +static inline __attribute_const__ u64 landlock_cap_to_bit(const int cap)
> +{
> + if (WARN_ON_ONCE(!cap_valid(cap)))
> + return 0;
> +
> + return BIT_ULL(cap);
> +}
> +
> +/**
> + * landlock_caps_to_bits - Validate and mask a capability bitmask
> + *
> + * @capabilities: Bitmask of capabilities (e.g. from user space).
> + *
> + * Return: @capabilities masked to known capabilities. Warns if unknown
> + * bits are present (callers must pre-mask for user input).
> + */
> +static inline __attribute_const__ u64
> +landlock_caps_to_bits(const u64 capabilities)
> +{
> + WARN_ON_ONCE(capabilities & ~CAP_VALID_MASK);
> + return capabilities & CAP_VALID_MASK;
> +}
> +
> +__init void landlock_add_cap_hooks(void);
> +
> +#endif /* _SECURITY_LANDLOCK_CAP_H */
> diff --git a/security/landlock/cred.h b/security/landlock/cred.h
> index 68067ff53ead..257197facbae 100644
> --- a/security/landlock/cred.h
> +++ b/security/landlock/cred.h
> @@ -184,6 +184,9 @@ landlock_perm_is_denied(const struct landlock_ruleset *const domain,
> case LANDLOCK_PERM_NAMESPACE_ENTER:
> allowed = domain->layers[layer].allowed.ns;
> break;
> + case LANDLOCK_PERM_CAPABILITY_USE:
> + allowed = domain->layers[layer].allowed.caps;
> + break;
> default:
> WARN_ON_ONCE(1);
> return layer + 1;
> diff --git a/security/landlock/limits.h b/security/landlock/limits.h
> index e361b653fcf5..43e832c0deb0 100644
> --- a/security/landlock/limits.h
> +++ b/security/landlock/limits.h
> @@ -11,6 +11,7 @@
> #define _SECURITY_LANDLOCK_LIMITS_H
>
> #include <linux/bitops.h>
> +#include <linux/capability.h>
> #include <linux/limits.h>
> #include <linux/ns/ns_common_types.h>
> #include <uapi/linux/landlock.h>
> @@ -32,11 +33,12 @@
> #define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1)
> #define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE)
>
> -#define LANDLOCK_LAST_PERM LANDLOCK_PERM_NAMESPACE_ENTER
> +#define LANDLOCK_LAST_PERM LANDLOCK_PERM_CAPABILITY_USE
> #define LANDLOCK_MASK_PERM ((LANDLOCK_LAST_PERM << 1) - 1)
> #define LANDLOCK_NUM_PERM __const_hweight64(LANDLOCK_MASK_PERM)
>
> #define LANDLOCK_NUM_PERM_NS __const_hweight64((u64)(CLONE_NS_ALL))
> +#define LANDLOCK_NUM_PERM_CAP (CAP_LAST_CAP + 1)
>
> #define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_TSYNC
> #define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1)
> diff --git a/security/landlock/setup.c b/security/landlock/setup.c
> index a7ed776b41b4..971419d663bb 100644
> --- a/security/landlock/setup.c
> +++ b/security/landlock/setup.c
> @@ -11,6 +11,7 @@
> #include <linux/lsm_hooks.h>
> #include <uapi/linux/lsm.h>
>
> +#include "cap.h"
> #include "common.h"
> #include "cred.h"
> #include "errata.h"
> @@ -70,6 +71,7 @@ static int __init landlock_init(void)
> landlock_add_fs_hooks();
> landlock_add_net_hooks();
> landlock_add_ns_hooks();
> + landlock_add_cap_hooks();
> landlock_init_id();
> landlock_initialized = true;
> pr_info("Up and running.\n");
> diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
> index 152d952e98f6..38a4bf92781a 100644
> --- a/security/landlock/syscalls.c
> +++ b/security/landlock/syscalls.c
> @@ -30,6 +30,7 @@
> #include <linux/uaccess.h>
> #include <uapi/linux/landlock.h>
>
> +#include "cap.h"
> #include "cred.h"
> #include "domain.h"
> #include "fs.h"
> @@ -98,8 +99,9 @@ static void build_check_abi(void)
> struct landlock_path_beneath_attr path_beneath_attr;
> struct landlock_net_port_attr net_port_attr;
> struct landlock_namespace_attr namespace_attr;
> + struct landlock_capability_attr capability_attr;
> size_t ruleset_size, path_beneath_size, net_port_size;
> - size_t namespace_size;
> + size_t namespace_size, capability_size;
>
> /*
> * For each user space ABI structures, first checks that there is no
> @@ -127,6 +129,11 @@ static void build_check_abi(void)
> namespace_size += sizeof(namespace_attr.namespace_types);
> BUILD_BUG_ON(sizeof(namespace_attr) != namespace_size);
> BUILD_BUG_ON(sizeof(namespace_attr) != 16);
> +
> + capability_size = sizeof(capability_attr.allowed_perm);
> + capability_size += sizeof(capability_attr.capabilities);
> + BUILD_BUG_ON(sizeof(capability_attr) != capability_size);
> + BUILD_BUG_ON(sizeof(capability_attr) != 16);
> }
>
> /* Ruleset handling */
> @@ -449,14 +456,57 @@ static int add_rule_namespace(struct landlock_ruleset *const ruleset,
> return 0;
> }
>
> +static int add_rule_capability(struct landlock_ruleset *const ruleset,
> + const void __user *const rule_attr)
> +{
> + struct landlock_capability_attr cap_attr;
> + int res;
> + access_mask_t mask;
> +
> + /* Copies raw user space buffer. */
> + res = copy_from_user(&cap_attr, rule_attr, sizeof(cap_attr));
> + if (res)
> + return -EFAULT;
> +
> + /* Informs about useless rule: empty allowed_perm. */
> + if (!cap_attr.allowed_perm)
> + return -ENOMSG;
> +
> + /* The allowed_perm must match LANDLOCK_PERM_CAPABILITY_USE. */
> + if (cap_attr.allowed_perm != LANDLOCK_PERM_CAPABILITY_USE)
> + return -EINVAL;
> +
> + /* Checks that allowed_perm matches the @ruleset constraints. */
> + mask = landlock_get_perm_mask(ruleset, 0);
> + if (!(mask & LANDLOCK_PERM_CAPABILITY_USE))
> + return -EINVAL;
> +
> + /* Informs about useless rule: empty capabilities. */
> + if (!cap_attr.capabilities)
> + return -ENOMSG;
> +
> + /*
> + * Stores only the capabilities this kernel knows about.
> + * Unknown bits are silently accepted for forward compatibility:
> + * user space compiled against newer headers can pass new
> + * CAP_* bits without getting EINVAL on older kernels.
> + * Unknown bits have no effect because no hook checks them.
> + */
> + mutex_lock(&ruleset->lock);
> + ruleset->layers[0].allowed.caps |=
> + landlock_caps_to_bits(cap_attr.capabilities & CAP_VALID_MASK);
> + mutex_unlock(&ruleset->lock);
> + return 0;
> +}
> +
> /**
> * sys_landlock_add_rule - Add a new rule to a ruleset
> *
> * @ruleset_fd: File descriptor tied to the ruleset that should be extended
> * with the new rule.
> * @rule_type: Identify the structure type pointed to by @rule_attr:
> - * %LANDLOCK_RULE_PATH_BENEATH, %LANDLOCK_RULE_NET_PORT, or
> - * %LANDLOCK_RULE_NAMESPACE.
> + * %LANDLOCK_RULE_PATH_BENEATH, %LANDLOCK_RULE_NET_PORT,
> + * %LANDLOCK_RULE_NAMESPACE, or %LANDLOCK_RULE_CAPABILITY.
> * @rule_attr: Pointer to a rule (matching the @rule_type).
> * @flags: Must be 0.
> *
> @@ -508,6 +558,8 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
> return add_rule_net_port(ruleset, rule_attr);
> case LANDLOCK_RULE_NAMESPACE:
> return add_rule_namespace(ruleset, rule_attr);
> + case LANDLOCK_RULE_CAPABILITY:
> + return add_rule_capability(ruleset, rule_attr);
> default:
> return -EINVAL;
> }
> --
> 2.53.0
>
Reviewed-by: Günther Noack <gnoack@google.com>
—Günther
next prev parent reply other threads:[~2026-05-08 15:55 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-12 10:04 [RFC PATCH v1 00/11] Landlock: Namespace and capability control Mickaël Salaün
2026-03-12 10:04 ` [RFC PATCH v1 01/11] security: add LSM blob and hooks for namespaces Mickaël Salaün
2026-03-25 12:31 ` Christian Brauner
2026-04-09 16:40 ` Mickaël Salaün
2026-04-10 9:35 ` Christian Brauner
2026-04-22 21:21 ` Günther Noack
2026-04-23 0:19 ` Paul Moore
2026-04-24 18:56 ` Mickaël Salaün
2026-04-24 19:28 ` Paul Moore
2026-04-27 14:57 ` Christian Brauner
2026-04-27 21:46 ` Paul Moore
2026-03-12 10:04 ` [RFC PATCH v1 02/11] security: Add LSM_AUDIT_DATA_NS for namespace audit records Mickaël Salaün
2026-03-25 12:32 ` Christian Brauner
2026-04-01 16:38 ` Mickaël Salaün
2026-04-01 18:48 ` Mickaël Salaün
2026-04-09 13:29 ` Christian Brauner
2026-04-22 21:21 ` Günther Noack
2026-03-12 10:04 ` [RFC PATCH v1 03/11] nsproxy: Add FOR_EACH_NS_TYPE() X-macro and CLONE_NS_ALL Mickaël Salaün
2026-03-25 12:33 ` Christian Brauner
2026-03-25 15:26 ` Mickaël Salaün
2026-03-26 14:22 ` (subset) " Christian Brauner
2026-03-12 10:04 ` [RFC PATCH v1 04/11] landlock: Wrap per-layer access masks in struct layer_rights Mickaël Salaün
2026-04-10 1:45 ` Tingmao Wang
2026-04-22 21:29 ` Günther Noack
2026-03-12 10:04 ` [RFC PATCH v1 05/11] landlock: Enforce namespace entry restrictions Mickaël Salaün
2026-04-10 1:45 ` Tingmao Wang
2026-05-08 15:46 ` Günther Noack
2026-03-12 10:04 ` [RFC PATCH v1 06/11] landlock: Enforce capability restrictions Mickaël Salaün
2026-04-22 21:36 ` Günther Noack
2026-05-08 15:54 ` Günther Noack [this message]
2026-03-12 10:04 ` [RFC PATCH v1 07/11] selftests/landlock: Drain stale audit records on init Mickaël Salaün
2026-03-24 13:27 ` Günther Noack
2026-03-12 10:04 ` [RFC PATCH v1 08/11] selftests/landlock: Add namespace restriction tests Mickaël Salaün
2026-03-12 10:04 ` [RFC PATCH v1 09/11] selftests/landlock: Add capability " Mickaël Salaün
2026-03-12 10:04 ` [RFC PATCH v1 10/11] samples/landlock: Add capability and namespace restriction support Mickaël Salaün
2026-04-22 21:20 ` Günther Noack
2026-04-23 13:51 ` Mickaël Salaün
2026-03-12 10:04 ` [RFC PATCH v1 11/11] landlock: Add documentation for capability and namespace restrictions Mickaël Salaün
2026-03-12 14:48 ` Justin Suess
2026-04-23 13:51 ` Mickaël Salaün
2026-04-23 16:01 ` Justin Suess
2026-04-23 16:08 ` Justin Suess
2026-04-22 20:38 ` Günther Noack
2026-04-23 13:52 ` Mickaël Salaün
2026-05-08 15:13 ` Günther Noack
2026-03-25 12:34 ` [RFC PATCH v1 00/11] Landlock: Namespace and capability control Christian Brauner
2026-04-20 15:06 ` Günther Noack
2026-04-21 8:24 ` Mickaël Salaün
2026-04-22 21:16 ` Günther Noack
2026-04-23 13:50 ` Mickaël Salaün
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=af4HUS2lRC2eUPnm@google.com \
--to=gnoack@google.com \
--cc=brauner@kernel.org \
--cc=enlightened@google.com \
--cc=ivanov.mikhail1@huawei-partners.com \
--cc=kernel-team@cloudflare.com \
--cc=lennart@poettering.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=m@maowtm.org \
--cc=mic@digikod.net \
--cc=nicolas.bouchinet@oss.cyber.gouv.fr \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
--cc=utilityemal77@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox