mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
fat: avoid parent link count underflow in rmdir
[ Upstream commit8cafcb8813] Corrupted FAT images can leave a directory inode with an incorrect i_nlink (e.g. 2 even though subdirectories exist). rmdir then unconditionally calls drop_nlink(dir) and can drive i_nlink to 0, triggering the WARN_ON in drop_nlink(). Add a sanity check in vfat_rmdir() and msdos_rmdir(): only drop the parent link count when it is at least 3, otherwise report a filesystem error. Link: https://lkml.kernel.org/r/20260101111148.1437-1-zhiyuzhang999@gmail.com Fixes:9a53c3a783("[PATCH] r/o bind mounts: unlink: monitor i_nlink") Signed-off-by: Zhiyu Zhang <zhiyuzhang999@gmail.com> Reported-by: Zhiyu Zhang <zhiyuzhang999@gmail.com> Closes: https://lore.kernel.org/linux-fsdevel/aVN06OKsKxZe6-Kv@casper.infradead.org/T/#t Tested-by: Zhiyu Zhang <zhiyuzhang999@gmail.com> Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a77e945c52
commit
17866f8a08
@@ -325,7 +325,12 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
|
||||
if (err)
|
||||
goto out;
|
||||
drop_nlink(dir);
|
||||
if (dir->i_nlink >= 3)
|
||||
drop_nlink(dir);
|
||||
else {
|
||||
fat_fs_error(sb, "parent dir link count too low (%u)",
|
||||
dir->i_nlink);
|
||||
}
|
||||
|
||||
clear_nlink(inode);
|
||||
fat_truncate_time(inode, NULL, S_CTIME);
|
||||
|
||||
+6
-1
@@ -803,7 +803,12 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
err = fat_remove_entries(dir, &sinfo); /* and releases bh */
|
||||
if (err)
|
||||
goto out;
|
||||
drop_nlink(dir);
|
||||
if (dir->i_nlink >= 3)
|
||||
drop_nlink(dir);
|
||||
else {
|
||||
fat_fs_error(sb, "parent dir link count too low (%u)",
|
||||
dir->i_nlink);
|
||||
}
|
||||
|
||||
clear_nlink(inode);
|
||||
fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
|
||||
|
||||
Reference in New Issue
Block a user