diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-22 09:58:44 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-22 09:58:44 -1000 |
| commit | 3815f7d55ae18564f4eac57557479f8b3548af95 (patch) | |
| tree | e8ec39efb4107e35910700c2ea8bc91c9a0bf77e /include/trace | |
| parent | bbc48daecac6c69ccbce4005aa2a681298e2fc7d (diff) | |
| parent | 3e271a27c46fd591d1011c7de5a644a41e2010f1 (diff) | |
Merge tag 'landlock-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull Landlock update from Mickaël Salaün:
"The main change adds composable Landlock controls for namespace types
and Linux capabilities, thanks to new LSM hooks (merged via the LSM
tree). A umount race condition is also fixed"
* tag 'landlock-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
landlock: Fix superblock use-after-free in release_inode()
selftests/landlock: Fix snprintf truncation checks in test files
landlock: Add documentation for capability and namespace restrictions
samples/landlock: Add capability and namespace restriction support
selftests/landlock: Add capability restriction tests
selftests/landlock: Add namespace restriction tests
landlock: Enforce capability restrictions
landlock: Enforce namespace use restrictions
landlock: Wrap per-layer access masks in struct layer_config
landlock: Rename quiet_masks to quiet_access
Diffstat (limited to 'include/trace')
| -rw-r--r-- | include/trace/events/landlock.h | 244 |
1 files changed, 224 insertions, 20 deletions
diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h index 9e172ea22d95..6d9d9e7c7ca2 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 shared fields as domain, same_exec, + * and logged. Access and permission denial events follow these with the + * blockers verdict input, type-specific fields, and 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 |
