Re: [PATCH v2 0/3] btrfs: fix balance NULL derefs and chunk/bg mapping verification
From: David Sterba
Date: Mon Mar 23 2026 - 13:42:02 EST
On Sat, Mar 14, 2026 at 08:37:38PM +0800, ZhengYuan Huang wrote:
> This series fixes two NULL dereferences in btrfs balance usage filters and
> the underlying mount-time verification bug that lets the corresponding
> chunk/block-group inconsistency go undetected.
>
> The balance crashes happen when metadata corruption leaves a chunk present
> in the chunk tree but without a corresponding block group in the in-memory
> block group cache. In that case, the usage filters call
> btrfs_lookup_block_group() and dereference the returned pointer without
> checking for NULL.
>
> The first two patches add the missing NULL checks and propagate -EUCLEAN
> back to userspace instead of crashing. They are split because the usage
> and usage-range filters were introduced by different commits, which should
> also make backporting easier, as suggested by Qu Wenruo.
>
> The third patch fixes the root cause on the mount-time verification side.
> check_chunk_block_group_mappings() is supposed to verify that every chunk
> has a matching block group, but its current iteration starts with
> btrfs_find_chunk_map(fs_info, 0, 1). If no chunk contains logical address
> 0, the lookup returns NULL immediately and the loop exits without checking
> any chunk at all. As a result, the corrupted mapping can survive mount and
> only crash later when balance reaches it.
>
> This series makes btrfs reject the inconsistency earlier at mount time,
> and also hardens the balance filters so the corruption is reported as
> -EUCLEAN instead of triggering a NULL dereference.
As I understand it you're using some advanced fuzzing tool (patch 1
mentions runtime fuzzing), so the errors would not normally happen. With
fuzzing it depends on the capabilities, at runtime it is possible to
confuse the filesystem so much that sipmle checks can't detect it.
Here checking if block group lookups are ok makes sense in general.
There are existing checks that seem to be following the same logic like
in unpin_extent_range().
>
> Changes since v1:
> - split the two balance filter fixes into separate patches
> - reworked the third patch to fix the case where
> check_chunk_block_group_mappings() does not actually check all chunk
> mappings
>
> [NOTE]
> Some of the changelogs may repeat parts of the bug analysis, which can
> make the series somewhat verbose. I did that intentionally because I was
> trying to follow the usual expectation that each patch should be able to
> stand on its own and explain the specific issue it fixes.
This is good, thanks. For simple fixes or cleanups it's fine to
make a vague reference to the main patch or a "in the previous/followup
patches".