Re: [RFC PATCH v1 05/11] landlock: Enforce namespace entry restrictions

Tingmao Wang
2026-04-10T01:45:20Z

On 3/12/26 10:04, Mickaël Salaün wrote:
> [...]
> diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> index f88fa1f68b77..b76e656241df 100644
> --- a/include/uapi/linux/landlock.h
> +++ b/include/uapi/linux/landlock.h
> @@ -51,6 +51,14 @@ struct landlock_ruleset_attr {
> * resources (e.g. IPCs).
> */
> __u64 scoped;
> + /**
> + * @handled_perm: Bitmask of permissions (cf. `Permission flags`_)
> + * that this ruleset handles. Each permission controls a broad
> + * operation enforced at a kernel chokepoint: all instances of
> + * that operation are denied unless explicitly allowed by a rule.
> + * See Documentation/security/landlock.rst for the rationale.
> + */
> + __u64 handled_perm;
> };
>
> /**
> @@ -153,6 +161,11 @@ enum landlock_rule_type {
> * landlock_net_port_attr .
> */
> LANDLOCK_RULE_NET_PORT,
> + /**
> + * @LANDLOCK_RULE_NAMESPACE: Type of a &struct
> + * landlock_namespace_attr .
> + */
> + LANDLOCK_RULE_NAMESPACE,
> };
>
> /**
> @@ -206,6 +219,24 @@ struct landlock_net_port_attr {
> __u64 port;
> };
>
> +/**
> + * struct landlock_namespace_attr - Namespace type definition
> + *
> + * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_NAMESPACE.
> + */
> +struct landlock_namespace_attr {
> + /**
> + * @allowed_perm: Must be set to %LANDLOCK_PERM_NAMESPACE_ENTER.
> + */
> + __u64 allowed_perm;
> + /**
> + * @namespace_types: Bitmask of namespace types (``CLONE_NEW*`` flags)
> + * that should be allowed to be entered under this rule. Unknown bits
> + * are silently ignored for forward compatibility.
> + */
> + __u64 namespace_types;
> +};
> +
> /**
> * DOC: fs_access
> *

This UAPI looks good, follows existing patterns and is extensible.

btw, I guess for consistency, later on this new handled_perm should also
have a quiet_perm, which would allow suppressing audit logs for namespace
/ capability rules (for those (possibly a subset) added with
LANDLOCK_ADD_RULE_QUIET)?

> [...]
> @@ -153,6 +153,48 @@ landlock_get_applicable_subject(const struct cred *const cred,
> return NULL;
> }
>
> +/**
> + * landlock_perm_is_denied - Check if a permission bitmask request is denied
> + *
> + * @domain: The enforced domain.
> + * @perm_bit: The LANDLOCK_PERM_* flag to check.
> + * @request_value: Compact bitmask to look for (e.g. result of
> + * ``landlock_ns_type_to_bit(CLONE_NEWNET)``).
> + *
> + * Iterate from the youngest layer to the oldest. For each layer that

How about this:

/**
* landlock_perm_is_denied - Check if a permission request is denied
*
* @domain: The enforced domain.
* @perm_bit: The LANDLOCK_PERM_* flag to check.
* @request_value: Compact bitmask to look for (e.g. result of
* ``landlock_ns_type_to_bit(CLONE_NEWNET)``).
* Must have only bit set.
*
* Iterate from the youngest layer to the oldest. For each layer that

Basically, to make it more obvious that this functions only checks one
bit. Currently if a combination of permission bits are passed, this
allows access if any of them are allowed, which if accidentally used this
way in the future will probably be a bug. I was considering a
WARN_ON_ONCE but maybe it's a bit unnecessary for now given the caller
always passes a landlock_*_to_bit result (and those already WARN_ON_ONCE
if given invalid parameter).

Reviewed-by: Tingmao Wang <m@maowtm.org>