Commit be3e5d10 authored by Deepanshu Kartikey's avatar Deepanshu Kartikey Committed by Viacheslav Dubeyko
Browse files

nilfs2: reject zero bd_oblocknr in nilfs_ioctl_mark_blocks_dirty()



nilfs_ioctl_mark_blocks_dirty() uses bd_oblocknr to detect dead blocks
by comparing it with the current block number bd_blocknr. If they differ,
the block is considered dead and skipped.

However, bd_oblocknr should never be 0 since block 0 typically stores the
primary superblock and is never a valid GC target block. A corrupted ioctl
request with bd_oblocknr set to 0 causes the comparison to incorrectly
match when the lookup returns -ENOENT and sets bd_blocknr to 0, bypassing
the dead block check and calling nilfs_bmap_mark() on a non-existent
block. This causes nilfs_btree_do_lookup() to return -ENOENT, triggering
the WARN_ON(ret == -ENOENT).

Fix this by rejecting ioctl requests with bd_oblocknr set to 0 at the
beginning of each iteration.

[ryusuke: slightly modified the commit message and comments for accuracy]

Fixes: 7942b919 ("nilfs2: ioctl operations")
Reported-by: default avatar <syzbot+98a040252119df0506f8@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=98a040252119df0506f8


Suggested-by: default avatarRyusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: default avatarDeepanshu Kartikey <Kartikey406@gmail.com>
Reported-by: default avatar <syzbot+466a45fcfb0562f5b9a0@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=466a45fcfb0562f5b9a0


Cc: Junjie Cao <junjie.cao@linux.dev>
Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: default avatarViacheslav Dubeyko <slava@dubeyko.com>
parent 4a4e0328
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -736,6 +736,12 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
	int ret, i;

	for (i = 0; i < nmembs; i++) {
		/*
		 * bd_oblocknr must never be 0 as block 0
		 * is never a valid GC target block
		 */
		if (unlikely(!bdescs[i].bd_oblocknr))
			return -EINVAL;
		/* XXX: use macro or inline func to check liveness */
		ret = nilfs_bmap_lookup_at_level(bmap,
						 bdescs[i].bd_offset,