[PATCH] fat: avoid parent link count underflow in rmdir

Zhiyu Zhang posted 1 patch 1 month, 1 week ago
fs/fat/namei_msdos.c | 7 ++++++-
fs/fat/namei_vfat.c  | 7 ++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
[PATCH] fat: avoid parent link count underflow in rmdir
Posted by Zhiyu Zhang 1 month, 1 week ago
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.

Fixes: 9a53c3a783c2 ("[PATCH] r/o bind mounts: unlink: monitor i_nlink")
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>
Signed-off-by: Zhiyu Zhang <zhiyuzhang999@gmail.com>
---
 fs/fat/namei_msdos.c | 7 ++++++-
 fs/fat/namei_vfat.c  | 7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 0b920ee40a7f..262ec1b790b5 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -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);
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 5dbc4cbb8fce..47ff083cfc7e 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -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);
-- 
2.34.1
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by OGAWA Hirofumi 1 month, 1 week ago
Zhiyu Zhang <zhiyuzhang999@gmail.com> writes:

> 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.
>
> Fixes: 9a53c3a783c2 ("[PATCH] r/o bind mounts: unlink: monitor i_nlink")
> 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>
> Signed-off-by: Zhiyu Zhang <zhiyuzhang999@gmail.com>

Looks good. Thanks.

Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

> ---
>  fs/fat/namei_msdos.c | 7 ++++++-
>  fs/fat/namei_vfat.c  | 7 ++++++-
>  2 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
> index 0b920ee40a7f..262ec1b790b5 100644
> --- a/fs/fat/namei_msdos.c
> +++ b/fs/fat/namei_msdos.c
> @@ -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);
> diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
> index 5dbc4cbb8fce..47ff083cfc7e 100644
> --- a/fs/fat/namei_vfat.c
> +++ b/fs/fat/namei_vfat.c
> @@ -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);

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by OGAWA Hirofumi 3 weeks, 5 days ago
Ping?

OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes:

> Zhiyu Zhang <zhiyuzhang999@gmail.com> writes:
>
>> 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.
>>
>> Fixes: 9a53c3a783c2 ("[PATCH] r/o bind mounts: unlink: monitor i_nlink")
>> 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>
>> Signed-off-by: Zhiyu Zhang <zhiyuzhang999@gmail.com>
>
> Looks good. Thanks.
>
> Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
>
>> ---
>>  fs/fat/namei_msdos.c | 7 ++++++-
>>  fs/fat/namei_vfat.c  | 7 ++++++-
>>  2 files changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
>> index 0b920ee40a7f..262ec1b790b5 100644
>> --- a/fs/fat/namei_msdos.c
>> +++ b/fs/fat/namei_msdos.c
>> @@ -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);
>> diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
>> index 5dbc4cbb8fce..47ff083cfc7e 100644
>> --- a/fs/fat/namei_vfat.c
>> +++ b/fs/fat/namei_vfat.c
>> @@ -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);

-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by Zhiyu Zhang 3 weeks, 5 days ago
Hi OGAWA,

Sorry, I thought the further merge request would be done by the maintainers.

What should I do then?

Best,
Zhiyu Zhang

OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> 于2026年1月13日周二 00:21写道:
>
> Ping?
>
> OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes:
>
> > Zhiyu Zhang <zhiyuzhang999@gmail.com> writes:
> >
> >> 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.
> >>
> >> Fixes: 9a53c3a783c2 ("[PATCH] r/o bind mounts: unlink: monitor i_nlink")
> >> 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>
> >> Signed-off-by: Zhiyu Zhang <zhiyuzhang999@gmail.com>
> >
> > Looks good. Thanks.
> >
> > Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
> >
> >> ---
> >>  fs/fat/namei_msdos.c | 7 ++++++-
> >>  fs/fat/namei_vfat.c  | 7 ++++++-
> >>  2 files changed, 12 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
> >> index 0b920ee40a7f..262ec1b790b5 100644
> >> --- a/fs/fat/namei_msdos.c
> >> +++ b/fs/fat/namei_msdos.c
> >> @@ -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);
> >> diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
> >> index 5dbc4cbb8fce..47ff083cfc7e 100644
> >> --- a/fs/fat/namei_vfat.c
> >> +++ b/fs/fat/namei_vfat.c
> >> @@ -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);
>
> --
> OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by Andrew Morton 3 weeks, 5 days ago
On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:

> Hi OGAWA,
> 
> Sorry, I thought the further merge request would be done by the maintainers.
> 
> What should I do then?

That's OK - I have now taken a copy of the patch mainly to keep track
of it.  It won't get lost.

I thought Christian was handling fat patches now, but perhaps that's a
miscommunication?
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by OGAWA Hirofumi 3 weeks, 5 days ago
Andrew Morton <akpm@linux-foundation.org> writes:

> On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:
>
>> Hi OGAWA,
>> 
>> Sorry, I thought the further merge request would be done by the maintainers.
>> 
>> What should I do then?
>
> That's OK - I have now taken a copy of the patch mainly to keep track
> of it.  It won't get lost.
>
> I thought Christian was handling fat patches now, but perhaps that's a
> miscommunication?

Hm, I was thinking Andrew is still handling the fat specific patch, and
Christian is only handling patches when vfs related.

Let me know if I need to do something.

Thanks.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by Andrew Morton 3 weeks, 5 days ago
On Tue, 13 Jan 2026 03:16:54 +0900 OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote:

> Andrew Morton <akpm@linux-foundation.org> writes:
> 
> > On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:
> >
> >> Hi OGAWA,
> >> 
> >> Sorry, I thought the further merge request would be done by the maintainers.
> >> 
> >> What should I do then?
> >
> > That's OK - I have now taken a copy of the patch mainly to keep track
> > of it.  It won't get lost.
> >
> > I thought Christian was handling fat patches now, but perhaps that's a
> > miscommunication?
> 
> Hm, I was thinking Andrew is still handling the fat specific patch, and
> Christian is only handling patches when vfs related.
> 
> Let me know if I need to do something.

OK, thanks, seems I misremembered.
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by Christian Brauner 3 weeks, 4 days ago
On Mon, Jan 12, 2026 at 10:39:59AM -0800, Andrew Morton wrote:
> On Tue, 13 Jan 2026 03:16:54 +0900 OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote:
> 
> > Andrew Morton <akpm@linux-foundation.org> writes:
> > 
> > > On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:
> > >
> > >> Hi OGAWA,
> > >> 
> > >> Sorry, I thought the further merge request would be done by the maintainers.
> > >> 
> > >> What should I do then?
> > >
> > > That's OK - I have now taken a copy of the patch mainly to keep track
> > > of it.  It won't get lost.
> > >
> > > I thought Christian was handling fat patches now, but perhaps that's a
> > > miscommunication?
> > 
> > Hm, I was thinking Andrew is still handling the fat specific patch, and
> > Christian is only handling patches when vfs related.
> > 
> > Let me know if I need to do something.
> 
> OK, thanks, seems I misremembered.

I prefer to take anything that touches fs/ - apart from reasonable
exceptions - to go through vfs tree. So I would prefer to take this
patch.
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by OGAWA Hirofumi 3 weeks, 4 days ago
Christian Brauner <brauner@kernel.org> writes:

> On Mon, Jan 12, 2026 at 10:39:59AM -0800, Andrew Morton wrote:
>> On Tue, 13 Jan 2026 03:16:54 +0900 OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote:
>> 
>> > Andrew Morton <akpm@linux-foundation.org> writes:
>> > 
>> > > On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:
>> > >
>> > >> Hi OGAWA,
>> > >> 
>> > >> Sorry, I thought the further merge request would be done by the maintainers.
>> > >> 
>> > >> What should I do then?
>> > >
>> > > That's OK - I have now taken a copy of the patch mainly to keep track
>> > > of it.  It won't get lost.
>> > >
>> > > I thought Christian was handling fat patches now, but perhaps that's a
>> > > miscommunication?
>> > 
>> > Hm, I was thinking Andrew is still handling the fat specific patch, and
>> > Christian is only handling patches when vfs related.
>> > 
>> > Let me know if I need to do something.
>> 
>> OK, thanks, seems I misremembered.
>
> I prefer to take anything that touches fs/ - apart from reasonable
> exceptions - to go through vfs tree. So I would prefer to take this
> patch.

OK. I will add you to To: (with Acked-by) instead of Andrew next time?

Thanks.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Re: [PATCH] fat: avoid parent link count underflow in rmdir
Posted by Christian Brauner 3 weeks, 3 days ago
On Tue, Jan 13, 2026 at 07:08:06PM +0900, OGAWA Hirofumi wrote:
> Christian Brauner <brauner@kernel.org> writes:
> 
> > On Mon, Jan 12, 2026 at 10:39:59AM -0800, Andrew Morton wrote:
> >> On Tue, 13 Jan 2026 03:16:54 +0900 OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> wrote:
> >> 
> >> > Andrew Morton <akpm@linux-foundation.org> writes:
> >> > 
> >> > > On Tue, 13 Jan 2026 01:45:18 +0800 Zhiyu Zhang <zhiyuzhang999@gmail.com> wrote:
> >> > >
> >> > >> Hi OGAWA,
> >> > >> 
> >> > >> Sorry, I thought the further merge request would be done by the maintainers.
> >> > >> 
> >> > >> What should I do then?
> >> > >
> >> > > That's OK - I have now taken a copy of the patch mainly to keep track
> >> > > of it.  It won't get lost.
> >> > >
> >> > > I thought Christian was handling fat patches now, but perhaps that's a
> >> > > miscommunication?
> >> > 
> >> > Hm, I was thinking Andrew is still handling the fat specific patch, and
> >> > Christian is only handling patches when vfs related.
> >> > 
> >> > Let me know if I need to do something.
> >> 
> >> OK, thanks, seems I misremembered.
> >
> > I prefer to take anything that touches fs/ - apart from reasonable
> > exceptions - to go through vfs tree. So I would prefer to take this
> > patch.
> 
> OK. I will add you to To: (with Acked-by) instead of Andrew next time?

Yes please. Thank you!