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 2/7] fs: add FD_FAILFS_ROOT and support it in fchdir()
Date: Thu, 23 Jul 2026 13:30:21 +0200 [thread overview]
Message-ID: <20260723-work-failfs-v1-2-3f69b9a9e958@kernel.org> (raw)
In-Reply-To: <20260723-work-failfs-v1-0-3f69b9a9e958@kernel.org>
Add a new file descriptor sentinel FD_FAILFS_ROOT following
FD_PIDFS_ROOT and FD_NSFS_ROOT and teach fchdir() to accept it. A
process calling fchdir(FD_FAILFS_ROOT) moves its working directory
into failfs. Every AT_FDCWD-relative lookup afterwards fails with
EOPNOTSUPP including "." and ".." and getcwd() reports the working
directory as unreachable from the process root by returning a path
prefixed with "(unreachable)". Lookups relative to explicit directory
file descriptors are unaffected.
The sentinel is the only way in. No privilege or gating is required.
Setting the working directory to a directory in which every operation
fails grants nothing and loses nothing that closing file descriptors
couldn't lose. An unlinked working directory behaves the same way today
modulo errno. The working directory also plays no role in confining ".."
resolution so no boundary is weakened.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
fs/failfs.c | 11 +++++++++++
fs/internal.h | 1 +
fs/open.c | 5 ++++-
include/uapi/linux/fcntl.h | 1 +
4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/failfs.c b/fs/failfs.c
index f9d4ba791928..f37e6af9c03c 100644
--- a/fs/failfs.c
+++ b/fs/failfs.c
@@ -3,6 +3,7 @@
#include <linux/fs.h>
#include <linux/fs/super_types.h>
#include <linux/fs_context.h>
+#include <linux/fs_struct.h>
#include <linux/magic.h>
#include <linux/mount.h>
@@ -124,6 +125,16 @@ static int failfs_init_fs_context(struct fs_context *fc)
return 0;
}
+int failfs_current_chdir(void)
+{
+ struct path path;
+
+ failfs_get_root(&path);
+ set_fs_pwd(current->fs, &path);
+ path_put(&path);
+ return 0;
+}
+
static struct file_system_type failfs_fs_type = {
.name = "failfs",
.init_fs_context = failfs_init_fs_context,
diff --git a/fs/internal.h b/fs/internal.h
index b6d38a5794eb..b3c88d999dec 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -364,3 +364,4 @@ void pidfs_get_root(struct path *path);
void nsfs_get_root(struct path *path);
void failfs_get_root(struct path *path);
void __init failfs_init(void);
+int failfs_current_chdir(void);
diff --git a/fs/open.c b/fs/open.c
index 408925d7bd0b..56b6032d4d81 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -570,9 +570,12 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
SYSCALL_DEFINE1(fchdir, unsigned int, fd)
{
- CLASS(fd_raw, f)(fd);
int error;
+ if ((int)fd == FD_FAILFS_ROOT)
+ return failfs_current_chdir();
+
+ CLASS(fd_raw, f)(fd);
if (fd_empty(f))
return -EBADF;
diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h
index aadfbf6e0cb3..e43e3de3e9ee 100644
--- a/include/uapi/linux/fcntl.h
+++ b/include/uapi/linux/fcntl.h
@@ -124,6 +124,7 @@ struct delegation {
#define FD_PIDFS_ROOT -10002 /* Root of the pidfs filesystem */
#define FD_NSFS_ROOT -10003 /* Root of the nsfs filesystem */
+#define FD_FAILFS_ROOT -10004 /* Root of the failfs filesystem */
#define FD_INVALID -10009 /* Invalid file descriptor: -10000 - EBADF = -10009 */
/* Generic flags for the *at(2) family of syscalls. */
--
2.53.0
next prev parent reply other threads:[~2026-07-23 11:30 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 ` Christian Brauner [this message]
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 ` [PATCH RFC 7/7] Documentation: add failfs documentation Christian Brauner
2026-07-23 14:04 ` 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-2-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.