Re: [PATCH] dm era: include the target offset when mapping writes

Samuel Moelius <[email protected]>
Newsgroups dev.linux.lists.dm-devel
Message-ID <CAE+C+DbijFM7gzuiA2yuoPm6UOQ8XruG0z5JGr11tFWP7-pMjA@mail.gmail.com>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.