Re: [PATCH v4 09/25] md/md-llbitmap: track bitmap sync_size explicitly
[email protected] Sat, 01 Aug 2026 17:44:12 +0000
| Newsgroups | org.kernel.vger.linux-raid |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(= s) to consider: - [High] Missing bounds check on `sync_size` causes out-of-bounds memory ac= cesses and disk overwrites. -- --- Patch [9]: [PATCH v4 09/25] md/md-llbitmap: track bitmap sync_size expl= icitly --- commit b06a020ec2776bd2bc0418543c90f7ea1a1e754b Author: Yu Kuai <[email protected]> md/md-llbitmap: track bitmap sync_size explicitly Track llbitmap's own sync_size instead of always using mddev->resync_max_sectors directly. This is the minimal bookkeeping needed before llbitmap can track old and new reshape geometry independently. > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > index 1fa2adf0ada1c..3417da288e994 100644 > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c [ ... ] > @@ -987,6 +991,9 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap) > goto out_put_page; > } > =20 > + sync_size =3D le64_to_cpu(sb->sync_size); > + if (!sync_size) > + sync_size =3D mddev->resync_max_sectors; [Severity: High] Does this code bypass capacity validation if the superblock is corrupted or tampered? If an array is assembled with a bitmap superblock where sb->sync_size is artificially large or small, this untrusted sync_size is read here. However, it appears the bounds check later in llbitmap_read_sb() still validates against mddev->resync_max_sectors instead of the new sync_size: if (chunksize < DIV_ROUND_UP_SECTOR_T(mddev->resync_max_sectors, mddev->bitmap_info.space << SECTOR_SHIFT)) { Could this allow maliciously large or small chunk requirements to bypass capacity validation? > chunksize =3D le32_to_cpu(sb->chunksize); > if (!is_power_of_2(chunksize)) { > pr_err("md/llbitmap: %s: chunksize not a power of 2", [ ... ] > @@ -1022,8 +1029,9 @@ static int llbitmap_read_sb(struct llbitmap *llbitm= ap) > =20 > llbitmap->barrier_idle =3D DEFAULT_BARRIER_IDLE; > llbitmap->chunksize =3D chunksize; > - llbitmap->chunks =3D DIV_ROUND_UP_SECTOR_T(mddev->resync_max_sectors, c= hunksize); > + llbitmap->chunks =3D DIV_ROUND_UP_SECTOR_T(sync_size, chunksize); [Severity: High] Is it safe to compute llbitmap->chunks using the unvalidated sync_size here? Since the validation check above still uses mddev->resync_max_sectors, an artificially large sync_size will cause llbitmap->chunks to exceed the allocated metadata space. This breaks the capacity validation invariant. Could this cause __llbitmap_flush() and llbitmap_write_page() to write bitm= ap data out-of-bounds on the underlying disk, overwriting adjacent partitions? Additionally, if sync_size is artificially small, the llbitmap->pctl array allocation (nr_pages) will be undersized. When IO arrives at valid offsets bounded by the block layer capacity, fast paths like llbitmap_start_write() could calculate a page_start index that exceeds nr_pages: drivers/md/md-llbitmap.c:llbitmap_start_write() { ... int page_start =3D (start + BITMAP_DATA_OFFSET) >> PAGE_SHIFT; int page_end =3D (end + BITMAP_DATA_OFFSET) >> PAGE_SHIFT; while (page_start <=3D page_end) { llbitmap_raise_barrier(llbitmap, page_start); page_start++; } ... } Could this lead to an out-of-bounds memory access on the pctl array when calling llbitmap_raise_barrier()? > llbitmap->chunkshift =3D ffz(~chunksize); > + llbitmap->sync_size =3D sync_size; > ret =3D llbitmap_cache_pages(llbitmap); --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260801172519.2982= [email protected]?part=3D9