All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org, Andy Lutomirski <luto@kernel.org>,
	 Jann Horn <jannh@google.com>
Cc: John Ericson <mail@johnericson.me>,
	linux-api@vger.kernel.org,  "H. Peter Anvin" <hpa@zytor.com>,
	Kees Cook <kees@kernel.org>,
	 Farid Zakaria <farid.m.zakaria@gmail.com>,
	 Alexander Viro <viro@zeniv.linux.org.uk>,
	 Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
	 linux-kernel@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
	 linux-doc@vger.kernel.org
Subject: [PATCH RFC 7/7] Documentation: add failfs documentation
Date: Thu, 23 Jul 2026 13:30:26 +0200	[thread overview]
Message-ID: <20260723-work-failfs-v1-7-3f69b9a9e958@kernel.org> (raw)
In-Reply-To: <20260723-work-failfs-v1-0-3f69b9a9e958@kernel.org>

Document the failfs semantics, the FD_FAILFS_ROOT sentinel, the
fchroot() entry requirements, and the ways back out.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 Documentation/filesystems/failfs.rst | 64 ++++++++++++++++++++++++++++++++++++
 Documentation/filesystems/index.rst  |  1 +
 2 files changed, 65 insertions(+)

diff --git a/Documentation/filesystems/failfs.rst b/Documentation/filesystems/failfs.rst
new file mode 100644
index 000000000000..46d91525916b
--- /dev/null
+++ b/Documentation/filesystems/failfs.rst
@@ -0,0 +1,64 @@
+.. 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 a 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 ``.``.
+
+The root itself cannot be opened at all 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 both 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, "..")``.
+
+Leaving
+=======
+
+A process that entered failfs counts as chrooted. It cannot create user
+namespaces to regain ``CAP_SYS_CHROOT``, and ``chroot(2)`` or
+``fchroot(2)`` back out require ``CAP_SYS_CHROOT``. The only other exit
+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 has thrown away the key.
diff --git a/Documentation/filesystems/index.rst b/Documentation/filesystems/index.rst
index 1f71cf159547..734a45e51667 100644
--- a/Documentation/filesystems/index.rst
+++ b/Documentation/filesystems/index.rst
@@ -91,6 +91,7 @@ Documentation for filesystem implementations.
    ext3
    ext4/index
    f2fs
+   failfs
    gfs2/index
    hfs
    hfsplus

-- 
2.53.0


  parent reply	other threads:[~2026-07-23 11:31 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 11:30 [PATCH RFC 0/7] fs: add failfs Christian Brauner
2026-07-23 11:30 ` [PATCH RFC 1/7] " Christian Brauner
2026-07-23 11:30 ` [PATCH RFC 2/7] fs: add FD_FAILFS_ROOT and support it in fchdir() Christian Brauner
2026-07-23 11:30 ` [PATCH RFC 3/7] fs: add fchroot() Christian Brauner
2026-07-23 11:30 ` [PATCH RFC 4/7] fs: support FD_FAILFS_ROOT in fchroot() Christian Brauner
2026-07-23 12:49   ` Andy Lutomirski
2026-07-23 13:01     ` Christian Brauner
2026-07-23 13:50       ` Andy Lutomirski
2026-07-23 14:35         ` Christian Brauner
2026-07-23 16:59           ` Andy Lutomirski
2026-07-23 14:42     ` Jann Horn
2026-07-23 14:07   ` Jann Horn
2026-07-23 16:56     ` Andy Lutomirski
2026-07-23 11:30 ` [PATCH RFC 5/7] arch: hookup fchroot() system call Christian Brauner
2026-07-23 11:30 ` [PATCH RFC 6/7] selftests/filesystems: add failfs selftests Christian Brauner
2026-07-23 11:30 ` Christian Brauner [this message]
2026-07-23 14:04   ` [PATCH RFC 7/7] Documentation: add failfs documentation Miquel Sabaté Solà
2026-07-23 12:53 ` [PATCH RFC 0/7] fs: add failfs Andy Lutomirski

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=20260723-work-failfs-v1-7-3f69b9a9e958@kernel.org \
    --to=brauner@kernel.org \
    --cc=corbet@lwn.net \
    --cc=farid.m.zakaria@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=kees@kernel.org \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.