diff options
author | Christian Brauner <[email protected]> | 2024-09-06 18:22:22 +0200 |
---|---|---|
committer | Linus Torvalds <[email protected]> | 2024-09-06 11:08:58 -0700 |
commit | 4e32c25b58b945f976435bbe51f39b32d714052e (patch) | |
tree | 3fbe16437b77046889ff6aa620f74acb2c66689e | |
parent | b831f83e40a24f07c8dcba5be408d93beedc820f (diff) |
libfs: fix get_stashed_dentry()
get_stashed_dentry() tries to optimistically retrieve a stashed dentry
from a provided location. It needs to ensure to hold rcu lock before it
dereference the stashed location to prevent UAF issues. Use
rcu_dereference() instead of READ_ONCE() it's effectively equivalent
with some lockdep bells and whistles and it communicates clearly that
this expects rcu protection.
Link: https://lore.kernel.org/r/20240906-vfs-hotfix-5959800ffa68@brauner
Fixes: 07fd7c329839 ("libfs: add path_from_stashed()")
Reported-by: [email protected]
Fixes: [email protected]
Reported-by: [email protected]
Fixes: [email protected]
Signed-off-by: Christian Brauner <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r-- | fs/libfs.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/libfs.c b/fs/libfs.c index 02602d00939e..b64b4c44cfea 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -2117,12 +2117,12 @@ struct timespec64 simple_inode_init_ts(struct inode *inode) } EXPORT_SYMBOL(simple_inode_init_ts); -static inline struct dentry *get_stashed_dentry(struct dentry *stashed) +static inline struct dentry *get_stashed_dentry(struct dentry **stashed) { struct dentry *dentry; guard(rcu)(); - dentry = READ_ONCE(stashed); + dentry = rcu_dereference(*stashed); if (!dentry) return NULL; if (!lockref_get_not_dead(&dentry->d_lockref)) @@ -2219,7 +2219,7 @@ int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, const struct stashed_operations *sops = mnt->mnt_sb->s_fs_info; /* See if dentry can be reused. */ - path->dentry = get_stashed_dentry(*stashed); + path->dentry = get_stashed_dentry(stashed); if (path->dentry) { sops->put_data(data); goto out_path; |