Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: Farid Zakaria <farid.m.zakaria@gmail.com>,
	 linux-fsdevel@vger.kernel.org
Cc: Daniel Borkmann <daniel@iogearbox.net>,
	 Alexei Starovoitov <ast@kernel.org>, Kees Cook <kees@kernel.org>,
	 Alexander Viro <viro@zeniv.linux.org.uk>,
	Jan Kara <jack@suse.cz>,  Jonathan Corbet <corbet@lwn.net>,
	linux-mm@kvack.org, bpf@vger.kernel.org,  jannh@google.com,
	mail@johnericson.me,
	 "Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH 08/21] exec: add AT_FLAGS_TRANSPARENT_INTERP
Date: Mon, 20 Jul 2026 11:33:31 +0200	[thread overview]
Message-ID: <20260720-work-bpf-binfmt_misc-ptinterp-v1-8-ddb76c9a508e@kernel.org> (raw)
In-Reply-To: <20260720-work-bpf-binfmt_misc-ptinterp-v1-0-ddb76c9a508e@kernel.org>

A transparent binfmt_misc dispatch hands the binary to the interpreter
through AT_EXECFD and leaves the argument vector exactly as the caller
built it. The loader on the receiving end has to know which contract it
got.

On the classic 'O'/'C' entries the binary's path is spliced into the
argument vector and the loader consumes arguments. In transparent mode
nothing was spliced and argv belongs entirely to the program. This
cannot be inferred from AT_EXECFD alone. Raise a new AT_FLAGS bit
following the AT_FLAGS_PRESERVE_ARGV0 precedent added for qemu-user in
commit 2347961b11d4 ("binfmt_misc: pass binfmt_misc flags to the
interpreter").

The bit also announces that mm->exe_file names the binary rather than
the interpreter (added in the next commit). A loader that sees the bit
may finish the identity polish by fixing up AT_PHDR/AT_ENTRY/AT_BASE in
saved_auxv and fix the code/data markers via one uncapped PR_SET_MM_MAP
once it has mapped the binary. I've got glibc patches for this as well
but it's useful for any loader.

BINPRM_FLAGS_TRANSPARENT_INTERP carries the mode from binfmt_misc to
the ELF loaders. Both create_elf_tables() variants translate it into
the aux vector bit. Nothing sets the bprm flag yet.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 fs/binfmt_elf.c              | 5 ++++-
 fs/binfmt_elf_fdpic.c        | 5 ++++-
 include/linux/binfmts.h      | 4 ++++
 include/uapi/linux/binfmts.h | 7 +++++++
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 16a56b6b3f6c..e44230242f3a 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -254,7 +254,10 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
 	NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
 	NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
 	NEW_AUX_ENT(AT_BASE, interp_load_addr);
-	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+	/* Transparency preserves the whole argv, argv[0] included. */
+	if (bprm->interp_flags & BINPRM_FLAGS_TRANSPARENT_INTERP)
+		flags |= AT_FLAGS_TRANSPARENT_INTERP;
+	else if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
 		flags |= AT_FLAGS_PRESERVE_ARGV0;
 	NEW_AUX_ENT(AT_FLAGS, flags);
 	NEW_AUX_ENT(AT_ENTRY, e_entry);
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 7e3108489c83..3306d21ab738 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -645,7 +645,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
 	NEW_AUX_ENT(AT_PHENT,	sizeof(struct elf_phdr));
 	NEW_AUX_ENT(AT_PHNUM,	exec_params->hdr.e_phnum);
 	NEW_AUX_ENT(AT_BASE,	interp_params->elfhdr_addr);
-	if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
+	/* Transparency preserves the whole argv, argv[0] included. */
+	if (bprm->interp_flags & BINPRM_FLAGS_TRANSPARENT_INTERP)
+		flags |= AT_FLAGS_TRANSPARENT_INTERP;
+	else if (bprm->interp_flags & BINPRM_FLAGS_PRESERVE_ARGV0)
 		flags |= AT_FLAGS_PRESERVE_ARGV0;
 	NEW_AUX_ENT(AT_FLAGS,	flags);
 	NEW_AUX_ENT(AT_ENTRY,	exec_params->entry_addr);
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 03e1794b5cbb..d4f64d143d1a 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -93,6 +93,10 @@ struct linux_binprm {
 #define BINPRM_FLAGS_PRESERVE_ARGV0_BIT 3
 #define BINPRM_FLAGS_PRESERVE_ARGV0 (1 << BINPRM_FLAGS_PRESERVE_ARGV0_BIT)
 
+/* binfmt_misc dispatched to the interpreter transparently */
+#define BINPRM_FLAGS_TRANSPARENT_INTERP_BIT 4
+#define BINPRM_FLAGS_TRANSPARENT_INTERP (1 << BINPRM_FLAGS_TRANSPARENT_INTERP_BIT)
+
 /*
  * This structure defines the functions that are used to load the binary formats that
  * linux accepts.
diff --git a/include/uapi/linux/binfmts.h b/include/uapi/linux/binfmts.h
index c6f9450efc12..aafc07d78b80 100644
--- a/include/uapi/linux/binfmts.h
+++ b/include/uapi/linux/binfmts.h
@@ -22,4 +22,11 @@ struct pt_regs;
 #define AT_FLAGS_PRESERVE_ARGV0_BIT 0
 #define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
 
+/*
+ * The interpreter runs transparently: the argument vector and the exe
+ * link belong to the binary passed in AT_EXECFD.
+ */
+#define AT_FLAGS_TRANSPARENT_INTERP_BIT 1
+#define AT_FLAGS_TRANSPARENT_INTERP (1 << AT_FLAGS_TRANSPARENT_INTERP_BIT)
+
 #endif /* _UAPI_LINUX_BINFMTS_H */

-- 
2.53.0



  parent reply	other threads:[~2026-07-20  9:34 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20  9:33 [PATCH 00/21] binfmt_misc: transparent interpreters and PT_INTERP loader substitution Christian Brauner
2026-07-20  9:33 ` [PATCH 01/21] exec: do not act on a stale execfd request without an executable Christian Brauner
2026-07-20  9:33 ` [PATCH 02/21] docs, binfmt_misc: keep general usage out of the handler sections Christian Brauner
2026-07-20  9:33 ` [PATCH 03/21] binfmt_misc: table-drive the register string flags Christian Brauner
2026-07-20  9:33 ` [PATCH 04/21] binfmt_misc: normalize the per-exec invocation flags Christian Brauner
2026-07-20  9:33 ` [PATCH 05/21] binfmt_misc: split out entry_open_interpreter() Christian Brauner
2026-07-20  9:33 ` [PATCH 06/21] binfmt_misc: split out build_interp_argv() Christian Brauner
2026-07-20  9:33 ` [PATCH 07/21] exec: release the replaced file with do_close_execat() Christian Brauner
2026-07-20  9:33 ` Christian Brauner [this message]
2026-07-20  9:33 ` [PATCH 09/21] exec: label mm->exe_file with the binary for a transparent dispatch Christian Brauner
2026-07-20  9:33 ` [PATCH 10/21] binfmt_misc: add transparent interpreter dispatch Christian Brauner
2026-07-20  9:33 ` [PATCH 11/21] binfmt_misc: add a static transparent flag 'T' Christian Brauner
2026-07-20  9:33 ` [PATCH 12/21] binfmt_misc: let a bpf handler run the interpreter transparently Christian Brauner
2026-07-20  9:33 ` [PATCH 13/21] selftests/exec: convert the binfmt_misc bpf test to the kselftest harness Christian Brauner
2026-07-20  9:33 ` [PATCH 14/21] selftests/exec: test the transparent binfmt_misc mode Christian Brauner
2026-07-20  9:33 ` [PATCH 15/21] binfmt_misc: document the transparent identity contract Christian Brauner
2026-07-20  9:33 ` [PATCH 16/21] exec: carry a PT_INTERP substitute in struct linux_binprm Christian Brauner
2026-07-20  9:33 ` [PATCH 17/21] binfmt_elf: consume a stashed PT_INTERP substitute Christian Brauner
2026-07-20  9:33 ` [PATCH 18/21] binfmt_misc: add the 'L' loader substitution flag Christian Brauner
2026-07-20  9:33 ` [PATCH 19/21] binfmt_misc: let a bpf handler request loader substitution Christian Brauner
2026-07-20  9:33 ` [PATCH 20/21] selftests/exec: test binfmt_misc " Christian Brauner
2026-07-20  9:33 ` [PATCH 21/21] binfmt_misc: document " Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260720-work-bpf-binfmt_misc-ptinterp-v1-8-ddb76c9a508e@kernel.org \
    --to=brauner@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=farid.m.zakaria@gmail.com \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=kees@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mail@johnericson.me \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox