]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nstree: allow lookup solely based on inode
authorChristian Brauner <brauner@kernel.org>
Wed, 29 Oct 2025 12:20:27 +0000 (13:20 +0100)
committerChristian Brauner <brauner@kernel.org>
Mon, 3 Nov 2025 16:41:17 +0000 (17:41 +0100)
The namespace file handle struct nsfs_file_handle is uapi and userspace
is expressly allowed to generate file handles without going through
name_to_handle_at().

Allow userspace to generate a file handle where both the inode number
and the namespace type are zero and just pass in the unique namespace
id. The kernel uses the unified namespace tree to find the namespace and
open the file handle.

When the kernel creates a file handle via name_to_handle_at() it will
always fill in the type and the inode number allowing userspace to
retrieve core information.

Link: https://patch.msgid.link/20251029-work-namespace-nstree-listns-v4-14-2e6f823ebdc0@kernel.org
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/nsfs.c

index 0c35e4e54711b0782098512b00fb508b5d58b6f7..4a95a0a38f8673b8975c17378724d47ca6c19174 100644 (file)
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -496,15 +496,22 @@ static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
                return NULL;
        }
 
+       if (!fid->ns_id)
+               return NULL;
+       /* Either both are set or both are unset. */
+       if (!fid->ns_inum != !fid->ns_type)
+               return NULL;
+
        scoped_guard(rcu) {
                ns = ns_tree_lookup_rcu(fid->ns_id, fid->ns_type);
                if (!ns)
                        return NULL;
 
                VFS_WARN_ON_ONCE(ns->ns_id != fid->ns_id);
-               VFS_WARN_ON_ONCE(ns->ns_type != fid->ns_type);
 
-               if (ns->inum != fid->ns_inum)
+               if (fid->ns_inum && (fid->ns_inum != ns->inum))
+                       return NULL;
+               if (fid->ns_type && (fid->ns_type != ns->ns_type))
                        return NULL;
 
                /*