]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nfsd: do not allow exporting of special kernel filesystems
authorAmir Goldstein <amir73il@gmail.com>
Thu, 29 Jan 2026 10:02:12 +0000 (11:02 +0100)
committerChristian Brauner <brauner@kernel.org>
Thu, 29 Jan 2026 16:26:30 +0000 (17:26 +0100)
pidfs and nsfs recently gained support for encode/decode of file handles
via name_to_handle_at(2)/open_by_handle_at(2).

These special kernel filesystems have custom ->open() and ->permission()
export methods, which nfsd does not respect and it was never meant to be
used for exporting those filesystems by nfsd.

Therefore, do not allow nfsd to export filesystems with custom ->open()
or ->permission() methods.

Fixes: b3caba8f7a34a ("pidfs: implement file handle support")
Fixes: 5222470b2fbb3 ("nsfs: support file handles")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://patch.msgid.link/20260129100212.49727-3-amir73il@gmail.com
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/nfsd/export.c
include/linux/exportfs.h

index 9d55512d0cc97fb51dec06db4709cb99ab3ad990..baaa18b878d780fb031a017b49c3b7a22fc1bf04 100644 (file)
@@ -427,7 +427,8 @@ static int check_export(const struct path *path, int *flags, unsigned char *uuid
         *       either a device number (so FS_REQUIRES_DEV needed)
         *       or an FSID number (so NFSEXP_FSID or ->uuid is needed).
         * 2:  We must be able to find an inode from a filehandle.
-        *       This means that s_export_op must be set.
+        *       This means that s_export_op must be set and comply with
+        *       the requirements for remote filesystem export.
         * 3: We must not currently be on an idmapped mount.
         */
        if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
@@ -437,8 +438,9 @@ static int check_export(const struct path *path, int *flags, unsigned char *uuid
                return -EINVAL;
        }
 
-       if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) {
-               dprintk("exp_export: export of invalid fs type.\n");
+       if (!exportfs_may_export(inode->i_sb->s_export_op)) {
+               dprintk("exp_export: export of invalid fs type (%s).\n",
+                       inode->i_sb->s_type->name);
                return -EINVAL;
        }
 
index 0660953c3fb768ef0ba2195df2c1400ec7709d8f..8bcdba28b406075ce82a4b1247b22ff2da88dd07 100644 (file)
@@ -338,6 +338,15 @@ static inline bool exportfs_can_decode_fh(const struct export_operations *nop)
        return nop && nop->fh_to_dentry;
 }
 
+static inline bool exportfs_may_export(const struct export_operations *nop)
+{
+       /*
+        * Do not allow nfs export for filesystems with custom ->open() or
+        * ->permission() ops, which nfsd does not respect (e.g. pidfs, nsfs).
+        */
+       return exportfs_can_decode_fh(nop) && !nop->open && !nop->permission;
+}
+
 static inline bool exportfs_can_encode_fh(const struct export_operations *nop,
                                          int fh_flags)
 {