Linux RAID subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yu Kuai" <yukuai@kernel.org>
Cc: yukuai@fygo.io, linux-raid@vger.kernel.org
Subject: Re: [PATCH v3 05/21] md/md-llbitmap: track bitmap sync_size explicitly
Date: Tue, 28 Jul 2026 09:16:05 +0000	[thread overview]
Message-ID: <20260728091605.ABDB51F000E9@smtp.kernel.org> (raw)
In-Reply-To: <c7c477a0e0203fd6ce98e49cd0cc1382b1786f4d.1785206690.git.yukuai@fygo.io>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Critical] Missing upper and lower bounds validation on the newly tracked `sync_size` read from the superblock leads to arbitrary out-of-bounds memory accesses.
- [High] Validation of `chunksize` in `llbitmap_read_sb` incorrectly uses `mddev->resync_max_sectors` instead of `sync_size`.
- [High] Torn read of the 64-bit `sync_size` field leading to superblock corruption and memory allocation bugs on reboot, along with unprotected bitmap geometry updates.

Pre-existing issues:
- [High] A teardown race condition in `llbitmap_destroy()` fails to prevent a workqueue task from re-arming a timer after it has been deleted, causing a UAF.
--

--- Patch [5]: [PATCH v3 05/21] md/md-llbitmap: track bitmap sync_size explicitly ---
commit e1b87a51dfe616ddb9c0f12bcc69bdac5d5044d5
Author: Yu Kuai <yukuai@fygo.io>

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 f0c20afa354eb..e3500a1a52c07 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;
>  	}
>  
> +	sync_size = le64_to_cpu(sb->sync_size);

[Severity: Critical]
Is it necessary to validate the upper and lower bounds of the sync_size
read from the superblock here?

If sync_size is manipulated to be near U64_MAX, calculating nr_pages
might truncate to a small 32-bit integer, while chunks remains huge.
Could this cause llbitmap_init_state() to perform massive out-of-bounds
writes into the undersized pctl array?

Alternatively, if sync_size is too small, nr_pages is small, but incoming
IO up to mddev->resync_max_sectors calculates a page_start that exceeds
the bounds of pctl:

drivers/md/md-llbitmap.c:llbitmap_start_write() {
    ...
    int page_start = (start + BITMAP_DATA_OFFSET) >> PAGE_SHIFT;
    ...
    while (page_start <= page_end) {
        llbitmap_raise_barrier(llbitmap, page_start);
    ...
}

Could this lead to out-of-bounds memory accesses if a maliciously crafted
bitmap superblock is mounted?


[Severity: High]
Should the chunksize validation further down in llbitmap_read_sb() be
updated to use sync_size as well?

    if (chunksize < DIV_ROUND_UP_SECTOR_T(mddev->resync_max_sectors,
                                          mddev->bitmap_info.space << SECTOR_SHIFT)) {

If an array is grown and stopped before the bitmap is resized,
mddev->resync_max_sectors reflects the new larger size, but the bitmap
superblock retains the old sync_size and chunksize.

Will checking if the old chunksize can cover the new resync_max_sectors
cause a false failure and abort bitmap initialization in this scenario?

> +	if (!sync_size)
> +		sync_size = mddev->resync_max_sectors;
>  	chunksize = le32_to_cpu(sb->chunksize);
>  	if (!is_power_of_2(chunksize)) {

[ ... ]

> @@ -1153,6 +1161,7 @@ static int llbitmap_resize(struct mddev *mddev, sector_t blocks, int chunksize)
>  	llbitmap->chunkshift = ffz(~chunksize);
>  	llbitmap->chunksize = chunksize;
>  	llbitmap->chunks = chunks;
> +	llbitmap->sync_size = blocks;
>  
>  	return 0;
>  }

[Severity: High]
Are these updates to the 64-bit sync_size and geometry variables
adequately protected from concurrent access?

Unlike the legacy bitmap which uses mddev->pers->quiesce() to pause IO,
llbitmap_resize() does not pause IO. This allows active IO paths to read
a mix of old and new geometry values.

Additionally, llbitmap_update_sb() concurrently reads llbitmap->sync_size
locklessly:

drivers/md/md-llbitmap.c:llbitmap_update_sb() {
    ...
    sb->sync_size = cpu_to_le64(llbitmap->sync_size);
    ...
}

On 32-bit platforms, might this race result in a torn read of the 64-bit
value, causing a corrupted value to be written to the disk superblock?

[ ... ]

This is a pre-existing issue, but does the teardown sequence in
llbitmap_destroy() allow the pending_timer to be re-armed after deletion?

In llbitmap_destroy():

    timer_delete_sync(&llbitmap->pending_timer);
    flush_workqueue(md_llbitmap_io_wq);

If the daemon work is concurrently running in the workqueue,
timer_delete_sync() returns immediately because the timer is no longer
pending.

The workqueue is then flushed, but at the end of the worker function
md_llbitmap_daemon_fn(), it unconditionally re-arms the timer:

    if (restart)
        mod_timer(&llbitmap->pending_timer,
                  jiffies + mddev->bitmap_info.daemon_sleep * HZ);

When llbitmap is subsequently freed, will the re-armed timer dereference
the freed memory when it fires?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1785206690.git.yukuai@fygo.io?part=5

  reply	other threads:[~2026-07-28  9:16 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28  8:49 [PATCH v3 00/21] md/md-llbitmap: support reshape for RAID10 and RAID5 Yu Kuai
2026-07-28  8:49 ` [PATCH v3 01/21] md/raid5: round bitmap stripes with sector division Yu Kuai
2026-07-28  9:03   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 02/21] md: add exact bitmap mapping and reshape hooks Yu Kuai
2026-07-28  8:49 ` [PATCH v3 03/21] md: skip bitmap accounting for empty write ranges Yu Kuai
2026-07-28  8:49 ` [PATCH v3 04/21] md: add helper to split bios at reshape offset Yu Kuai
2026-07-28  9:03   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 05/21] md/md-llbitmap: track bitmap sync_size explicitly Yu Kuai
2026-07-28  9:16   ` sashiko-bot [this message]
2026-07-28  8:49 ` [PATCH v3 06/21] md/md-llbitmap: allocate page controls independently Yu Kuai
2026-07-28  9:06   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 07/21] md/md-llbitmap: grow the page cache in place for reshape Yu Kuai
2026-07-28  9:09   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 08/21] md/md-llbitmap: track target reshape geometry fields Yu Kuai
2026-07-28  9:12   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 09/21] md/md-llbitmap: finish reshape geometry Yu Kuai
2026-07-28  9:14   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 10/21] md/md-llbitmap: refuse reshape while llbitmap still needs sync Yu Kuai
2026-07-28  9:12   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 11/21] md/md-llbitmap: add reshape range mapping helpers Yu Kuai
2026-07-28  9:11   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 12/21] md/md-llbitmap: don't skip reshape ranges from bitmap state Yu Kuai
2026-07-28  8:49 ` [PATCH v3 13/21] md/md-llbitmap: remap checkpointed bits as reshape progresses Yu Kuai
2026-07-28  9:06   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 14/21] md/md-llbitmap: clamp state-machine walks to tracked bits Yu Kuai
2026-07-28  9:13   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 15/21] md/raid10: reject llbitmap reshape when md chunk shrinks Yu Kuai
2026-07-28  9:15   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 16/21] md/raid10: wire llbitmap reshape lifecycle Yu Kuai
2026-07-28  9:22   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 17/21] md/raid10: split reshape bios before bitmap accounting Yu Kuai
2026-07-28  9:15   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 18/21] md/raid5: add exact old and new llbitmap mapping helpers Yu Kuai
2026-07-28  9:25   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 19/21] md/raid5: reject llbitmap reshape when md chunk shrinks Yu Kuai
2026-07-28  9:22   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 20/21] md/raid5: wire llbitmap reshape lifecycle Yu Kuai
2026-07-28  9:21   ` sashiko-bot
2026-07-28  8:49 ` [PATCH v3 21/21] md/raid5: split reshape bios before bitmap accounting Yu Kuai
2026-07-28  9:26   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260728091605.ABDB51F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=yukuai@fygo.io \
    --cc=yukuai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox