summaryrefslogtreecommitdiff
path: root/include/trace
diff options
context:
space:
mode:
authorMickaël Salaün <mic@digikod.net>2026-08-11 11:43:24 +0200
committerMickaël Salaün <mic@digikod.net>2026-08-17 10:17:15 +0200
commit132d84b16b5fe729fd228b169fa9e55f3e56b7af (patch)
tree247b822b59f9102095414f15aa1aa08652fdff96 /include/trace
parent67567f03a4bf75905684b333f518da8c21f58514 (diff)
landlock: Add landlock_enforce_domain tracepoint
The landlock_create_domain event records that a domain was created, once, before thread-sync. It cannot tell which threads end up enforcing it: a successful landlock_restrict_self(2) with LANDLOCK_RESTRICT_SELF_TSYNC applies the domain to the caller and every eligible sibling. Creation (the operation) and enforcement (the per-thread outcome) are distinct. Add landlock_enforce_domain(domain, complete, process_wide), emitted once per thread the domain is applied to, strictly after that thread's commit_creds(), so it fires only for a thread that is enforcing the domain, never speculatively; an aborted operation emits none. The lifecycle now reads create -> enforce* -> free. The two booleans name properties, not the implementation: - complete: marks the single event that concludes the operation. It names the outcome, the set is now enforced, not which thread finishes, which the contract leaves unspecified. - process_wide: means every eligible thread of the process is covered. It is set race-free by either establishing path, thread-sync or a single-threaded process, so complete && process_wide is the whole-process-enforced guarantee. The requesting thread and source ruleset are not repeated here: they are on create_domain (joined via domain->hierarchy->id) and on the immutable domain->hierarchy->details. Source ruleset means the ruleset_id and ruleset_version recorded on create_domain, not the ruleset object, which the caller may close before enforcement. Cc: Günther Noack <gnoack@google.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-11-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
Diffstat (limited to 'include/trace')
-rw-r--r--include/trace/events/landlock.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h
index 9f0d0436a8bb..43bf126eb449 100644
--- a/include/trace/events/landlock.h
+++ b/include/trace/events/landlock.h
@@ -340,6 +340,66 @@ TRACE_EVENT(landlock_create_domain,
);
/**
+ * landlock_enforce_domain - Domain enforced on a thread
+ *
+ * @domain: Domain now enforced on the current thread (never NULL,
+ * immutable; read locklessly). Correlate to
+ * landlock_create_domain via @domain->hierarchy->id for the
+ * source ruleset and requesting thread, or read
+ * @domain->hierarchy->details for the requesting process.
+ * @complete: Set on the single event that concludes the operation, after
+ * all its other enforcements; filter on it for one event per
+ * operation.
+ * @process_wide: The enforcement covers every eligible (non-exiting)
+ * thread of the process: set when the caller used
+ * %LANDLOCK_RESTRICT_SELF_TSYNC or the process is
+ * single-threaded. A lone thread whose group still
+ * holds a zombie leader is not counted single-threaded,
+ * so process_wide == 0 never proves the opposite.
+ * @no_new_privs: The enforcing thread's no_new_privs state at
+ * enforcement time: 1 if set (by a prior
+ * :manpage:`prctl(2)` %PR_SET_NO_NEW_PRIVS or by
+ * %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS), 0 if the domain
+ * was enforced with %CAP_SYS_ADMIN instead.
+ *
+ * Emitted for each thread sys_landlock_restrict_self() enforces the
+ * domain on, in that thread's own context, right after its
+ * commit_creds(), so it fires only once the thread is irreversibly
+ * enforcing the domain (aborted operations emit none). Not
+ * balanced; every enforcement falls between the domain's
+ * landlock_create_domain and landlock_free_domain events.
+ *
+ * @complete == 1 && @process_wide == 1 means the whole process is
+ * sandboxed by @domain, durably (Landlock domains are monotonic and
+ * inherited on :manpage:`clone(2)`).
+ */
+TRACE_EVENT(landlock_enforce_domain,
+
+ TP_PROTO(const struct landlock_domain *domain, bool complete,
+ bool process_wide, bool no_new_privs),
+
+ TP_ARGS(domain, complete, process_wide, no_new_privs),
+
+ TP_STRUCT__entry(
+ __field( __u64, domain_id )
+ __field( bool, complete )
+ __field( bool, process_wide )
+ __field( bool, no_new_privs )
+ ),
+
+ TP_fast_assign(
+ __entry->domain_id = domain->hierarchy->id;
+ __entry->complete = complete;
+ __entry->process_wide = process_wide;
+ __entry->no_new_privs = no_new_privs;
+ ),
+
+ TP_printk("domain=%llx complete=%d process_wide=%d no_new_privs=%d",
+ __entry->domain_id, __entry->complete, __entry->process_wide,
+ __entry->no_new_privs)
+);
+
+/**
* landlock_free_domain - Domain freed
*
* @hierarchy: Hierarchy node being freed (never NULL).