[PATCH RFC POC 1/4] exec: stash a bpf-selected interpreter in struct linux_binprm

From: Christian Brauner

Date: Tue Jul 07 2026 - 15:40:27 EST


The upcoming bpf-backed binfmt_misc handlers select the interpreter for
a binary programmatically at exec time. The selection runs before
load_misc_binary() has copied the binary path from bprm->interp into
the argument vector, so the selecting program cannot go through
bprm_change_interp() directly without clobbering argv[1].

Stage the selected path in the bprm instead. The bprm is exclusively
owned by the task doing the exec so no synchronization is needed. The
consumer frees and clears the field once the exec attempt that set it
is finished; free_bprm() covers all error paths.

Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
fs/exec.c | 1 +
include/linux/binfmts.h | 1 +
2 files changed, 2 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index b92fe7db176c..7c9e28f549a4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1418,6 +1418,7 @@ static void free_bprm(struct linux_binprm *bprm)
/* If a binfmt changed the interp, free it. */
if (bprm->interp != bprm->filename)
kfree(bprm->interp);
+ kfree(bprm->bpf_interp);
kfree(bprm->fdpath);
kfree(bprm);
}
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 2c77e383e737..0070d207d54f 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -65,6 +65,7 @@ struct linux_binprm {
of the time same as filename, but could be
different for binfmt_{misc,script} */
const char *fdpath; /* generated filename for execveat */
+ const char *bpf_interp; /* interpreter selected by a bpf handler */
unsigned interp_flags;
int execfd; /* File descriptor of the executable */
unsigned long exec;

--
2.53.0