On Mon, Jun 15, 2026 at 2:20 PM Ming Hung Tsai <[email protected]> wrote:
>
> 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

I will send a new patch with the subject line you've suggested.

Reply via email to