Skip to content

Commit a295aef

Browse files
z00448126Miklos Szeredi
authored andcommitted
ovl: fix missing negative dentry check in ovl_rename()
The following reproducer mkdir lower upper work merge touch lower/old touch lower/new mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work merge rm merge/new mv merge/old merge/new & unlink upper/new may result in this race: PROCESS A: rename("merge/old", "merge/new"); overwrite=true,ovl_lower_positive(old)=true, ovl_dentry_is_whiteout(new)=true -> flags |= RENAME_EXCHANGE PROCESS B: unlink("upper/new"); PROCESS A: lookup newdentry in new_upperdir call vfs_rename() with negative newdentry and RENAME_EXCHANGE Fix by adding the missing check for negative newdentry. Signed-off-by: Zheng Liang <[email protected]> Fixes: e9be9d5 ("overlay filesystem") Cc: <[email protected]> # v3.18 Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 6880fa6 commit a295aef

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

fs/overlayfs/dir.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,9 +1219,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
12191219
goto out_dput;
12201220
}
12211221
} else {
1222-
if (!d_is_negative(newdentry) &&
1223-
(!new_opaque || !ovl_is_whiteout(newdentry)))
1224-
goto out_dput;
1222+
if (!d_is_negative(newdentry)) {
1223+
if (!new_opaque || !ovl_is_whiteout(newdentry))
1224+
goto out_dput;
1225+
} else {
1226+
if (flags & RENAME_EXCHANGE)
1227+
goto out_dput;
1228+
}
12251229
}
12261230

12271231
if (olddentry == trap)

0 commit comments

Comments
 (0)