Skip to content

Commit e8bd877

Browse files
committed
ovl: fix possible double unlink
commit 9d23967 ("ovl: simplify an error path in ovl_copy_up_workdir()") introduced the helper ovl_cleanup_unlocked(), which is later used in several following patches to re-acquire the parent inode lock and unlink a dentry that was earlier found using lookup. This helper was eventually renamed to ovl_cleanup(). The helper ovl_parent_lock() is used to re-acquire the parent inode lock. After acquiring the parent inode lock, the helper verifies that the dentry has not since been moved to another parent, but it failed to verify that the dentry wasn't unlinked from the parent. This means that now every call to ovl_cleanup() could potentially race with another thread, unlinking the dentry to be cleaned up underneath overlayfs and trigger a vfs assertion. Reported-by: [email protected] Tested-by: [email protected] Fixes: 9d23967 ("ovl: simplify an error path in ovl_copy_up_workdir()") Suggested-by: NeilBrown <[email protected]> Signed-off-by: Amir Goldstein <[email protected]>
1 parent 5f1c896 commit e8bd877

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

fs/overlayfs/util.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,8 @@ void ovl_copyattr(struct inode *inode)
15521552
int ovl_parent_lock(struct dentry *parent, struct dentry *child)
15531553
{
15541554
inode_lock_nested(parent->d_inode, I_MUTEX_PARENT);
1555-
if (!child || child->d_parent == parent)
1555+
if (!child ||
1556+
(!d_unhashed(child) && child->d_parent == parent))
15561557
return 0;
15571558

15581559
inode_unlock(parent->d_inode);

0 commit comments

Comments
 (0)