xref: /linux/Documentation/filesystems/failfs.rst (revision cd051cfe1e35a471fc2cdf6d32fae6ee23305ecb)
1.. SPDX-License-Identifier: GPL-2.0
2
3======
4failfs
5======
6
7failfs is a kernel-internal filesystem that fails every operation
8reaching it with ``EOPNOTSUPP``. It is the counterpart to nullfs. Where
9nullfs is permanently empty, failfs means "nothing is supported here".
10It cannot be mounted from userspace, nothing can be mounted on top of
11it. It cannot be cloned.
12
13The only way into it is the ``FD_FAILFS_ROOT`` file descriptor sentinel which
14is understood by ``fchdir(2)`` and ``fchroot(2)``.
15
16Semantics
17=========
18
19Every path walk of a component through failfs fails with
20``EOPNOTSUPP`` before that component is parsed, including ``.``.
21
22No path lookup can open the root, not even with ``O_PATH``.
23
24A process with its working directory in failfs fails every
25``AT_FDCWD``-relative lookup. As with any working directory that is
26unreachable from the process root, the ``getcwd(2)`` system call returns
27a path prefixed with ``(unreachable)``.
28
29A process with its root directory in failfs fails every absolute path
30lookup including absolute symlinks and the interpreter of dynamically
31linked binaries. In other words, this fails exec.
32
33Lookups anchored at explicit directory file descriptors keep working. It
34is the ``fs_struct`` equivalent of ``RESOLVE_BENEATH``. The process must
35anchor every lookup at a file descriptor it explicitly holds.
36
37Entering
38========
39
40``fchroot(FD_FAILFS_ROOT, 0)`` requires ``CAP_SYS_CHROOT`` in the
41caller's user namespace, mirroring ``chroot(2)``. Unprivileged callers
42may enter if all of the following hold:
43
44* ``no_new_privs`` is set: setuid binaries on regular mounts remain
45  reachable via inherited directory file descriptors and executing them
46  with an unusable root directory is the classic confused deputy.
47
48* The caller is not already chrooted: the root directory is what
49  confines ``..`` resolution and the failfs root can never be reached by
50  walking up a real mount tree, so moving the root of a chrooted task to
51  failfs would allow it to escape its chroot via ``openat(fd, "..")``.
52
53* The caller does not share its ``fs_struct``: ``no_new_privs`` is
54  checked on the calling thread, but the root lives in the ``fs_struct``.
55  A ``CLONE_FS`` sibling without ``no_new_privs`` could otherwise execute
56  a setuid binary with the failfs root, so entry requires ``fs->users ==
57  1``, the same restriction ``setns(2)`` applies for the mount and user
58  namespaces.
59
60Leaving
61=======
62
63Backing out is currently hard, but this is a property of the current
64implementation, not a guaranteed interface, and may be loosened later.
65For now a process that entered failfs counts as chrooted, so it cannot
66create user namespaces to regain ``CAP_SYS_CHROOT``, and ``chroot(2)``
67or ``fchroot(2)`` back out require ``CAP_SYS_CHROOT``. The remaining way
68out today is ``setns(2)`` with a mount namespace file descriptor, which
69requires ``CAP_SYS_ADMIN`` over the target mount namespace as well as
70``CAP_SYS_CHROOT`` and ``CAP_SYS_ADMIN`` in the caller's user namespace
71and resets both root and working directory. A process that holds no such
72file descriptor and restricts ``*chdir()``/``*chroot()``/``setns()`` via
73seccomp cannot currently get back out.
74