bcachefs: Fix missing validation in bch2_sb_journal_v2_validate()

Reported-by: syzbot+47ecc948aadfb2ab3efc@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2024-08-21 21:10:45 -04:00
parent cab18be695
commit bdbdd4759f

View File

@ -104,6 +104,7 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct bch_sb_field *f
struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2); struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx); struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
int ret = -BCH_ERR_invalid_sb_journal; int ret = -BCH_ERR_invalid_sb_journal;
u64 sum = 0;
unsigned nr; unsigned nr;
unsigned i; unsigned i;
struct u64_range *b; struct u64_range *b;
@ -119,6 +120,15 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct bch_sb_field *f
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
b[i].start = le64_to_cpu(journal->d[i].start); b[i].start = le64_to_cpu(journal->d[i].start);
b[i].end = b[i].start + le64_to_cpu(journal->d[i].nr); b[i].end = b[i].start + le64_to_cpu(journal->d[i].nr);
if (b[i].end <= b[i].start) {
prt_printf(err, "journal buckets entry with bad nr: %llu+%llu",
le64_to_cpu(journal->d[i].start),
le64_to_cpu(journal->d[i].nr));
goto err;
}
sum += le64_to_cpu(journal->d[i].nr);
} }
sort(b, nr, sizeof(*b), u64_range_cmp, NULL); sort(b, nr, sizeof(*b), u64_range_cmp, NULL);
@ -148,6 +158,11 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct bch_sb_field *f
} }
} }
if (sum > UINT_MAX) {
prt_printf(err, "too many journal buckets: %llu > %u", sum, UINT_MAX);
goto err;
}
ret = 0; ret = 0;
err: err:
kfree(b); kfree(b);