Thread (50 messages) flat view 50 messages, 4 authors, 4d ago

Re: [PATCH v4 10/25] md/md-llbitmap: allocate page controls independently

From: sashiko-bot@kernel.org
Date: 2026-08-01 17:47:56

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

New issues:
- [Critical] Unflushed zeroed pages create a memory-disk inconsistency, leading to silent parity corruption on crash/reboot after an array resize.

Pre-existing issues:
- [High] Incomplete fix for out-of-bounds array access on `pctl` during maximum in-place array growth.
--
--- Patch [10]: [PATCH v4 10/25] md/md-llbitmap: allocate page controls independently ---
commit 325d92bcc68f880073f4c6b96714394c0bafe835
Author: Yu Kuai [off-list ref]

md/md-llbitmap: allocate page controls independently

This patch allocates one llbitmap page-control object at a time and frees
each object through the same model. It also updates llbitmap_read_page() to
return a zeroed page without reading from disk when the page index is beyond
the current bitmap size.
quoted hunk ↗ jump to hunk
diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c
index 3417da288e994..d12b3dba6ae15 100644
--- a/drivers/md/md-llbitmap.c
+++ b/drivers/md/md-llbitmap.c
[ ... ]
quoted hunk ↗ jump to hunk
@@ -526,6 +532,8 @@ static struct page *llbitmap_read_page(struct llbitmap *llbitmap, int idx)
 	page = alloc_page(GFP_NOIO | __GFP_ZERO);
 	if (!page)
 		return ERR_PTR(-ENOMEM);
+	if (idx >= llbitmap_used_pages(llbitmap, llbitmap->chunks))
+		return page;
[Severity: Critical]
Does this new bypass create a memory-disk inconsistency?

By returning a zeroed page in memory without reading or flushing to disk, the
physical disk is left containing uninitialized garbage. If the array is
reshaped and expands into this pre-allocated region, a crash before the new
region is fully written could expose the disk garbage to the state machine on
the subsequent boot. If the garbage matches states like BitClean, resync
might be incorrectly skipped for the new region.
 
 	rdev_for_each(rdev, mddev) {
[ ... ]
+static unsigned int llbitmap_reserved_pages(struct llbitmap *llbitmap)
+{
+	return DIV_ROUND_UP(llbitmap->mddev->bitmap_info.space << SECTOR_SHIFT,
+			    PAGE_SIZE);
+}
[Severity: High]
This isn't a bug introduced by this patch, but does this calculation
under-allocate the array by one page for the maximum allowed chunk size?

This calculation omits BITMAP_DATA_OFFSET. Because llbitmap_resize() allows
chunks to grow up to space << SECTOR_SHIFT, the maximum used_pages (which
correctly includes the offset) can exceed reserved_pages by 1.

When pos approaches the maximum allowed chunks in llbitmap_write():

    pos += BITMAP_DATA_OFFSET;
    idx = pos >> PAGE_SHIFT;

the offset causes idx to exceed the pre-allocated bounds of the pctl array,
which could lead to out-of-bounds memory corruption.
+
+static int llbitmap_alloc_pages(struct llbitmap *llbitmap)
+{
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260801172519.2982121-1-yukuai@kernel.org?part=10
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help