summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-10-08 11:39:37 +0200
committerMark Brown <broonie@kernel.org>2026-10-08 11:39:37 +0200
commitfaf79d91d67e539ed4ce446f2a31127ec27dbe63 (patch)
tree940048866c3aef03cdc2673d88125608905a2751 /include
parent05e11e9b39f6bf8b49e7e738f7af4ead3a8f9776 (diff)
parent64b9e6eff524804de6ec7a7be83131ec3d8ae17f (diff)
downloadlinux-next-faf79d91d67e539ed4ce446f2a31127ec27dbe63.tar.gz
linux-next-faf79d91d67e539ed4ce446f2a31127ec27dbe63.zip
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git
Diffstat (limited to 'include')
-rw-r--r--include/linux/landlock.h29
-rw-r--r--include/trace/events/landlock.h244
-rw-r--r--include/uapi/linux/landlock.h139
3 files changed, 381 insertions, 31 deletions
diff --git a/include/linux/landlock.h b/include/linux/landlock.h
index 004cbd0b9298..0ee4880988ba 100644
--- a/include/linux/landlock.h
+++ b/include/linux/landlock.h
@@ -13,14 +13,16 @@
#include <uapi/linux/landlock.h>
/*
- * Access-right and scope names, shared between the audit records (get_blocker()
- * in security/landlock/audit.c) and the trace events
+ * Access-right, scope, and permission names, shared between the audit records
+ * (get_blocker() in security/landlock/audit.c) and the trace events
* (include/trace/events/landlock.h). A consumer defines
* _LANDLOCK_NAME_ENTRY(mask, name) before expanding a list and undefines it
* afterwards: audit maps each entry to a "[bit] = name" slot for O(1) lookup,
* the trace events map it to a __print_flags() { mask, name } pair. The bit
* value lives only in the LANDLOCK_* UAPI constant each entry references.
- * Names are unprefixed; audit prepends the "fs."/"net."/"scope." category.
+ * Access-right and scope names are unprefixed; audit prepends the
+ * "fs."/"net."/"scope." category. Permission entries carry an action and a
+ * domain for the qualified and bare views below.
*/
#define _LANDLOCK_ACCESS_FS_NAMES \
_LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_EXECUTE, "execute"), \
@@ -53,4 +55,25 @@
"abstract_unix_socket"), \
_LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_SIGNAL, "signal")
+#define _LANDLOCK_PERMISSION_NAMESPACE_NAME "namespace"
+#define _LANDLOCK_PERMISSION_CAPABILITY_NAME "capability"
+
+#define _LANDLOCK_PERMISSION_LIST(entry) \
+ entry(LANDLOCK_PERMISSION_NAMESPACE_USE, "use", \
+ _LANDLOCK_PERMISSION_NAMESPACE_NAME), \
+ entry(LANDLOCK_PERMISSION_CAPABILITY_USE, "use", \
+ _LANDLOCK_PERMISSION_CAPABILITY_NAME)
+
+#define _LANDLOCK_PERMISSION_QUALIFIED_ENTRY(mask, action, domain) \
+ _LANDLOCK_NAME_ENTRY(mask, domain "." action)
+
+#define _LANDLOCK_PERMISSION_BARE_ENTRY(mask, action, ...) \
+ _LANDLOCK_NAME_ENTRY(mask, action)
+
+#define _LANDLOCK_PERMISSION_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_QUALIFIED_ENTRY)
+
+#define _LANDLOCK_PERMISSION_BLOCKER_NAMES \
+ _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_BARE_ENTRY)
+
#endif /* _LINUX_LANDLOCK_H */
diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h
index 3a43638c9bc2..b11f98d0a736 100644
--- a/include/trace/events/landlock.h
+++ b/include/trace/events/landlock.h
@@ -36,6 +36,8 @@ static_assert(sizeof(access_mask_t) <= sizeof(u64));
TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY);
TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_ACCESS);
TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NET_ACCESS);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NAMESPACE);
+TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_CAPABILITY);
#ifdef CREATE_TRACE_POINTS
@@ -276,13 +278,14 @@ static inline const char *__trace_landlock_print_layers(
* Every denial event shares three fields. domain is the ID of the
* innermost domain that blocked the access. same_exec tells whether the
* current task is the same executable that entered that domain. logged is
- * the domain's audit-logging decision for this denial (its log_status is
- * enabled and the per-execution flag selected by same_exec is set); a
- * stateless ftrace filter can select the denials the domain submits to
- * audit with logged==1, without reconstructing it from the per-execution
- * log flags. Denial events order their fields as domain, same_exec,
- * logged, then blockers (deny_access events only), then the type-specific
- * object fields, then any variable-length field.
+ * the complete audit-submission selection for this denial: the domain's
+ * log_status and per-execution flag, per-object or per-member quiet rules,
+ * and request-specific no-audit options. This excludes global audit state
+ * and audit-side filters. A stateless ftrace filter can select the denials
+ * the domain submits to audit with logged==1, without reconstructing those
+ * inputs. Denial events order their fields as domain, same_exec,
+ * logged, then the blockers verdict input, then the
+ * type-specific object fields, then any variable-length field.
*
* Relational referents
* ~~~~~~~~~~~~~~~~~~~~~
@@ -302,9 +305,9 @@ static inline const char *__trace_landlock_print_layers(
* Blocker fields
* ~~~~~~~~~~~~~~
*
- * The filesystem and network blocker arguments identify the request type
- * and carry its final missing access subset when applicable. The type
- * determines how to interpret the access value.
+ * Blocker arguments identify the request type and carry its final missing
+ * access subset when applicable. The type determines how to interpret the
+ * access value.
*/
/*
@@ -343,26 +346,31 @@ TRACE_EVENT(landlock_create_ruleset,
TP_ARGS(ruleset),
TP_STRUCT__entry(
- __field( u64, ruleset_id )
- __field( u64, ruleset_version )
- __field( access_mask_t, handled_fs )
- __field( access_mask_t, handled_net )
- __field( access_mask_t, scoped )
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, handled_fs )
+ __field( access_mask_t, handled_net )
+ __field( access_mask_t, scoped )
+ __field( access_mask_t, handled_permissions )
),
TP_fast_assign(
__entry->ruleset_id = ruleset->id;
__entry->ruleset_version = ruleset->version;
- __entry->handled_fs = ruleset->handled_masks.fs;
- __entry->handled_net = ruleset->handled_masks.net;
- __entry->scoped = ruleset->handled_masks.scope;
+ __entry->handled_fs = ruleset->layer.handled.fs;
+ __entry->handled_net = ruleset->layer.handled.net;
+ __entry->scoped = ruleset->layer.handled.scope;
+ __entry->handled_permissions =
+ ruleset->layer.handled.permissions;
),
- TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s",
+ TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s handled_permissions=%s",
__entry->ruleset_id, __entry->ruleset_version,
__print_flags(__entry->handled_fs, "|", _LANDLOCK_ACCESS_FS_NAMES),
__print_flags(__entry->handled_net, "|", _LANDLOCK_ACCESS_NET_NAMES),
- __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES))
+ __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES),
+ __print_flags(__entry->handled_permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES))
);
/**
@@ -497,6 +505,103 @@ TRACE_EVENT(landlock_add_rule_net_port,
);
/**
+ * landlock_add_rule_namespace - Namespace rule added to a ruleset
+ *
+ * @ruleset: Source ruleset (never NULL).
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @permissions: Validated permission mask from the rule attribute.
+ * @allowed_namespace_types: Effective known namespace types allowed by this
+ * call, using CLONE_NEW* values.
+ * @quiet_namespace_types: Effective known namespace types quieted by this
+ * call, using CLONE_NEW* values.
+ *
+ * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so
+ * the reported ruleset is a stable snapshot that no concurrent writer can
+ * change.
+ */
+TRACE_EVENT(landlock_add_rule_namespace,
+
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 permissions, u64 allowed_namespace_types,
+ u64 quiet_namespace_types),
+
+ TP_ARGS(ruleset, flags, permissions, allowed_namespace_types,
+ quiet_namespace_types),
+
+ TP_STRUCT__entry(
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, permissions )
+ __field( u64, allowed_namespace_types )
+ __field( u64, quiet_namespace_types )
+ ),
+
+ TP_fast_assign(
+ lockdep_assert_held(&ruleset->lock);
+ __entry->ruleset_id = ruleset->id;
+ __entry->ruleset_version = ruleset->version;
+ __entry->permissions = permissions;
+ __entry->allowed_namespace_types = allowed_namespace_types;
+ __entry->quiet_namespace_types = quiet_namespace_types;
+ ),
+
+ TP_printk("ruleset=%llx.%llu permissions=%s allowed_namespace_types=0x%llx quiet_namespace_types=0x%llx",
+ __entry->ruleset_id, __entry->ruleset_version,
+ __print_flags(__entry->permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES),
+ __entry->allowed_namespace_types,
+ __entry->quiet_namespace_types)
+);
+
+/**
+ * landlock_add_rule_capability - Capability rule added to a ruleset
+ *
+ * @ruleset: Source ruleset (never NULL).
+ * @flags: Complete validated landlock_add_rule_flags value supplied by this
+ * successful call, not the rule's accumulated quiet state.
+ * @permissions: Validated permission mask from the rule attribute.
+ * @allowed_capabilities: Effective known capabilities allowed by this call.
+ * @quiet_capabilities: Effective known capabilities quieted by this call.
+ *
+ * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so
+ * the reported ruleset is a stable snapshot that no concurrent writer can
+ * change.
+ */
+TRACE_EVENT(landlock_add_rule_capability,
+
+ TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags,
+ u64 permissions, u64 allowed_capabilities,
+ u64 quiet_capabilities),
+
+ TP_ARGS(ruleset, flags, permissions, allowed_capabilities,
+ quiet_capabilities),
+
+ TP_STRUCT__entry(
+ __field( u64, ruleset_id )
+ __field( u64, ruleset_version )
+ __field( access_mask_t, permissions )
+ __field( u64, allowed_capabilities )
+ __field( u64, quiet_capabilities )
+ ),
+
+ TP_fast_assign(
+ lockdep_assert_held(&ruleset->lock);
+ __entry->ruleset_id = ruleset->id;
+ __entry->ruleset_version = ruleset->version;
+ __entry->permissions = permissions;
+ __entry->allowed_capabilities = allowed_capabilities;
+ __entry->quiet_capabilities = quiet_capabilities;
+ ),
+
+ TP_printk("ruleset=%llx.%llu permissions=%s allowed_capabilities=0x%llx quiet_capabilities=0x%llx",
+ __entry->ruleset_id, __entry->ruleset_version,
+ __print_flags(__entry->permissions, "|",
+ _LANDLOCK_PERMISSION_NAMES),
+ __entry->allowed_capabilities, __entry->quiet_capabilities)
+);
+
+/**
* landlock_create_domain - New domain created
*
* @domain: Newly created domain (never NULL, immutable after creation).
@@ -874,6 +979,105 @@ TRACE_EVENT(landlock_deny_access_net,
);
/**
+ * landlock_deny_permission_namespace - Namespace use denied
+ *
+ * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
+ * domain field.
+ * @same_exec: Whether the current task entered the denying domain itself.
+ * @logged: Whether this denial was selected for audit logging.
+ * @blockers: Request type and final missing permission subset (never NULL).
+ * @namespace_type: CLONE_NEW* namespace type that was denied.
+ * @namespace_id: Namespace ID, or 0 when creation was denied.
+ *
+ * Emitted when a Landlock domain denies namespace use.
+ */
+TRACE_EVENT(landlock_deny_permission_namespace,
+
+ TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
+ bool logged, const struct landlock_blockers *blockers,
+ u32 namespace_type, u64 namespace_id),
+
+ TP_ARGS(hierarchy, same_exec, logged, blockers, namespace_type,
+ namespace_id),
+
+ TP_STRUCT__entry(
+ __field( u64, domain_id )
+ __field( bool, same_exec )
+ __field( bool, logged )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
+ __field( u32, namespace_type )
+ __field( u64, namespace_id )
+ ),
+
+ TP_fast_assign(
+ __entry->domain_id = hierarchy->id;
+ __entry->same_exec = same_exec;
+ __entry->logged = logged;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
+ __entry->namespace_type = namespace_type;
+ __entry->namespace_id = namespace_id;
+ ),
+
+ TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s namespace_type=0x%x namespace_id=%llu",
+ __entry->domain_id, __entry->same_exec, __entry->logged,
+ __entry->blockers_type == LANDLOCK_REQUEST_NAMESPACE ?
+ __print_flags(__entry->blockers_access, "|",
+ _LANDLOCK_PERMISSION_BLOCKER_NAMES) :
+ "unknown",
+ __entry->namespace_type, __entry->namespace_id)
+);
+
+/**
+ * landlock_deny_permission_capability - Capability use denied
+ *
+ * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
+ * domain field.
+ * @same_exec: Whether the current task entered the denying domain itself.
+ * @logged: Whether this denial was selected for audit logging.
+ * @blockers: Request type and final missing permission subset (never NULL).
+ * @capability: CAP_* number that was denied.
+ *
+ * Emitted when a Landlock domain denies capability use, except for checks
+ * made with CAP_OPT_NOAUDIT, which are denied without emitting this event.
+ */
+TRACE_EVENT(landlock_deny_permission_capability,
+
+ TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec,
+ bool logged, const struct landlock_blockers *blockers,
+ int capability),
+
+ TP_ARGS(hierarchy, same_exec, logged, blockers, capability),
+
+ TP_STRUCT__entry(
+ __field( u64, domain_id )
+ __field( bool, same_exec )
+ __field( bool, logged )
+ __field( enum landlock_request_type, blockers_type )
+ __field( access_mask_t, blockers_access )
+ __field( int, capability )
+ ),
+
+ TP_fast_assign(
+ __entry->domain_id = hierarchy->id;
+ __entry->same_exec = same_exec;
+ __entry->logged = logged;
+ __entry->blockers_type = blockers->type;
+ __entry->blockers_access = blockers->access;
+ __entry->capability = capability;
+ ),
+
+ TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s capability=%d",
+ __entry->domain_id, __entry->same_exec, __entry->logged,
+ __entry->blockers_type == LANDLOCK_REQUEST_CAPABILITY ?
+ __print_flags(__entry->blockers_access, "|",
+ _LANDLOCK_PERMISSION_BLOCKER_NAMES) :
+ "unknown",
+ __entry->capability)
+);
+
+/**
* landlock_deny_ptrace - Ptrace access denied by a Landlock domain
*
* @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index cceda3b3b961..24510e5d8479 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -33,14 +33,14 @@
* (and that they have tested with a kernel that supported them all).
*
* @quiet_access_fs and @quiet_access_net are bitmasks of actions for which a
- * denial by this layer will not trigger a log if the corresponding object (or
- * its children, for filesystem rules) is marked with the "quiet" bit via
- * %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per
+ * denial by this layer will not trigger an audit record if the corresponding
+ * object (or its children, for filesystem rules) is marked with the "quiet" bit
+ * via %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per
* landlock_restrict_self() flags. @quiet_scoped is similar, except that it
* does not require marking any objects as quiet - if the ruleset is created
* with any bits set in @quiet_scoped, then denial of such scoped resources will
- * not trigger any log. These 3 fields are available since Landlock ABI version
- * 10.
+ * not trigger an audit record. These three fields are available since Landlock
+ * ABI version 10.
*
* @quiet_access_fs, @quiet_access_net and @quiet_scoped must be a subset of
* @handled_access_fs, @handled_access_net and @scoped respectively.
@@ -66,18 +66,24 @@ struct landlock_ruleset_attr {
__u64 scoped;
/**
* @quiet_access_fs: Bitmask of filesystem actions which should not be
- * logged if per-object quiet flag is set.
+ * submitted to audit if the per-object quiet flag is set.
*/
__u64 quiet_access_fs;
/**
* @quiet_access_net: Bitmask of network actions which should not be
- * logged if per-object quiet flag is set.
+ * submitted to audit if the per-object quiet flag is set.
*/
__u64 quiet_access_net;
/**
- * @quiet_scoped: Bitmask of scoped actions which should not be logged.
+ * @quiet_scoped: Bitmask of scoped actions which should not be
+ * submitted to audit.
*/
__u64 quiet_scoped;
+ /**
+ * @handled_permissions: Bitmask of handled permissions (cf. `Permission
+ * flags`_).
+ */
+ __u64 handled_permissions;
};
/**
@@ -228,6 +234,15 @@ 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,
+ /**
+ * @LANDLOCK_RULE_CAPABILITY: Type of a &struct
+ * landlock_capability_attr .
+ */
+ LANDLOCK_RULE_CAPABILITY,
};
/**
@@ -282,6 +297,77 @@ struct landlock_net_port_attr {
};
/**
+ * struct landlock_namespace_attr - Namespace type definition
+ *
+ * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_NAMESPACE.
+ */
+struct landlock_namespace_attr {
+ /**
+ * @permissions: Must be set to %LANDLOCK_PERMISSION_NAMESPACE_USE.
+ */
+ __u64 permissions;
+ /**
+ * @allowed_namespace_types: Bitmask of namespace types (``CLONE_NEW*``
+ * flags) to allow under this rule. Unknown bits are silently ignored
+ * for forward compatibility.
+ */
+ __u64 allowed_namespace_types;
+ /**
+ * @quiet_namespace_types: Bitmask of namespace types (``CLONE_NEW*``
+ * flags) whose denial by this layer should not be submitted to audit,
+ * even when landlock_restrict_self() enables audit logging. Only audit
+ * records attributed to this layer are suppressed; denial tracepoints
+ * still fire (see `Permission flags`_). Bits also set in
+ * @allowed_namespace_types have no effect, since an allowed type is
+ * never denied. Unknown bits are silently ignored.
+ *
+ * At least one of @allowed_namespace_types or @quiet_namespace_types
+ * must be non-zero, otherwise the call returns ``-ENOMSG``. The
+ * non-zero check runs on the raw input before unknown-bit masking, so a
+ * rule that sets only bits unknown to the running kernel succeeds but
+ * has no runtime effect. Programs should omit this rule when they
+ * neither allow nor quiet a namespace type.
+ */
+ __u64 quiet_namespace_types;
+};
+
+/**
+ * struct landlock_capability_attr - Capability definition
+ *
+ * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_CAPABILITY.
+ */
+struct landlock_capability_attr {
+ /**
+ * @permissions: Must be set to %LANDLOCK_PERMISSION_CAPABILITY_USE.
+ */
+ __u64 permissions;
+ /**
+ * @allowed_capabilities: Bitmask of capabilities (``1ULL << CAP_*``) to
+ * allow under this rule. Bits above ``CAP_LAST_CAP`` are silently
+ * ignored for forward compatibility.
+ */
+ __u64 allowed_capabilities;
+ /**
+ * @quiet_capabilities: Bitmask of capabilities (``1ULL << CAP_*``)
+ * whose denial by this layer should not be submitted to audit, even if
+ * audit logging would normally take place per landlock_restrict_self()
+ * flags. Only audit records attributed to this layer are suppressed;
+ * denial tracepoints still fire (see `Permission flags`_). Bits also
+ * set in @allowed_capabilities have no effect, since an allowed
+ * capability is never denied. Bits above ``CAP_LAST_CAP`` are silently
+ * ignored.
+ *
+ * At least one of @allowed_capabilities or @quiet_capabilities must be
+ * non-zero, otherwise the call returns ``-ENOMSG``. The non-zero check
+ * runs on the raw input before unknown-bit masking, so a rule that sets
+ * only bits unknown to the running kernel (above ``CAP_LAST_CAP``)
+ * succeeds but has no runtime effect. Programs should omit this rule
+ * when they neither allow nor quiet a capability.
+ */
+ __u64 quiet_capabilities;
+};
+
+/**
* DOC: fs_access
*
* A set of actions on kernel objects may be defined by an attribute (e.g.
@@ -507,4 +593,41 @@ struct landlock_net_port_attr {
#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
/* clang-format on*/
+/**
+ * DOC: permission
+ *
+ * Permission flags
+ * ~~~~~~~~~~~~~~~~
+ *
+ * These flags restrict the use of members of a category, each member being
+ * identified by a constant from another kernel subsystem (e.g. CLONE_NEW*
+ * namespace types, CAP_* capabilities). A flag covers every kernel path that
+ * uses a member of its category, and members that no rule explicitly allows are
+ * denied. Values unknown to the running kernel are silently accepted for
+ * forward compatibility and stay denied by default. See
+ * Documentation/security/landlock.rst for design details.
+ *
+ * When a ruleset handles multiple permissions whose operations overlap (e.g. a
+ * non-user namespace needs both its namespace type and CAP_SYS_ADMIN), the
+ * operation is allowed only if each handled permission independently allows it.
+ * See Documentation/userspace-api/landlock.rst.
+ *
+ * - %LANDLOCK_PERMISSION_NAMESPACE_USE: Restrict the use of specific namespace
+ * types: creation (:manpage:`unshare(2)`, :manpage:`clone(2)`,
+ * :manpage:`clone3(2)`), joining (:manpage:`setns(2)`), and acquiring an fd
+ * reference (:manpage:`open_tree(2)`, :manpage:`fsmount(2)`). A process in a
+ * Landlock domain that handles this permission is denied from using namespace
+ * types that are not explicitly allowed by a %LANDLOCK_RULE_NAMESPACE rule.
+ * Support added in Landlock ABI version 12.
+ * - %LANDLOCK_PERMISSION_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. Support added in
+ * Landlock ABI version 12.
+ */
+#define LANDLOCK_PERMISSION_NAMESPACE_USE (1ULL << 0)
+#define LANDLOCK_PERMISSION_CAPABILITY_USE (1ULL << 1)
+
#endif /* _UAPI_LINUX_LANDLOCK_H */