summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSasha Levin <sashal@kernel.org>2026-05-29 09:15:29 -0400
committerSasha Levin <sashal@kernel.org>2026-10-07 18:26:44 -0400
commitef777ef05ebcc5ea5393b4bd5af6fc3ad1b3aec9 (patch)
tree0ab7211d338ecb6195d0b5ac916af7345fb5356a /include
parenteddd14da6bede7b3f321fa6412ab7836b0a1ecfe (diff)
downloadlinux-next-ef777ef05ebcc5ea5393b4bd5af6fc3ad1b3aec9.tar.gz
linux-next-ef777ef05ebcc5ea5393b4bd5af6fc3ad1b3aec9.zip
kernel/api: add syscall enter/exit tracepoints
Add two tracepoints to the CONFIG_KAPI_RUNTIME_CHECKS syscall validation path so the framework's behavior can be observed without the noise and loss of pr_warn_ratelimited(): kapi_syscall_enter - the spec name, the raw argument values, and a rendered "name=value" list of the specified parameters (pointer-like values in hex, signed integers and file descriptors in decimal) kapi_syscall_exit - the spec name, the return value, and whether it matched the specification (spec_match) Both fire only for syscalls that have a KAPI specification and live inside the existing CONFIG_KAPI_RUNTIME_CHECKS region, so they exist exactly when the runtime checks do; they compile to no-ops without CONFIG_TRACEPOINTS and stay dormant until enabled. The parameter list is rendered only when the enter tracepoint is enabled. kapi_syscall_exit is also emitted on the parameter-validation rejection path -- where the validator returns -EINVAL and the real handler is skipped -- with spec_match=0, so every kapi_syscall_enter has a matching exit. Assisted-by: LLM Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/trace/events/kapi.h74
1 files changed, 74 insertions, 0 deletions
diff --git a/include/trace/events/kapi.h b/include/trace/events/kapi.h
new file mode 100644
index 000000000000..47828f333882
--- /dev/null
+++ b/include/trace/events/kapi.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kapi
+
+#if !defined(_TRACE_KAPI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KAPI_H
+
+#include <linux/tracepoint.h>
+
+/* Max length of the rendered "name=value, ..." parameter list. */
+#define KAPI_TP_PARAMS_LEN 256
+
+/*
+ * Emitted from the CONFIG_KAPI_RUNTIME_CHECKS syscall validation path for
+ * syscalls that have a KAPI specification: kapi_syscall_enter fires before
+ * parameter validation, kapi_syscall_exit after the handler returns.
+ * @name is the spec name, e.g. "sys_open".
+ *
+ * kapi_syscall_enter carries both the raw argument values (args[]) and, when
+ * the spec provides parameter metadata, a rendered "name=value" list (params,
+ * built by the caller): pointer-like values in hex, integers and fds in decimal.
+ */
+TRACE_EVENT(kapi_syscall_enter,
+
+ TP_PROTO(const char *name, int nargs, const s64 *args, const char *params),
+
+ TP_ARGS(name, nargs, args, params),
+
+ TP_STRUCT__entry(
+ __string( name, name )
+ __field( int, nargs )
+ __array( u64, args, 6 )
+ __string( params, params )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name);
+ __entry->nargs = nargs;
+ memset(__entry->args, 0, sizeof(__entry->args));
+ if (args && nargs > 0)
+ memcpy(__entry->args, args,
+ min_t(int, nargs, 6) * sizeof(__entry->args[0]));
+ __assign_str(params);
+ ),
+
+ TP_printk("%s(%s)", __get_str(name), __get_str(params))
+);
+
+TRACE_EVENT(kapi_syscall_exit,
+
+ TP_PROTO(const char *name, long ret, bool spec_match),
+
+ TP_ARGS(name, ret, spec_match),
+
+ TP_STRUCT__entry(
+ __string( name, name )
+ __field( long, ret )
+ __field( bool, spec_match )
+ ),
+
+ TP_fast_assign(
+ __assign_str(name);
+ __entry->ret = ret;
+ __entry->spec_match = spec_match;
+ ),
+
+ TP_printk("%s = %ld spec_match=%d",
+ __get_str(name), __entry->ret, __entry->spec_match)
+);
+
+#endif /* _TRACE_KAPI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>