Re: [PATCH 3/4] md/md-llbitmap: unmap sb page before freeing it
[email protected] Sun, 19 Jul 2026 14:57:46 +0000
| Newsgroups | org.kernel.vger.linux-raid |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: Pre-existing issues: - [High] Integer Truncation of 64-bit event counter causes spurious array recoveries on 32-bit architectures - [High] Use-After-Free in teardown sequence due to re-arming timer - [High] Lost Write to `sb->sync_size` during superblock load - [High] Integer overflow causing division by zero when calculating minimum chunksize - [High] Integer overflow in page count calculation leading to out-of-bounds heap access -- --- Patch [3]: [PATCH 3/4] md/md-llbitmap: unmap sb page before freeing it --- commit 6be442dfef7ad93b44cadb093b6d078f152b2522 Author: Mykola Marzhan <[email protected]> md/md-llbitmap: unmap sb page before freeing it The patch swaps __free_page(sb_page) and kunmap_local(sb) in llbitmap_read_sb() to avoid unmapping a page after it has been freed. > diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c > index 2d3de38f9b784..2d6c7ad0923a1 100644 > --- a/drivers/md/md-llbitmap.c > +++ b/drivers/md/md-llbitmap.c > @@ -1035,8 +1035,8 @@ static int llbitmap_read_sb(struct llbitmap *llbitmap) > ret = llbitmap_cache_pages(llbitmap); [Severity: High] This is a pre-existing issue, but is there an integer overflow when calculating nr_pages on 32-bit architectures inside llbitmap_cache_pages()? drivers/md/md-llbitmap.c:llbitmap_cache_pages() { ... unsigned int nr_pages = DIV_ROUND_UP(llbitmap->chunks + BITMAP_DATA_OFFSET, PAGE_SIZE); ... llbitmap->pctl = kmalloc_array(nr_pages, sizeof(void *), GFP_KERNEL | __GFP_ZERO); ... } If a malicious superblock sets a high resync_max_sectors and chunksize of 2, could llbitmap->chunks + BITMAP_DATA_OFFSET overflow to 0? Would this result in a zero-sized array allocation and subsequent out-of-bounds access? > > out_put_page: > - __free_page(sb_page); > kunmap_local(sb); > + __free_page(sb_page); [Severity: High] This is a pre-existing issue, but is the update to sb->sync_size lost here? Earlier in llbitmap_read_sb(), sb->sync_size is updated: sb->sync_size = cpu_to_le64(mddev->resync_max_sectors); Since sb_page is unmapped and unconditionally freed here without being written back to disk or retained in memory, does the runtime state lose this update? > return ret; > } There are a few other pre-existing issues in this file that might need attention. [Severity: High] This is a pre-existing issue, but does assigning the 64-bit sb->events to the unsigned long events variable truncate it on 32-bit architectures? drivers/md/md-llbitmap.c:llbitmap_read_sb() { unsigned long events; ... events = le64_to_cpu(sb->events); if (events < mddev->events) { ... } } When the 64-bit counter exceeds 4 billion, would this truncation cause a spurious full array resync by incorrectly making the bitmap appear stale? [Severity: High] This is a pre-existing issue, but can the timer fire on freed memory during teardown? drivers/md/md-llbitmap.c:llbitmap_destroy() { ... timer_delete_sync(&llbitmap->pending_timer); flush_workqueue(md_llbitmap_io_wq); ... } drivers/md/md-llbitmap.c:md_llbitmap_daemon_fn() { ... if (restart) mod_timer(&llbitmap->pending_timer, ...); } If llbitmap_destroy() deletes the timer and flushes the workqueue, could md_llbitmap_daemon_fn() unconditionally re-arm the timer at the end of its execution, leading to a use-after-free when llbitmap is subsequently freed? [Severity: High] This is a pre-existing issue, but can this overflow and cause a division by zero panic? drivers/md/md-llbitmap.c:llbitmap_read_sb() { ... if (chunksize < DIV_ROUND_UP_SECTOR_T(mddev->resync_max_sectors, mddev->bitmap_info.space << SECTOR_SHIFT)) { ... } On 32-bit systems, mddev->bitmap_info.space is a 32-bit unsigned long. If an attacker-controlled superblock sets a value where space << 9 overflows to 0, would DIV_ROUND_UP_SECTOR_T divide by zero? -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=3