Skip to content

Commit bcfbaea

Browse files
author
Kent Overstreet
committed
bcachefs: Fix shift overflows in replicas.c
We can't disallow unknown data_types in verify() - we have to preserve them unchanged for backwards compat; that means we have to add a few more guards. Reported-by: [email protected] Signed-off-by: Kent Overstreet <[email protected]>
1 parent f108ddd commit bcfbaea

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

fs/bcachefs/replicas.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -524,13 +524,16 @@ int bch2_replicas_gc_start(struct bch_fs *c, unsigned typemask)
524524
c->replicas_gc.nr = 0;
525525
c->replicas_gc.entry_size = 0;
526526

527-
for_each_cpu_replicas_entry(&c->replicas, e)
528-
if (!((1 << e->data_type) & typemask)) {
527+
for_each_cpu_replicas_entry(&c->replicas, e) {
528+
/* Preserve unknown data types */
529+
if (e->data_type >= BCH_DATA_NR ||
530+
!((1 << e->data_type) & typemask)) {
529531
c->replicas_gc.nr++;
530532
c->replicas_gc.entry_size =
531533
max_t(unsigned, c->replicas_gc.entry_size,
532534
replicas_entry_bytes(e));
533535
}
536+
}
534537

535538
c->replicas_gc.entries = kcalloc(c->replicas_gc.nr,
536539
c->replicas_gc.entry_size,
@@ -542,7 +545,8 @@ int bch2_replicas_gc_start(struct bch_fs *c, unsigned typemask)
542545
}
543546

544547
for_each_cpu_replicas_entry(&c->replicas, e)
545-
if (!((1 << e->data_type) & typemask))
548+
if (e->data_type >= BCH_DATA_NR ||
549+
!((1 << e->data_type) & typemask))
546550
memcpy(cpu_replicas_entry(&c->replicas_gc, i++),
547551
e, c->replicas_gc.entry_size);
548552

@@ -998,25 +1002,34 @@ unsigned bch2_sb_dev_has_data(struct bch_sb *sb, unsigned dev)
9981002
{
9991003
struct bch_sb_field_replicas *replicas;
10001004
struct bch_sb_field_replicas_v0 *replicas_v0;
1001-
unsigned i, data_has = 0;
1005+
unsigned data_has = 0;
10021006

10031007
replicas = bch2_sb_field_get(sb, replicas);
10041008
replicas_v0 = bch2_sb_field_get(sb, replicas_v0);
10051009

10061010
if (replicas) {
10071011
struct bch_replicas_entry_v1 *r;
10081012

1009-
for_each_replicas_entry(replicas, r)
1010-
for (i = 0; i < r->nr_devs; i++)
1013+
for_each_replicas_entry(replicas, r) {
1014+
if (r->data_type >= sizeof(data_has) * 8)
1015+
continue;
1016+
1017+
for (unsigned i = 0; i < r->nr_devs; i++)
10111018
if (r->devs[i] == dev)
10121019
data_has |= 1 << r->data_type;
1020+
}
1021+
10131022
} else if (replicas_v0) {
10141023
struct bch_replicas_entry_v0 *r;
10151024

1016-
for_each_replicas_entry_v0(replicas_v0, r)
1017-
for (i = 0; i < r->nr_devs; i++)
1025+
for_each_replicas_entry_v0(replicas_v0, r) {
1026+
if (r->data_type >= sizeof(data_has) * 8)
1027+
continue;
1028+
1029+
for (unsigned i = 0; i < r->nr_devs; i++)
10181030
if (r->devs[i] == dev)
10191031
data_has |= 1 << r->data_type;
1032+
}
10201033
}
10211034

10221035

0 commit comments

Comments
 (0)