# Conflicts:
#	fs/ext2/xattr.c
#	fs/gfs2/glock.c
This commit is contained in:
Mark Brown
2026-07-31 13:45:17 +01:00
303 changed files with 9317 additions and 3257 deletions
+238 -3
View File
@@ -26,7 +26,8 @@ Here is what the fields mean:
name below ``/proc/sys/fs/binfmt_misc``; cannot contain slashes ``/`` for
obvious reasons.
- ``type``
is the type of recognition. Give ``M`` for magic and ``E`` for extension.
is the type of recognition. Give ``M`` for magic, ``E`` for extension and
``B`` for a bpf-backed handler (see below).
- ``offset``
is the offset of the magic/mask in the file, counted in bytes. This
defaults to 0 if you omit it (i.e. you write ``:name:type::magic...``).
@@ -48,7 +49,8 @@ Here is what the fields mean:
filename extension matching.
- ``interpreter``
is the program that should be invoked with the binary as first
argument (specify the full path)
argument (specify the full path). For ``B`` entries this field
carries the name of the bpf handler instead (see below).
- ``flags``
is an optional field that controls several aspects of the invocation
of the interpreter. It is a string of capital letters, each controls a
@@ -88,6 +90,32 @@ Here is what the fields mean:
emulation is installed and uses the opened image to spawn the
emulator, meaning it is always available once installed,
regardless of how the environment changes.
``T`` - transparent
Run the interpreter transparently. The binary is handed to
the interpreter through ``AT_EXECFD`` (``T`` implies ``O``),
the argument vector is left exactly as the caller built it
and the kernel labels ``/proc/pid/exe`` with the binary
instead of the interpreter. The interpreter has to load the
binary from ``AT_EXECFD`` and follow the
``AT_FLAGS_TRANSPARENT_INTERP`` contract. Combining ``T``
with ``P`` is rejected: transparency preserves the whole
argument vector, argv[0] included.
``L`` - loader substitution
Do not run the interpreter on the binary at all: load the
binary itself as a fully native exec and substitute the
interpreter for the loader named in the binary's
``PT_INTERP``. See the "Loader substitution" section
below. ``L`` rejects ``T``, ``P``, ``O`` and ``C``;
``F`` composes.
``D`` - registered disabled
The entry is created disabled instead of being matchable at
once, and has to be enabled by writing ``1`` to its file
before it dispatches anything. This splits a registration
into creating the entry and activating it, leaving room to
configure it in between - which is what a ``B`` entry that
binds interpreters needs; see the bpf section below. The flag
is spent on the registration and is not read back: what an
entry file reports afterwards is whether it is enabled.
There are some restrictions:
@@ -96,6 +124,11 @@ There are some restrictions:
- the magic must reside in the first 128 bytes of the file, i.e.
offset+size(magic) has to be less than 128
- the interpreter string may not exceed 127 characters
- an interpreter used with ``C`` or ``L`` but without ``F`` has to be
named by an absolute path. It is opened when the binary is executed, so
a relative one would be resolved against the working directory of
whoever runs the binary
To use binfmt_misc you have to mount it first. You can mount it with
``mount -t binfmt_misc none /proc/sys/fs/binfmt_misc`` command, or you can add
@@ -133,7 +166,209 @@ or 1 (to enable) to ``/proc/sys/fs/binfmt_misc/status`` or
Catting the file tells you the current status of ``binfmt_misc/the_entry``.
You can remove one entry or all entries by echoing -1 to ``/proc/.../the_name``
or ``/proc/sys/fs/binfmt_misc/status``.
or ``/proc/sys/fs/binfmt_misc/status``. A single entry can also be removed
by simply unlinking (``rm``) ``/proc/.../the_name``.
bpf-backed handlers
-------------------
With ``CONFIG_BINFMT_MISC_BPF`` both the matching and the interpreter
selection can be delegated to bpf programs. A handler is an instance of the
``binfmt_misc_ops`` struct_ops with a ``match`` and a ``load`` program and a
``name``. Once the struct_ops map is registered the handler can be activated
with a ``B`` entry that references it by name in the ``interpreter`` field
and carries neither offset, magic, nor mask::
echo ':qemu:B::::my_handler:' > register
Both programs receive the ``linux_binprm`` of the binary and both can
sleep. The ``match`` program decides whether the handler applies: it is
consulted during the entry walk exactly like magic and extension matching,
in the same registration order with the same first-match-wins semantics.
Unlike static matching it is not limited to the prefetched first bytes of
the file in ``bprm->buf``: it can read the file, e.g. to parse ELF program
headers whose data sits at arbitrary offsets. It only decides, though: the
selection kfuncs below are rejected in it. The ``load`` program of the
matched handler then selects the interpreter: it can equally read the file
and derive the interpreter from the binary's location. It selects the
interpreter by calling the ``bpf_binprm_set_interp()`` kfunc with an
absolute path and returning ``0``. A match is committed: a failing
``load`` fails the exec with its error instead of falling through to later
entries; ``-ENOEXEC`` lets the remaining binary formats have a go. A path
selected this way is opened with the credentials of the task doing the
exec, exactly as a statically registered interpreter without ``F`` would
be.
An entry can instead bind the interpreters its handler may use, so that no
path is resolved at exec time at all. An entry registered with ``D`` is not
matchable yet, which is what leaves it open to being given them, one
``+name path`` write at a time::
echo ':qemu:B::::my_handler:D' > register
echo '+aarch64 /usr/bin/qemu-aarch64' > qemu
echo '+arm /usr/bin/qemu-arm' > qemu
echo 1 > qemu
Each path is opened during its write, in the writing process's context and
with the credentials the entry file was opened with, exactly the way ``F``
pre-opens a static entry's interpreter; the paths must be absolute. The
path is everything past the first space, so there is nothing it cannot
express, and no interpreter has to fit in a register string. An entry
binds at most 100 interpreters; a write past that is refused with
``-ENOSPC``. To bind a file that has no path of its own - already
unlinked, a ``memfd``, or reachable only in another mount namespace -
open it and write ``/proc/self/fd/N``.
The ``load`` program then selects one per exec by name with the
``bpf_binprm_select_interp()`` kfunc, and every exec runs a clone of the
file that was opened. The path decides which file is bound and nothing
else: it is not resolved again, in any namespace, so what it holds later -
or what it holds in the namespace of whoever runs the binary - no longer
decides anything.
Enabling the entry ends this. Its interpreters are read at exec time with
nothing but a reference held on the entry, so an entry that has ever been
matchable can never have its set changed again: the first ``1`` seals it,
from then on ``+`` is refused with ``-EBUSY``, and an entry registered
without ``D`` is sealed from the start. Binding a name twice is refused
with ``-EEXIST``.
Selection is by name so that the configuration and the program need not
agree on an order, and so that a handler is not tied to where a distribution
puts its interpreters. A name is a single word of printable ASCII, at most
32 characters; a name the entry did not bind gives the program ``-ENOENT``,
which it can act on or return. The interpreter runs under the path it was
registered under, and the entry reports what it bound::
$ cat /proc/sys/fs/binfmt_misc/qemu
enabled
bpf my_handler
bpf-interpreter aarch64 /usr/bin/qemu-aarch64
bpf-interpreter arm /usr/bin/qemu-arm
flags:
The path reported is the one the interpreter was bound under, which named
the file at that moment; it is not re-resolved, so it is a record of what
was bound rather than a promise about what that path holds now.
The ``load`` program can also pass a single argument to the interpreter with
the ``bpf_binprm_set_interp_arg()`` kfunc. It is inserted between the
interpreter and the binary, exactly like the optional argument of a ``#!``
interpreter line, e.g. for a handler that resolves ``$ORIGIN`` in a script's
``#!`` path and needs to preserve the argument that followed it.
The invocation flags a static entry fixes at registration - ``P``, ``C``,
``O``, ``T`` and ``L`` - are per-exec choices for a bpf handler, made by the
``load`` program with the ``bpf_binprm_set_flags()`` kfunc, so a single
handler can decide them differently for each binary it handles:
- ``BPF_BINPRM_PRESERVE_ARGV0`` keeps the caller's ``argv[0]`` (the ``P``
flag).
- ``BPF_BINPRM_CREDENTIALS`` computes credentials from the binary (the ``C``
flag), bounded to user namespaces that map the binary's owner just like
any other setuid exec.
- ``BPF_BINPRM_EXECFD`` opens the binary on the interpreter's behalf and
passes it through the ``AT_EXECFD`` aux vector entry (the ``O`` flag), so
the interpreter can run binaries it could not open by path.
- ``BPF_BINPRM_TRANSPARENT`` runs the interpreter transparently (the ``T``
flag): the binary is handed over through ``AT_EXECFD`` as
with ``BPF_BINPRM_EXECFD``, but the argument vector is also left as the
caller passed it. An interpreter that loads the binary from ``AT_EXECFD``
then appears in ``argv[0]`` and ``/proc/pid/cmdline`` as a direct
execution of the binary. ``BPF_BINPRM_PRESERVE_ARGV0`` and a staged
interpreter argument are rejected in combination with it, just as ``P``
is with ``T``. It also lets a handler
run a binary passed as an inaccessible ``O_CLOEXEC`` file descriptor to
``execveat()``, which a path-splicing dispatch cannot: the interpreter
has no path by which to open it.
- ``BPF_BINPRM_LOADER`` substitutes the interpreter for the binary's
``PT_INTERP`` and runs the binary as a fully native exec (the ``L``
flag). It excludes the other flags and a staged interpreter argument.
Because these are program choices, a ``B`` entry carries no invocation
flags in the register string; ``F`` has none to spell for it either, since
the interpreters it binds already pre-open what ``F`` would. The
registration directive ``D`` is the exception: it decides how the entry
starts out, not how the interpreter is invoked.
Handlers are looked up in the user namespace the struct_ops map was
registered in, falling back to ancestor namespaces, mirroring how
binfmt_misc instances themselves are looked up. The entry keeps the handler
alive; deleting the struct_ops map only prevents new activations.
Transparent interpreters
------------------------
With the ``T`` flag or ``BPF_BINPRM_TRANSPARENT`` the dispatch is invisible
to the resulting process. The argument vector is left exactly as the caller
built it. The binary is passed through ``AT_EXECFD``. The kernel also labels
``/proc/pid/exe`` correctly. The binary's file is write-denied while the
process runs and the interpreter's is not, exactly as if the binary had been
executed directly. A transparent entry does not change how credentials are
derived. As
with any other entry, set*id bits of the binary are only honored with ``C`` (or
``BPF_BINPRM_CREDENTIALS``).
The interpreter has to be built for this contract. The kernel announces it
with ``AT_FLAGS_TRANSPARENT_INTERP`` in the ``AT_FLAGS`` aux vector entry
next to ``AT_EXECFD``. The argument vector belongs entirely to the program,
nothing was spliced in, so the interpreter doesn't consume arguments and
simply loads the program from the descriptor. The bit is also the loader's
license to finish the identity. After mapping the program it may retarget the
``AT_PHDR``/``AT_ENTRY``/``AT_BASE`` entries of ``/proc/pid/auxv`` and the
code/data statistics markers via one ``PR_SET_MM_MAP`` which completes
what attaching debuggers observe. What remains visibly different from a
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
+73
View File
@@ -0,0 +1,73 @@
.. SPDX-License-Identifier: GPL-2.0
======
failfs
======
failfs is a kernel-internal filesystem that fails every operation
reaching it with ``EOPNOTSUPP``. It is the counterpart to nullfs. Where
nullfs is permanently empty, failfs means "nothing is supported here".
It cannot be mounted from userspace, nothing can be mounted on top of
it. It cannot be cloned.
The only way into it is the ``FD_FAILFS_ROOT`` file descriptor sentinel which
is understood by ``fchdir(2)`` and ``fchroot(2)``.
Semantics
=========
Every path walk of a component through failfs fails with
``EOPNOTSUPP`` before that component is parsed, including ``.``.
No path lookup can open the root, not even with ``O_PATH``.
A process with its working directory in failfs fails every
``AT_FDCWD``-relative lookup. As with any working directory that is
unreachable from the process root, the ``getcwd(2)`` system call returns
a path prefixed with ``(unreachable)``.
A process with its root directory in failfs fails every absolute path
lookup including absolute symlinks and the interpreter of dynamically
linked binaries. In other words, this fails exec.
Lookups anchored at explicit directory file descriptors keep working. It
is the ``fs_struct`` equivalent of ``RESOLVE_BENEATH``. The process must
anchor every lookup at a file descriptor it explicitly holds.
Entering
========
``fchroot(FD_FAILFS_ROOT, 0)`` requires ``CAP_SYS_CHROOT`` in the
caller's user namespace, mirroring ``chroot(2)``. Unprivileged callers
may enter if all of the following hold:
* ``no_new_privs`` is set: setuid binaries on regular mounts remain
reachable via inherited directory file descriptors and executing them
with an unusable root directory is the classic confused deputy.
* The caller is not already chrooted: the root directory is what
confines ``..`` resolution and the failfs root can never be reached by
walking up a real mount tree, so moving the root of a chrooted task to
failfs would allow it to escape its chroot via ``openat(fd, "..")``.
* The caller does not share its ``fs_struct``: ``no_new_privs`` is
checked on the calling thread, but the root lives in the ``fs_struct``.
A ``CLONE_FS`` sibling without ``no_new_privs`` could otherwise execute
a setuid binary with the failfs root, so entry requires ``fs->users ==
1``, the same restriction ``setns(2)`` applies for the mount and user
namespaces.
Leaving
=======
Backing out is currently hard, but this is a property of the current
implementation, not a guaranteed interface, and may be loosened later.
For now a process that entered failfs counts as chrooted, so it cannot
create user namespaces to regain ``CAP_SYS_CHROOT``, and ``chroot(2)``
or ``fchroot(2)`` back out require ``CAP_SYS_CHROOT``. The remaining way
out today is ``setns(2)`` with a mount namespace file descriptor, which
requires ``CAP_SYS_ADMIN`` over the target mount namespace as well as
``CAP_SYS_CHROOT`` and ``CAP_SYS_ADMIN`` in the caller's user namespace
and resets both root and working directory. A process that holds no such
file descriptor and restricts ``*chdir()``/``*chroot()``/``setns()`` via
seccomp cannot currently get back out.
+1
View File
@@ -91,6 +91,7 @@ Documentation for filesystem implementations.
ext3
ext4/index
f2fs
failfs
gfs2/index
hfs
hfsplus
+1 -1
View File
@@ -61,7 +61,7 @@ inode_operations
prototypes::
int (*create) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t, bool);
int (*create) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
+16
View File
@@ -347,6 +347,22 @@ The resulting access permissions should be the same. The difference is in
the time of copy (on-demand vs. up-front).
Idmapped mounts
---------------
The overlay mount itself can be turned into an idmapped mount by applying an
idmapping to it with mount_setattr(2) and MOUNT_ATTR_IDMAP, just like for
other filesystems that support idmapped mounts.
The mount idmapping only changes how ownership and permissions of the overlay
inodes are presented to and interpreted for the caller. It does not change
how overlayfs accesses the underlying layers: those are still accessed with
the stashed mounter's credentials through their own mounts, which may
themselves be idmapped. The overlay mount idmapping and any layer idmapping
compose, an underlying id is first mapped according to the relevant layer
idmapping and then according to the overlay mount idmapping.
Multiple lower layers
---------------------
+9 -1
View File
@@ -1173,7 +1173,7 @@ these conditions don't require explicit checks:
- if LOOKUP_CREATE is NOT given, then the dentry won't be negative,
ERR_PTR(-ENOENT) is returned instead
- if LOOKUP_EXCL IS given, then the dentry won't be positive,
ERR_PTR(-EEXIST) is rreturned instread
ERR_PTR(-EEXIST) is returned instead
LOOKUP_EXCL now means "target must not exist". It can be combined with
LOOK_CREATE or LOOKUP_RENAME_TARGET.
@@ -1401,3 +1401,11 @@ as with d_dispose_if_unused() these are not trivial; with this variant
of API it's more explicit, since grabbing ->d_lock is caller-side, but
d_dispose_if_unused() had all the same issues. It's a low-level primitive;
use only if you have no alternative.
---
**mandatory**
The .create inode_operation no longer receives the 'excl' arg. It must
always assume the file does not already exist. If the filesystem needs
to be involved in non-exclusive create, it should provide atomic_open.
+1 -1
View File
@@ -415,7 +415,7 @@ As of kernel 2.6.22, the following members are defined:
.. code-block:: c
struct inode_operations {
int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, umode_t, bool);
int (*create) (struct mnt_idmap *, struct inode *,struct dentry *, umode_t);
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
-5
View File
@@ -9494,11 +9494,6 @@ L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/fbdev/efifb.c
EFS FILESYSTEM
S: Orphan
W: http://aeschi.ch.eu.org/efs/
F: fs/efs/
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
L: netdev@vger.kernel.org
S: Orphan
+1
View File
@@ -511,3 +511,4 @@
579 common file_setattr sys_file_setattr
580 common listns sys_listns
581 common rseq_slice_yield sys_rseq_slice_yield
582 common fchroot sys_fchroot
+1
View File
@@ -486,3 +486,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
+1
View File
@@ -483,3 +483,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
+1
View File
@@ -471,3 +471,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
@@ -477,3 +477,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
@@ -410,3 +410,4 @@
469 n32 file_setattr sys_file_setattr
470 n32 listns sys_listns
471 n32 rseq_slice_yield sys_rseq_slice_yield
472 n32 fchroot sys_fchroot
@@ -386,3 +386,4 @@
469 n64 file_setattr sys_file_setattr
470 n64 listns sys_listns
471 n64 rseq_slice_yield sys_rseq_slice_yield
472 n64 fchroot sys_fchroot
@@ -459,3 +459,4 @@
469 o32 file_setattr sys_file_setattr
470 o32 listns sys_listns
471 o32 rseq_slice_yield sys_rseq_slice_yield
472 o32 fchroot sys_fchroot
+1
View File
@@ -470,3 +470,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
+1
View File
@@ -562,3 +562,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 nospu rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
+1
View File
@@ -398,3 +398,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot
+1
View File
@@ -475,3 +475,4 @@
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
472 common fchroot sys_fchroot

Some files were not shown because too many files have changed in this diff Show More