Skip to content

Commit cb8d2bd

Browse files
Miklos Szeredibrauner
authored andcommitted
fuse: fix race when disposing stale dentries
In fuse_dentry_tree_work() just before d_dispose_if_unused() the dentry could get evicted, resulting in UAF. Move unlocking dentry_hash[i].lock to after the dispose. To do this, fuse_dentry_tree_del_node() needs to be moved from fuse_dentry_prune() to fuse_dentry_release() to prevent an ABBA deadlock. The lock ordering becomes: -> dentry_bucket.lock -> dentry.d_lock Reported-by: Al Viro <viro@zeniv.linux.org.uk> Closes: https://lore.kernel.org/all/20251206014242.GO1712166@ZenIV/ Fixes: ab84ad5 ("fuse: new work queue to periodically invalidate expired dentries") Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Link: https://patch.msgid.link/20260114145344.468856-2-mszeredi@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 4973d95 commit cb8d2bd

1 file changed

Lines changed: 2 additions & 9 deletions

File tree

fs/fuse/dir.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ static void fuse_dentry_tree_work(struct work_struct *work)
172172
if (time_after64(get_jiffies_64(), fd->time)) {
173173
rb_erase(&fd->node, &dentry_hash[i].tree);
174174
RB_CLEAR_NODE(&fd->node);
175-
spin_unlock(&dentry_hash[i].lock);
176175
d_dispose_if_unused(fd->dentry, &dispose);
176+
spin_unlock(&dentry_hash[i].lock);
177177
cond_resched();
178178
spin_lock(&dentry_hash[i].lock);
179179
} else
@@ -479,18 +479,12 @@ static int fuse_dentry_init(struct dentry *dentry)
479479
return 0;
480480
}
481481

482-
static void fuse_dentry_prune(struct dentry *dentry)
482+
static void fuse_dentry_release(struct dentry *dentry)
483483
{
484484
struct fuse_dentry *fd = dentry->d_fsdata;
485485

486486
if (!RB_EMPTY_NODE(&fd->node))
487487
fuse_dentry_tree_del_node(dentry);
488-
}
489-
490-
static void fuse_dentry_release(struct dentry *dentry)
491-
{
492-
struct fuse_dentry *fd = dentry->d_fsdata;
493-
494488
kfree_rcu(fd, rcu);
495489
}
496490

@@ -527,7 +521,6 @@ const struct dentry_operations fuse_dentry_operations = {
527521
.d_revalidate = fuse_dentry_revalidate,
528522
.d_delete = fuse_dentry_delete,
529523
.d_init = fuse_dentry_init,
530-
.d_prune = fuse_dentry_prune,
531524
.d_release = fuse_dentry_release,
532525
.d_automount = fuse_dentry_automount,
533526
};

0 commit comments

Comments
 (0)