Re: [PATCH] btrfs: fix NULL pointer deref during assertion in btrfs_backref_free_node()

Qu Wenruo <[email protected]>
Newsgroups org.kernel.vger.linux-btrfs
Message-ID <[email protected]>

在 2026/6/30 00:39, [email protected] 写道:
> From: Filipe Manana <[email protected]>
> 
> In btrfs_backref_free_node() we have the following assertion:
> 
>    ASSERT(node->eb == NULL, "node->eb->start=%llu", node->eb->start);
> 
> and a user reported the following crash:
> 
>    Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
>    KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
>    CPU: 0 UID: 0 PID: 10422 Comm: syz.0.17 Not tainted 7.1.0-02765-g6b5a2b7d9bc1-dirty #44 PREEMPT(full)
>    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
>    RIP: 0010:btrfs_backref_free_node fs/btrfs/backref.c:3057 [inline]
>    RIP: 0010:btrfs_backref_free_node+0xb9/0x200 fs/btrfs/backref.c:3051
>    Code: 00 fc ff (...)
>    RSP: 0018:ffa0000006b0f3c0 EFLAGS: 00010246
>    RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff840eb78b
>    RDX: 0000000000000000 RSI: ffffffff840eafa5 RDI: ff110000742ab768
>    RBP: ff110000742ab700 R08: 0000000000000000 R09: 0000000000000000
>    R10: ff110000742ab700 R11: 00000000000a81f9 R12: ff11000107a92020
>    R13: ff1100005c182ea8 R14: 0000000000000000 R15: dffffc0000000000
>    FS:  0000555575536500(0000) GS:ff11000183985000(0000) knlGS:0000000000000000
>    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>    CR2: 00007fa3d0e9d580 CR3: 000000002232a000 CR4: 0000000000753ef0
>    PKRU: 00000000
>    Call Trace:
>     <TASK>
>     btrfs_backref_cleanup_node+0x27/0x30 fs/btrfs/backref.c:3133
>     relocate_tree_block fs/btrfs/relocation.c:2604 [inline]
>     relocate_tree_blocks+0x11b0/0x1a20 fs/btrfs/relocation.c:2707
>     relocate_block_group+0x499/0xf30 fs/btrfs/relocation.c:3635
>     do_nonremap_reloc fs/btrfs/relocation.c:5323 [inline]
>     btrfs_relocate_block_group+0x1749/0x5fb0 fs/btrfs/relocation.c:5490
>     btrfs_relocate_chunk+0x12b/0x950 fs/btrfs/volumes.c:3647
>     __btrfs_balance fs/btrfs/volumes.c:4586 [inline]
>     btrfs_balance+0x1c7f/0x55c0 fs/btrfs/volumes.c:4973
>     btrfs_ioctl_balance fs/btrfs/ioctl.c:3474 [inline]
>     btrfs_ioctl+0x38a4/0x5d20 fs/btrfs/ioctl.c:5570
>     vfs_ioctl fs/ioctl.c:51 [inline]
>     __do_sys_ioctl fs/ioctl.c:597 [inline]
>     __se_sys_ioctl fs/ioctl.c:583 [inline]
>     __x64_sys_ioctl+0x18f/0x210 fs/ioctl.c:583
>     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>     do_syscall_64+0x11f/0x860 arch/x86/entry/syscall_64.c:94
>     entry_SYSCALL_64_after_hwframe+0x77/0x7f
>     RIP: 0033:0x7fb38e3b56dd
>     Code: 02 b8 ff (...)
>     RSP: 002b:00007fff04115788 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>     RAX: ffffffffffffffda RBX: 00007fb38f6b0020 RCX: 00007fb38e3b56dd
>     RDX: 00002000000003c0 RSI: 00000000c4009420 RDI: 0000000000000004
>     RBP: 00007fb38e451b48 R08: 0000000000000000 R09: 0000000000000000
>     R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
>     R13: 0000000000000000 R14: 00007fb38f6b0020 R15: 00007fb38f6b002c
>     </TASK>
> 
> It seems that this happens on some systems for some reason, when the
> ASSERT() macro calls the inline function verify_assert_printk_format()
> to evaluate the format string and arguments, causing the NULL pointer
> dereference on node->eb.
> 
> So change the assertion to check for a NULL node->eb before dereferencing
> it. Also, while at it, make the assertion more useful by printing the
> owner of the extent buffer as well as its level.
> 
> Reported-by: Yue Sun <[email protected]>
> Link: https://lore.kernel.org/linux-btrfs/[email protected]/
> Fixes: c4e7778580d6 ("btrfs: use verbose assertions in backref.c")
> Signed-off-by: Filipe Manana <[email protected]>

Reviewed-by: Qu Wenruo <[email protected]>

Thanks,
Qu

> ---
>   fs/btrfs/backref.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 23c3eeb58dc1..1be632c742bd 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -3054,7 +3054,10 @@ void btrfs_backref_free_node(struct btrfs_backref_cache *cache,
>   	if (node) {
>   		ASSERT(list_empty(&node->list));
>   		ASSERT(list_empty(&node->lower));
> -		ASSERT(node->eb == NULL, "node->eb->start=%llu", node->eb->start);
> +		ASSERT(node->eb == NULL, "node->eb->start=%llu level=%d owner=%llu",
> +		       node->eb ? node->eb->start : 0,
> +		       node->eb ? btrfs_header_level(node->eb) : 0,
> +		       node->eb ? btrfs_header_owner(node->eb) : 0);
>   		cache->nr_nodes--;
>   		btrfs_put_root(node->root);
>   		kfree(node);
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.