Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
	 Kees Cook <kees@kernel.org>,
	linux-mm@kvack.org, bpf@vger.kernel.org,
	 Jonathan Corbet <corbet@lwn.net>,
	Farid Zakaria <farid.m.zakaria@gmail.com>,
	 Daniel Borkmann <daniel@iogearbox.net>,
	Alexei Starovoitov <ast@kernel.org>,
	 jannh@google.com, mail@johnericson.me,
	 "Christian Brauner (Amutable)" <brauner@kernel.org>
Subject: [PATCH 0/9] binfmt_misc: bind interpreters to a bpf-backed entry
Date: Thu, 30 Jul 2026 15:34:02 +0200	[thread overview]
Message-ID: <20260730-work-binfmt_misc-preopen-v1-0-4a0b0da71f16@kernel.org> (raw)

A 'B' entry's load program hands the kernel an absolute path and
open_exec() resolves it at exec time in the mount namespace of whoever
runs the binary. So the handler names an interpreter but never gets to
say which file that is. Whoever controls the filesystem view of the exec
does.

Static entries have had the answer for a while. 'F' opens the file at
registration and every exec runs a clone of it. I can't just reuse it as
it stands. It pre-opens the one interpreter named in the register string
and a 'B' entry has no fixed interpreter. The program picks per exec,
and a qemu-user shaped handler wants one per guest architecture. So it
may want a whole set of them and that doesn't fit in a register string.

An entry is matchable the moment it is registered, so everything it
needs has to fit in that one write. Patch 1 adds a 'D' flag that creates
the entry disabled and splits a registration into create and activate:

    echo ':qemu:B::::qemu_user:D' > register
    echo '+aarch64 /usr/bin/qemu-aarch64' > qemu
    echo '+arm /usr/bin/qemu-arm' > qemu
    echo 1 > qemu

Each path is opened by its write, with the credentials the entry file was
opened with. Same open_exec() call, same place as 'F'. The program picks
one per exec with bpf_binprm_select_interp() and gets a clone of the
file. Nothing is resolved again, in any namespace.

A 'D' entry simply isn't hashed until that first '1', so the rcu
insertion that publishes the entry also publishes its interpreters and
the exec side needs no barriers. Reading the entry file doesn't take any
locks either. Bindings are rcu-published and the open file already pins
everything the read looks at. We use paths, not fds which makes the
config remain nice and static and can be shipped via /etc/binfmt.d.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
Christian Brauner (9):
      binfmt_misc: let a register string create an entry disabled
      selftests/exec: let binfmt_flag_supported() return a bool
      selftests/exec: test registering an entry disabled
      binfmt_misc: document registering an entry disabled
      selftests/exec: share the bpf handler preconditions
      binfmt_misc: carry pre-opened interpreters in struct binfmt_misc_interp
      binfmt_misc: let a 'B' entry bind its interpreters
      selftests/exec: test interpreters bound to a 'B' entry
      binfmt_misc: document interpreters bound by a 'B' entry

 Documentation/admin-guide/binfmt-misc.rst          |  75 +++-
 fs/binfmt_misc.c                                   | 459 +++++++++++++++++----
 fs/binfmt_misc_bpf.c                               |  75 +++-
 fs/exec.c                                          |   2 +
 include/linux/binfmt_misc.h                        |  39 +-
 include/linux/binfmts.h                            |   3 +
 tools/testing/selftests/exec/Makefile              |  11 +-
 tools/testing/selftests/exec/binfmt_bind_interp.c  |  14 +
 tools/testing/selftests/exec/binfmt_misc_bpf.c     | 306 ++++++++++++--
 tools/testing/selftests/exec/binfmt_misc_common.h  |  45 +-
 .../testing/selftests/exec/binfmt_misc_disabled.c  | 172 ++++++++
 .../selftests/exec/binfmt_misc_transparent.c       |   2 +-
 tools/testing/selftests/exec/interp_bind.bpf.c     |  76 ++++
 13 files changed, 1164 insertions(+), 115 deletions(-)
---
base-commit: 4bdcf682a476e8d9f52b2c5c01e998d70e45656c
change-id: 20260729-work-binfmt_misc-preopen-9653fb9d1d04



             reply	other threads:[~2026-07-30 13:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-30 13:34 Christian Brauner [this message]
2026-07-30 13:34 ` [PATCH 1/9] binfmt_misc: let a register string create an entry disabled Christian Brauner
2026-07-30 13:34 ` [PATCH 2/9] selftests/exec: let binfmt_flag_supported() return a bool Christian Brauner
2026-07-30 13:34 ` [PATCH 3/9] selftests/exec: test registering an entry disabled Christian Brauner
2026-07-30 13:34 ` [PATCH 4/9] binfmt_misc: document " Christian Brauner
2026-07-30 13:34 ` [PATCH 5/9] selftests/exec: share the bpf handler preconditions Christian Brauner
2026-07-30 13:34 ` [PATCH 6/9] binfmt_misc: carry pre-opened interpreters in struct binfmt_misc_interp Christian Brauner
2026-07-30 13:34 ` [PATCH 7/9] binfmt_misc: let a 'B' entry bind its interpreters Christian Brauner
2026-07-30 13:34 ` [PATCH 8/9] selftests/exec: test interpreters bound to a 'B' entry Christian Brauner
2026-07-30 13:34 ` [PATCH 9/9] binfmt_misc: document interpreters bound by " 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=20260730-work-binfmt_misc-preopen-v1-0-4a0b0da71f16@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