[RFC PATCH] binfmt_misc: add binfmt_misc_select tracepoint

From: BoxStrikesTeam

Date: Mon Oct 26 2026 - 16:17:49 EST


Hi,

This is an RFC patch for a binfmt_misc_select tracepoint. The patch
was tested on v7.3-rc7, but I currently have limited computer access
and no usable SMTP setup, so I could not send it with git send-email.
I know patches should be inline; the patch is attached as
0001-binfmt_misc-select-tracepoint.patch, and I can resend it inline
once I have access to a suitable environment.From: Eneshan ErdoÄ?an Karaca <BoxStrikesTeam@xxxxxxxxx>
Subject: [RFC PATCH] binfmt_misc: add binfmt_misc_select tracepoint

A binfmt_misc entry can select an interpreter for an exec. With a BPF
'B' handler, that selection can be made by a BPF struct_ops program.
The kernel commits the decision in bprm->interp and bprm->flags, but it
does not emit an event at the selection point.

Existing observers have to reconstruct the decision from
/proc/PID/exe, AT_EXECFD, AT_FLAGS, or /proc/PID/maps. These sources
are mode-dependent: a transparent dispatch still reports the original
binary in /proc/PID/exe, and a short-lived process can exit before the
observer reads it. A classic dispatch reports the interpreter, but
not which handler selected it or which invocation flags were used.

Add a tracepoint after the interpreter and the invocation flags are
selected. It reports the binary filename, the selected interpreter,
the handler name (for BPF handlers), the invocation flags, and the
pid. The flags are masked with MISC_FMT_INVOCATION_FLAGS so that
static entry state does not leak into the event.

The tracepoint is observability only; it does not change exec
behavior.

Assisted-by: LLM
Signed-off-by: Eneshan ErdoÄ?an Karaca <BoxStrikesTeam@xxxxxxxxx>
---

This is an RFC. A small PoC and short A/B results are available for
context; they are not needed to review the patch.

fs/binfmt_misc.c | 8 ++++++++
include/trace/events/binfmt_misc.h | 52 ++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)

diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -41,6 +41,9 @@

#include "internal.h"

+#define CREATE_TRACE_POINTS
+#include <trace/events/binfmt_misc.h>
+
/* Entry status and match type bit numbers. */
enum binfmt_misc_entry_bits {
MISC_FMT_ENABLED_BIT = 0,
@@ -644,6 +647,11 @@

flags = entry_invocation_flags(fmt, bprm);

+ trace_binfmt_misc_select(bprm, interpreter,
+ test_bit(MISC_FMT_BPF_BIT, &fmt->flags) ?
+ fmt->bpf_ops->name : "",
+ flags & MISC_FMT_INVOCATION_FLAGS);
+
/* No argv is built for a staged argument to land in. */
if ((flags & (MISC_FMT_LOADER | MISC_FMT_TRANSPARENT)) &&
bprm->bpf_interp_arg)

diff --git a/include/trace/events/binfmt_misc.h b/include/trace/events/binfmt_misc.h
new file mode 100644
--- /dev/null
+++ b/include/trace/events/binfmt_misc.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Tracepoint for binfmt_misc binary type handler dispatch.
+ *
+ * Fires once for every exec a binfmt_misc entry matches, after the
+ * interpreter and the invocation flags have been selected. Unlike
+ * sched_process_exec (which reports bprm->filename) and /proc/PID/exe
+ * (which a transparent dispatch sets to the binary), this reports the
+ * interpreter that actually runs, so observers can see through a
+ * transparent dispatch.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM binfmt_misc
+
+#if !defined(_TRACE_BINFMT_MISC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_BINFMT_MISC_H
+
+#include <linux/tracepoint.h>
+#include <linux/binfmts.h>
+
+TRACE_EVENT(binfmt_misc_select,
+
+ TP_PROTO(struct linux_binprm *bprm, const char *interp,
+ const char *handler, unsigned long flags),
+
+ TP_ARGS(bprm, interp, handler, flags),
+
+ TP_STRUCT__entry(
+ __string(filename, bprm->filename)
+ __string(interp, interp)
+ __string(handler, handler)
+ __field(unsigned long, flags)
+ __field(pid_t, pid)
+ ),
+
+ TP_fast_assign(
+ __assign_str(filename);
+ __assign_str(interp);
+ __assign_str(handler);
+ __entry->flags = flags;
+ __entry->pid = current->pid;
+ ),
+
+ TP_printk("pid=%d filename=%s interp=%s handler=%s flags=%#lx",
+ __entry->pid, __get_str(filename), __get_str(interp),
+ __get_str(handler), __entry->flags)
+);
+
+#endif /* _TRACE_BINFMT_MISC_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>