Re: [PATCH] vfs: add FS_USERNS_DELEGATABLE flag and set it for NFS

From: Jeff Layton

Date: Mon Jun 08 2026 - 16:15:31 EST


On Thu, 2026-01-29 at 16:47 -0500, Jeff Layton wrote:
> Commit e1c5ae59c0f2 ("fs: don't allow non-init s_user_ns for filesystems
> without FS_USERNS_MOUNT") prevents the mount of any filesystem inside a
> container that doesn't have FS_USERNS_MOUNT set.
>
> This broke NFS mounts in our containerized environment. We have a daemon
> somewhat like systemd-mountfsd running in the init_ns. A process does a
> fsopen() inside the container and passes it to the daemon via unix
> socket.
>
> The daemon then vets that the request is for an allowed NFS server and
> performs the mount. This now fails because the fc->user_ns is set to the
> value in the container and NFS doesn't set FS_USERNS_MOUNT. We don't
> want to add FS_USERNS_MOUNT to NFS since that would allow the container
> to mount any NFS server (even malicious ones).
>
> Add a new FS_USERNS_DELEGATABLE flag, and enable it on NFS.
>
> Fixes: e1c5ae59c0f2 ("fs: don't allow non-init s_user_ns for filesystems without FS_USERNS_MOUNT")
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
> fs/nfs/fs_context.c | 8 ++++++--
> fs/super.c | 11 ++++++-----
> include/linux/fs.h | 1 +
> 3 files changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
> index b4679b7161b0968810e13f57c889052ea015bf56..128ebd48b4f4ba1c17e8b5b1b9dcefbd7a97db1a 100644
> --- a/fs/nfs/fs_context.c
> +++ b/fs/nfs/fs_context.c
> @@ -1768,7 +1768,9 @@ struct file_system_type nfs_fs_type = {
> .init_fs_context = nfs_init_fs_context,
> .parameters = nfs_fs_parameters,
> .kill_sb = nfs_kill_super,
> - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
> + .fs_flags = FS_RENAME_DOES_D_MOVE |
> + FS_BINARY_MOUNTDATA |
> + FS_USERNS_DELEGATABLE,
> };
> MODULE_ALIAS_FS("nfs");
> EXPORT_SYMBOL_GPL(nfs_fs_type);
> @@ -1780,7 +1782,9 @@ struct file_system_type nfs4_fs_type = {
> .init_fs_context = nfs_init_fs_context,
> .parameters = nfs_fs_parameters,
> .kill_sb = nfs_kill_super,
> - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
> + .fs_flags = FS_RENAME_DOES_D_MOVE |
> + FS_BINARY_MOUNTDATA |
> + FS_USERNS_DELEGATABLE,
> };
> MODULE_ALIAS_FS("nfs4");
> MODULE_ALIAS("nfs4");
> diff --git a/fs/super.c b/fs/super.c
> index 3d85265d14001d51524dbaec0778af8f12c048ac..b7f1bb2b679b43261fbdcd586971c551b85e8372 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -738,12 +738,13 @@ struct super_block *sget_fc(struct fs_context *fc,
> int err;
>
> /*
> - * Never allow s_user_ns != &init_user_ns when FS_USERNS_MOUNT is
> - * not set, as the filesystem is likely unprepared to handle it.
> - * This can happen when fsconfig() is called from init_user_ns with
> - * an fs_fd opened in another user namespace.
> + * Never allow s_user_ns != &init_user_ns when FS_USERNS_MOUNT or
> + * FS_USERNS_DELEGATABLE is not set, as the filesystem is likely
> + * unprepared to handle it. This can happen when fsconfig() is called
> + * from init_user_ns with an fs_fd opened in another user namespace.
> */
> - if (user_ns != &init_user_ns && !(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) {
> + if (user_ns != &init_user_ns &&
> + !(fc->fs_type->fs_flags & (FS_USERNS_MOUNT | FS_USERNS_DELEGATABLE))) {
> errorfc(fc, "VFS: Mounting from non-initial user namespace is not allowed");
> return ERR_PTR(-EPERM);
> }
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index a01621fa636a60764e1dfe83f2260caf50c4037e..94695ce5e25b5fbe4f321d5478172b8cb24e00d1 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2273,6 +2273,7 @@ struct file_system_type {
> #define FS_MGTIME 64 /* FS uses multigrain timestamps */
> #define FS_LBS 128 /* FS supports LBS */
> #define FS_POWER_FREEZE 256 /* Always freeze on suspend/hibernate */
> +#define FS_USERNS_DELEGATABLE 512 /* Can be mounted inside userns from outside */
> #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
> int (*init_fs_context)(struct fs_context *);
> const struct fs_parameter_spec *parameters;
>
> ---
> base-commit: 8dfce8991b95d8625d0a1d2896e42f93b9d7f68d
> change-id: 20260129-twmount-114ddfd43420
>
> Best regards,

Ping?

I just realized that this patch never made it into -next or a release.
Any chance we can get this into the coming v7.3 merge window? (although
it looks like we'll need to renumber the bit since
FS_USERNS_MOUNT_RESTRICTED has gone in since then.

Thanks,
--
Jeff Layton <jlayton@xxxxxxxxxx>