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>
 
 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;
                        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;
                break;
        }
 
-       dst->nr_errors = cpu_to_le16(nr_errors);
        return ret;
 }