binfmt_misc: document loader substitution

Describe the L mode next to the transparent one.

Link: https://patch.msgid.link/20260721-work-bpf-binfmt_misc-ptinterp-v2-21-e57866e4ae0f@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-07-21 16:14:03 +02:00
parent 87c50a5855
commit bf9008534e

View File

@@ -260,6 +260,53 @@ direct execution is the address space layout. The interpreter occupies
the main-image position and the program lives in the mmap region.
Loader substitution
-------------------
The ``L`` flag turns the execution model around. Instead of running the
registered interpreter with the binary as its payload the kernel loads
the matched binary itself as the main image and substitutes the registered
interpreter for the loader named in the binary's ``PT_INTERP``.
Because the exec is native, there is no dispatch identity to
reconstruct and no contract the substitute has to implement. A stock
dynamic loader works unchanged. The argument vector is untouched,
credentials and ``AT_SECURE`` derive from the binary, there is no
``AT_EXECFD`` and no marker in the aux vector, the binary sits in the
main-image slot with the native brk placement so ``/proc/pid/maps``,
core dumps and perf mmap records have the native shape, and the
identity is already complete when ``PTRACE_EVENT_EXEC`` stops the
tracee. So launching under a debugger works, not just attaching. ``L``
entries are for ELF binaries of a native architecture. Foreign-arch
emulation and non-ELF payloads remain the domain of the classic and
transparent modes.
The override applies when the format that finally claims the file is
ELF with a ``PT_INTERP``. A matched binary without one or an
interpreter-less ``ET_DYN`` drops the override and runs natively. A file
claimed by another format - a ``#!`` script, say - is handled by that
format as if the entry had not matched. ``L`` is therefore not an
enforcement mechanism: it decides how a binary that asks for a loader is
run, it does not guarantee that everything matching the entry runs under
the substitute. A format that cannot consume the override at all instead
refuses the exec with ``ENOEXEC`` before the point of no return.
A wrong-architecture ELF fails the whole exec with ``ENOEXEC`` exactly
as if no entry had matched. A substitute that is not ELF of the right
architecture fails with ``ELIBBAD``. The usual ``PT_INTERP`` sanity
checks on the binary still apply. But the segment's content is otherwise
irrelevant.
``L`` rejects the classic-dispatch flags ``T``, ``P``, ``O`` and ``C``
at registration. ``F`` composes and is valuable: with it the substitute
is opened at registration time, so later mount namespace or path changes
cannot redirect it. Without it the substitute is opened when the binary
is executed, and the path is resolved in the mount namespace and root of
whoever runs the binary, which is why it has to be absolute. As with
``C``, register only trusted interpreters. The substituted loader runs
with credentials derived from the binary.
Hints
-----