Re: [PATCH] nilfs2: enhance btree node keys check

Viacheslav Dubeyko <[email protected]>
Newsgroups org.kernel.vger.linux-nilfs,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Mon, 2026-08-10 at 23:20 +0900, Ryusuke Konishi wrote:
> From: Wang Jianjian <[email protected]>
> 
> 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.
> 
> [ryusuke: split long lines in btree.c to satisfy checkpatch and
>  improved the error message format for clarity]
> 
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=158be45e4d99232e1900
> Signed-off-by: Wang Jianjian <[email protected]>
> Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
> Cc: <[email protected]> # Warning suppression primarily
> Signed-off-by: Ryusuke Konishi <[email protected]>
> ---
> Hi Viacheslav,
> 
> Please apply this for the next cycle.
> 
> This introduces a check for sorted keys when reading btree node
> blocks
> into the cache, preventing unexpected errors during the block number
> assignment phase in log writing caused by key order inconsistencies,
> as well as the kernel warnings reported by syzbot.
> 
> Thanks,
> Ryusuke Konishi
> 
>  fs/nilfs2/btree.c | 19 ++++++++++++++++---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
> index 64bac66af25b..6b8332e8c0db 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,21 @@ 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): unsorted keys at index %d (%llu) and %d (%llu)",
> +				inode->i_ino, (unsigned long
> long)blocknr,
> +				i - 1, prev_key, i, key);
> +			return 1;
> +		}
> +	}
> +	return 0;
>  }
>  
>  /**

Applied.

Thanks,
Slava.
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.