btrfs: tree-checker: validate parent field for inode extref items

For a subvolume tree, the parent field of an inode extref item corresponds
to an inode number, and that must always be within the range:

   [ BTRFS_FIRST_FREE_OBJECTID (256), BTRFS_LAST_FREE_OBJECTID (-256) ]

Add a check for that in check_inode_extref().

Reviewed-by: Boris Burkov <boris@bur.io>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2026-09-03 16:24:43 +01:00 committed by David Sterba
parent 2a4513ab53
commit b18f0f8334

View File

@ -1962,12 +1962,14 @@ static int check_inode_extref(struct extent_buffer *leaf,
{
unsigned long ptr = btrfs_item_ptr_offset(leaf, slot);
unsigned long end = ptr + btrfs_item_size(leaf, slot);
const bool is_fstree = btrfs_is_fstree(btrfs_header_owner(leaf));
if (unlikely(!check_prev_ino(leaf, key, slot, prev_key)))
return -EUCLEAN;
while (ptr < end) {
struct btrfs_inode_extref *extref = (struct btrfs_inode_extref *)ptr;
u64 parent;
u16 namelen;
if (unlikely(ptr + sizeof(*extref) > end)) {
@ -1977,6 +1979,16 @@ static int check_inode_extref(struct extent_buffer *leaf,
return -EUCLEAN;
}
parent = btrfs_inode_extref_parent(leaf, extref);
if (unlikely(is_fstree && (parent < BTRFS_FIRST_FREE_OBJECTID ||
parent > BTRFS_LAST_FREE_OBJECTID))) {
inode_ref_err(leaf, slot,
"invalid parent for extref key, have %llu expect [%llu, %lld]",
parent, BTRFS_FIRST_FREE_OBJECTID,
BTRFS_LAST_FREE_OBJECTID);
return -EUCLEAN;
}
namelen = btrfs_inode_extref_name_len(leaf, extref);
if (unlikely(ptr + sizeof(*extref) + namelen > end)) {
inode_ref_err(leaf, slot,