Commit f8f1dde6 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix missing validation for bch_backpointer.level



This fixes an assertion pop where we try to navigate to the target of
the backpointer, and the path level isn't what we expect.

Reported-by: default avatar <syzbot+b17df21b4d370f2dc330@syzkaller.appspotmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 27a036a0
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -52,6 +52,12 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
			      enum bch_validate_flags flags)
{
	struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
	int ret = 0;

	bkey_fsck_err_on(bp.v->level > BTREE_MAX_DEPTH,
			 c, backpointer_level_bad,
			 "backpointer level bad: %u >= %u",
			 bp.v->level, BTREE_MAX_DEPTH);

	rcu_read_lock();
	struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
@@ -64,7 +70,6 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
	struct bpos bucket = bp_pos_to_bucket(ca, bp.k->p);
	struct bpos bp_pos = bucket_pos_to_bp_noerror(ca, bucket, bp.v->bucket_offset);
	rcu_read_unlock();
	int ret = 0;

	bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size ||
			 !bpos_eq(bp.k->p, bp_pos),
+5 −1
Original line number Diff line number Diff line
@@ -136,7 +136,9 @@ enum bch_fsck_flags {
	x(bucket_gens_nonzero_for_invalid_buckets,		122,	FSCK_AUTOFIX)	\
	x(need_discard_freespace_key_to_invalid_dev_bucket,	123,	0)		\
	x(need_discard_freespace_key_bad,			124,	0)		\
	x(discarding_bucket_not_in_need_discard_btree,		291,	0)		\
	x(backpointer_bucket_offset_wrong,			125,	0)		\
	x(backpointer_level_bad,				294,	0)		\
	x(backpointer_to_missing_device,			126,	0)		\
	x(backpointer_to_missing_alloc,				127,	0)		\
	x(backpointer_to_missing_ptr,				128,	0)		\
@@ -177,7 +179,9 @@ enum bch_fsck_flags {
	x(ptr_stripe_redundant,					163,	0)		\
	x(reservation_key_nr_replicas_invalid,			164,	0)		\
	x(reflink_v_refcount_wrong,				165,	0)		\
	x(reflink_v_pos_bad,					292,	0)		\
	x(reflink_p_to_missing_reflink_v,			166,	0)		\
	x(reflink_refcount_underflow,				293,	0)		\
	x(stripe_pos_bad,					167,	0)		\
	x(stripe_val_size_bad,					168,	0)		\
	x(stripe_csum_granularity_bad,				290,	0)		\
@@ -302,7 +306,7 @@ enum bch_fsck_flags {
	x(accounting_key_replicas_devs_unsorted,		280,	FSCK_AUTOFIX)	\
	x(accounting_key_version_0,				282,	FSCK_AUTOFIX)	\
	x(logged_op_but_clean,					283,	FSCK_AUTOFIX)	\
	x(MAX,							291,	0)
	x(MAX,							295,	0)

enum bch_sb_error_id {
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,