On Tue, Jun 9, 2026 at 8:36 AM Samuel Moelius
<[email protected]> wrote:
>
> dm-era tracks writes in target-relative blocks, but the mapping path can
> ignore the target offset when translating bios.  Tables with a non-zero
> start sector can therefore map and account I/O against the wrong origin
> sectors.
>
> The result is inconsistent metadata for devices that are not mapped at
> sector zero.
>
> Apply the target offset consistently when mapping and tracking writes.
>
> 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
>
>

Thanks for the patch. This is a general bug for any dm-era table with
a non-zero start sector, causing out-of-bounds memory access to the
bitset when calling writeset_marked. Here's the reproducer:

```
# era metadata
dmsetup create emeta --table "0 8192 linear /dev/ram0 0"
dd if=/dev/zero of=/dev/mapper/emeta bs=4k count=1

# era origin
dmsetup create eorig --table "0 8192 linear /dev/ram0 16384"

# create an era device of 64 blocks, plus 2mb (32 blocks) padding at the front
dmsetup create era --table "0 4096 zero
4096 8192 era /dev/mapper/emeta /dev/mapper/eorig 128"

# write to the 64th block. it should be the 32nd era data block, but
being mapped to the 64th era data block (out-of-bounds)
dd if=/dev/zero of=/dev/mapper/era bs=64K count=1 seek=64
```

KASAN report:

BUG: KASAN: vmalloc-out-of-bounds in era_map+0x263/0x4a0
Read of size 8 at addr ffffc90000075008 by task dd/86

I'd suggest revising the commit message to emphasize the severity, e.g.,

dm era: fix out-of-bounds memory access for non-zero start sector


Reply via email to