dm-era tracks writes in target-relative blocks, but era_map() calculates the writeset block before applying the target offset. Tables with a non-zero start sector can therefore pass an absolute mapped-device block to metadata_current_marked().
If the absolute block is beyond the current writeset size, writeset_marked() tests past the end of the in-core bitset. KASAN reports this as a vmalloc-out-of-bounds access. Apply the target offset before calculating the era block so writeset lookups use the target-relative block number. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <[email protected]> --- drivers/md/dm-era-target.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c index 05285c04ff2c..18aed0e2a508 100644 --- a/drivers/md/dm-era-target.c +++ b/drivers/md/dm-era-target.c @@ -1229,6 +1229,7 @@ static dm_block_t get_block(struct era *era, struct bio *bio) static void remap_to_origin(struct era *era, struct bio *bio) { bio_set_dev(bio, era->origin_dev->bdev); + bio->bi_iter.bi_sector = dm_target_offset(era->ti, bio->bi_iter.bi_sector); } /* @@ -1560,7 +1561,7 @@ static void era_dtr(struct dm_target *ti) static int era_map(struct dm_target *ti, struct bio *bio) { struct era *era = ti->private; - dm_block_t block = get_block(era, bio); + dm_block_t block; /* * All bios get remapped to the origin device. We do this now, but @@ -1568,6 +1569,7 @@ static int era_map(struct dm_target *ti, struct bio *bio) * block is marked in this era. */ remap_to_origin(era, bio); + block = get_block(era, bio); /* * REQ_PREFLUSH bios carry no data, so we're not interested in them. -- 2.43.0

