[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAKFNMokBCsjR-QvQCAHcAoSfC5yFAGU+xpiA2CUnGPhi7f-uFA@mail.gmail.com>
Date: Wed, 17 Dec 2025 22:38:32 +0900
From: Ryusuke Konishi <konishi.ryusuke@...il.com>
To: Edward Adam Davis <eadavis@...com>
Cc: syzbot+7eedce5eb281acd832f0@...kaller.appspotmail.com, axboe@...nel.dk,
kristian@...usen.dk, linux-kernel@...r.kernel.org,
linux-nilfs@...r.kernel.org, slava@...eyko.com,
syzkaller-bugs@...glegroups.com
Subject: Re: [PATCH] nilfs2: fix potential block overflow that cause system hang
On Wed, Dec 17, 2025 at 5:43 PM Edward Adam Davis wrote:
>
> When a user executes the FITRIM command, an underflow can occur when
> calculating nblocks if end_block is too small. Since nblocks is of
> type sector_t, which is u64, a negative nblocks value will become a
> very large positive integer. This ultimately leads to the block layer
> function __blkdev_issue_discard() taking an excessively long time to
> process the bio chain, and the ns_segctor_sem lock remains held for a
> long period. This prevents other tasks from acquiring the ns_segctor_sem
> lock, resulting in the hang reported by syzbot in [1].
>
> The fix involves adding a check for the end block: if it equals the
> start block, the trim operation is exited and -EINVAL is returned.
>
> [1]
> task:segctord state:D stack:28968 pid:6093 tgid:6093 ppid:2 task_flags:0x200040 flags:0x00080000
> Call Trace:
> rwbase_write_lock+0x3dd/0x750 kernel/locking/rwbase_rt.c:272
> nilfs_transaction_lock+0x253/0x4c0 fs/nilfs2/segment.c:357
> nilfs_segctor_thread_construct fs/nilfs2/segment.c:2569 [inline]
> nilfs_segctor_thread+0x6ec/0xe00 fs/nilfs2/segment.c:2684
>
> Fixes: 82e11e857be3 ("nilfs2: add nilfs_sufile_trim_fs to trim clean segs")
> Reported-by: syzbot+7eedce5eb281acd832f0@...kaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=7eedce5eb281acd832f0
> Signed-off-by: Edward Adam Davis <eadavis@...com>
> ---
> fs/nilfs2/sufile.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
> index 83f93337c01b..63a1f0b29066 100644
> --- a/fs/nilfs2/sufile.c
> +++ b/fs/nilfs2/sufile.c
> @@ -1093,6 +1093,9 @@ int nilfs_sufile_trim_fs(struct inode *sufile, struct fstrim_range *range)
> else
> end_block = start_block + len - 1;
>
> + if (start_block == end_block)
> + return -EINVAL;
> +
> segnum = nilfs_get_segnum_of_block(nilfs, start_block);
> segnum_end = nilfs_get_segnum_of_block(nilfs, end_block);
>
> --
> 2.43.0
Hi Edward,
Thanks for the patch.
And, sorry for the noise on the block layer. As his patch points out,
this looks like a defect in the NILFS2 fstrim implementation.
However, I would like to discuss the approach to the fix with Edward.
Since the FITRIM request size is larger than the block size (which is
1KiB in the syzbot reproducer), the request itself looks valid. I
believe we need to fix the logic that causes the loop overrun instead
of rejecting the request.
I attempted to reproduce the issue using the exact same ioctl
parameters, but it completed successfully. Therefore, I suspect that
specific disk usage or metadata corruption might be a prerequisite for
triggering this bug.
I will follow up with more detailed feedback later.
Thanks,
Ryusuke Konishi
Powered by blists - more mailing lists