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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.