]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: abort transaction on item count overflow in __push_leaf_left()
authorFilipe Manana <fdmanana@suse.com>
Thu, 13 Nov 2025 16:44:41 +0000 (16:44 +0000)
committerDavid Sterba <dsterba@suse.com>
Mon, 24 Nov 2025 21:42:25 +0000 (22:42 +0100)
If we try to push an item count from the right leaf that is greater than
the number of items in the leaf, we just emit a warning. This should
never happen but if it does we get an underflow in the new number of
items in the right leaf and chaos follows from it. So replace the warning
with proper error handling, by aborting the transaction and returning
-EUCLEAN, and proper logging by using btrfs_crit() instead of WARN(),
which gives us proper formatting and information about the filesystem.

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.c

index 57b7d09d85cc2144068d298c553f6d24aa27d294..8b54daf3d0e71d27ce936738a56b392521a8eb25 100644 (file)
@@ -3393,9 +3393,13 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
        btrfs_set_header_nritems(left, old_left_nritems + push_items);
 
        /* fixup right node */
-       if (push_items > right_nritems)
-               WARN(1, KERN_CRIT "push items %d nr %u\n", push_items,
-                      right_nritems);
+       if (unlikely(push_items > right_nritems)) {
+               ret = -EUCLEAN;
+               btrfs_abort_transaction(trans, ret);
+               btrfs_crit(fs_info, "push items (%d) > right leaf items (%u)",
+                          push_items, right_nritems);
+               goto out;
+       }
 
        if (push_items < right_nritems) {
                push_space = btrfs_item_offset(right, push_items - 1) -