Re: [PATCH v3] nilfs2: enhance btree node keys check
Ryusuke Konishi <[email protected]>
| Newsgroups | org.kernel.vger.linux-nilfs |
|---|---|
| Message-ID | <CAKFNMo=ypauSr1O7YqrYaD0JkoSJAHcDW-DFfFhLgqgh2o0G-w@mail.gmail.com> |
On Mon, Aug 10, 2026 at 3:43 PM Wang Jianjian wrote: > > syzbot reported a warning on nilfs_btree_assign: > WARNING: fs/nilfs2/btree.c:2302 at nilfs_btree_assign+0x983/0xbe0 fs/nilfs2/btree.c:2302, > > Analysis found that a corrupted file has the following btree layout: > Level2(key/ptr): [ 256/15 ] > Level1(key/ptr): [ 0/8, 1/9, 0/10, 3/11, 4/12, 5/13, 6/14, 139637976727559/16, 0/17 ] > > The test truncated the file to 2 bytes, which partially zeroes the first block and > adds the file to the dirty list. When the segment constructor writes it and assigns > a new blocknr for the index block, it searches the btree with key=0 and min level=2, > and apparently returns ENOENT. > > Therefore, we should perform more checks on the btree nodes and return early. > > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=158be45e4d99232e1900 > Signed-off-by: Wang Jianjian <[email protected]> > --- > fs/nilfs2/btree.c | 17 ++++++++++++++--- > 1 file changed, 14 insertions(+), 3 deletions(-) Hi Wang Jianjian, Thank you for the patch. I would like to send this upstream. However, since there are a few minor things I would like to tweak, I will make the adjustments myself, run a thorough test, and then send it upstream. Specifically, after actually testing it, I found the message a bit confusing. (While the commit message refers to keys and pointers as "key/ptr", referring to them as "index/key" in the actual log message is confusing.)Therefore, please note this slight change to the error message output: nilfs_crit(inode->i_sb, "bad btree node (ino=%llu, blocknr=%llu): unsorted keys at index %d (%llu) and %d (%llu)", inode->i_ino, (unsigned long long)blocknr, i - 1, prev_key, i, key); Also, starting next time when you submit patches, please run checkpatch.pl (located in the scripts folder) on the patch output generated by git format-patch beforehand to check if it complies with the coding style guidelines. So, unless you have any concerns, please leave this to me and sit tight. Thanks, Ryusuke Konishi > > diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c > index 64d5f7c5ab44..adf087c896ba 100644 > --- a/fs/nilfs2/btree.c > +++ b/fs/nilfs2/btree.c > @@ -341,7 +341,8 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node, > sector_t blocknr) > { > int level, flags, nchildren; > - int ret = 0; > + __u64 key, prev_key; > + int i; > > level = nilfs_btree_node_get_level(node); > flags = nilfs_btree_node_get_flags(node); > @@ -356,9 +357,19 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node, > "bad btree node (ino=%llu, blocknr=%llu): level = %d, flags = 0x%x, nchildren = %d", > inode->i_ino, (unsigned long long)blocknr, level, > flags, nchildren); > - ret = 1; > + return 1; > } > - return ret; > + > + for (i = 1, prev_key = nilfs_btree_node_get_key(node, 0); i < nchildren; i++, prev_key = key) { > + key = nilfs_btree_node_get_key(node, i); > + if (unlikely(key <= prev_key)) { > + nilfs_crit(inode->i_sb, > + "bad btree node(ino=%llu, blocknr=%llu), key not sorted: %d/%llu <= %d/%llu", > + inode->i_ino, (unsigned long long)blocknr, i, key, i - 1, prev_key); > + return 1; > + } > + } > + return 0; > } > > /** > -- > 2.34.1 >