Ynt: Re: [RFC PATCH] binfmt_misc: add binfmt_misc_select tracepoint

From: BoxStrikesTeam

Date: Tue Oct 27 2026 - 17:02:39 EST


Thank you! Steve, for your suggestions.

I’ll take a look at the suggested fixes for the patch tomorrow. The main issue I ran into was that Proton Mail’s SMTP submission setup requires a paid plan, which caused me quite a bit of trouble. That’s why I’ve included the patch as an attachment for now.

It seems that Yandex Mail doesn’t have the same limitation. Once I’ve prepared version 2 of the patch, I’ll send it to you using Yandex Mail.

Thanks again for your help and suggestions!



Proton Mail güvenli e-posta ile gönderildi.

Steven Rostedt <rostedt@xxxxxxxxxxx>, 26 Ekim 2026 Pazartesi saat 23:28 tarihinde şunu yazdı:

>
> You shouldn't attach patches but inline them. Yeah, I know a lot of email
> clients can't handle that. But claws-mail can! (and it can also reply to
> attachments like they were inlined ;-) ).
>
> I'll let others comment on whether or not this patch is needed, but I'll
> comment on the tracing side of things.
>
>
> On Mon, 26 Oct 2026 20:17:26 +0000
> BoxStrikesTeam <BoxStrikesTeam@xxxxxxxxx> wrote:
>
> > 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);
>
> Logic like the above should be done in the trace event itself. Not in the
> code path. That is, pass in fmt and 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)
>
> Then here you would have:
>
> __string(handler, test_bit(MISC_FMT_BPF_BIT, &fmt->flags) ?
> fmt->bpf_ops->name : "")
>
>
> > + __field(unsigned long, flags)
> > + __field(pid_t, pid)
> > + ),
> > +
> > + TP_fast_assign(
> > + __assign_str(filename);
> > + __assign_str(interp);
> > + __assign_str(handler);
> > + __entry->flags = flags;
>
> and here:
>
> __entry->flags = flags & MISC_FMT_INVOCATION_FLAGS;
>
> -- Steve
>
>
> > + __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>
>
>