Commit 082c7441 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix downgrade_table_extra()



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: default avatar <syzbot+14c52d86ddbd89bea13e@syzkaller.appspotmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 757601ef
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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;
}