]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: Fix downgrade_table_extra()
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 8 Jun 2025 15:58:59 +0000 (11:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 12 Jun 2025 03:21:30 +0000 (23:21 -0400)
Fix a UAF: we were calling darray_make_room() and retaining a pointer to
the old buffer.

And fix an UBSAN warning: struct bch_sb_field_downgrade_entry uses
__counted_by, so set dst->nr_errors before assigning to the array entry.

Reported-by: syzbot+14c52d86ddbd89bea13e@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/sb-downgrade.c

index b61f88450a6d280092126863b33ffc75d5fb8b84..1506d05e06654b0b1c3ef768ad3d69cfc31baf4d 100644 (file)
@@ -253,6 +253,7 @@ DOWNGRADE_TABLE()
 
 static int downgrade_table_extra(struct bch_fs *c, darray_char *table)
 {
+       unsigned dst_offset = table->nr;
        struct bch_sb_field_downgrade_entry *dst = (void *) &darray_top(*table);
        unsigned bytes = sizeof(*dst) + sizeof(dst->errors[0]) * le16_to_cpu(dst->nr_errors);
        int ret = 0;
@@ -268,6 +269,9 @@ static int downgrade_table_extra(struct bch_fs *c, darray_char *table)
                        if (ret)
                                return ret;
 
+                       dst = (void *) &table->data[dst_offset];
+                       dst->nr_errors = cpu_to_le16(nr_errors + 1);
+
                        /* open coded __set_bit_le64, as dst is packed and
                         * dst->recovery_passes is misaligned */
                        unsigned b = BCH_RECOVERY_PASS_STABLE_check_allocations;
@@ -278,7 +282,6 @@ static int downgrade_table_extra(struct bch_fs *c, darray_char *table)
                break;
        }
 
-       dst->nr_errors = cpu_to_le16(nr_errors);
        return ret;
 }