]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
alloc_path_pseudo(): make sure we don't end up with NORCU dentries for directories
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 27 Apr 2026 18:19:28 +0000 (14:19 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 5 Jun 2026 04:34:54 +0000 (00:34 -0400)
A lot of places relies upon directories never having NORCU dentries;
currently that property holds, but the proof is not straightforward
and rather brittle.

It's better to have that verified in the sole caller of d_alloc_pseudo(),
so that any future bugs in that direction were caught early.

That way we can be sure that
* current directory of any process is not NORCU
* root directory of any process is not NORCU
* starting point of any LOOKUP_RCU pathwalk is not NORCU
* dget_parent() can rely upon ->d_parent not being NORCU
* d_walk() and is_subdir() can rely upon the same
* alloc_file_pseudo() won't create multiple aliases for a directory
without having to go through a convoluted audit.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/file_table.c

index 16e52e7fc2ace855c7ad5364974e2e8c3c050925..108ba09fb402b90c251bd14750575edb4d07b78f 100644 (file)
@@ -402,6 +402,8 @@ static struct file *alloc_file(const struct path *path, int flags,
 static inline int alloc_path_pseudo(const char *name, struct inode *inode,
                                    struct vfsmount *mnt, struct path *path)
 {
+       if (WARN_ON_ONCE(S_ISDIR(inode->i_mode)))
+               return -EINVAL;
        path->dentry = d_alloc_pseudo(mnt->mnt_sb, &QSTR(name));
        if (!path->dentry)
                return -ENOMEM;