mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 08:58:07 +00:00
bcachefs: Fix sb-downgrade validation
Superblock downgrade entries are only two byte aligned, but section sizes are 8 byte aligned, which means we have to be careful about overrun checks; an entry that crosses the end of the section is allowed (and ignored) as long as it has zero errors. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
d509cadc3a
commit
9242a34b76
1 changed files with 10 additions and 3 deletions
|
@ -146,10 +146,17 @@ static int bch2_sb_downgrade_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
|||
for (const struct bch_sb_field_downgrade_entry *i = e->entries;
|
||||
(void *) i < vstruct_end(&e->field);
|
||||
i = downgrade_entry_next_c(i)) {
|
||||
/*
|
||||
* Careful: sb_field_downgrade_entry is only 2 byte aligned, but
|
||||
* section sizes are 8 byte aligned - an empty entry spanning
|
||||
* the end of the section is allowed (and ignored):
|
||||
*/
|
||||
if ((void *) &i->errors[0] > vstruct_end(&e->field))
|
||||
break;
|
||||
|
||||
if (flags & BCH_VALIDATE_write &&
|
||||
((void *) &i->errors[0] > vstruct_end(&e->field) ||
|
||||
(void *) downgrade_entry_next_c(i) > vstruct_end(&e->field))) {
|
||||
prt_printf(err, "downgrade entry overruns end of superblock section)");
|
||||
(void *) downgrade_entry_next_c(i) > vstruct_end(&e->field)) {
|
||||
prt_printf(err, "downgrade entry overruns end of superblock section");
|
||||
return -BCH_ERR_invalid_sb_downgrade;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue