From: sashiko-bot@kernel.org
To: "David Hildenbrand (Arm)" <david@kernel.org>
Cc: "Alexander Gordeev" <agordeev@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
linux-s390@vger.kernel.org, "Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [PATCH 05/10] x86/mm: stop marking vmemmap as SECTION_INFO
Date: Wed, 08 Jul 2026 15:10:03 +0000 [thread overview]
Message-ID: <20260708151003.843391F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260708-bootmem_info_part2-v1-5-156ce4986598@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Kernel page table pages (PGD, P4D, PUD, PMD) permanently leak during memory hot-remove due to mismatched reference counting.
- [High] Kernel page table pages and vmemmap physical pages are synchronously freed to the buddy allocator BEFORE their corresponding higher-level page table entries are cleared, causing a Use-After-Free.
--
--- Patch [5]: [PATCH 05/10] x86/mm: stop marking vmemmap as SECTION_INFO ---
commit 9fecf5a2d51cb3529c85d6e643dda7a25adb7fd1
Author: David Hildenbrand (Arm) <david@kernel.org>
x86/mm: stop marking vmemmap as SECTION_INFO
This commit removes the remaining vmemmap bootmem registration machinery
which is no longer required. It stops marking vmemmap pages as
SECTION_INFO and allows free_vmemmap_pages() to free reserved pages
directly.
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index 320e742b0bb3f..82bb0384b8ab0 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1024,19 +1024,12 @@ static void __meminit free_vmemmap_pages(struct page *page, unsigned int order,
[ ... ]
> - } else {
> + else
> __free_pages(page, order);
> - }
> }
>
> static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
[Severity: High]
This is a pre-existing issue, but does this function (and others like it)
free the PTE table page before clearing the corresponding PMD entry?
Looking at free_pte_table(), free_pagetable() frees the PTE table page
to the buddy allocator. Only after this does the code acquire
init_mm.page_table_lock and call pmd_clear() to unlink it:
arch/x86/mm/init_64.c:free_pte_table() {
...
free_pagetable(pmd_page(*pmd));
spin_lock(&init_mm.page_table_lock);
pmd_clear(pmd);
...
}
Because init_mm is shared globally, could a hardware MMU page table walk
on another CPU speculatively traverse the still-valid PMD entry into
the freed page before the pmd_clear() occurs?
If the buddy allocator reallocates this page to userspace and it is
populated with user-controlled data, could this lead to a use-after-free
and potential privilege escalation?
A similar pattern appears to exist in remove_pte_table() for physical
vmemmap pages.
[ ... ]
> @@ -1593,12 +1586,8 @@ void register_page_bootmem_memmap(unsigned long section_nr,
> p4d_t *p4d;
> pud_t *pud;
> pmd_t *pmd;
> - unsigned int nr_pmd_pages;
> - struct page *page;
>
> for (; addr < end; addr = next) {
[Severity: High]
This isn't a bug introduced by this patch, but does this loop permanently
leak kernel page table pages during memory hot-remove?
When vmemmap is mapped with 4KB base pages (e.g., if huge pages are not
used), the loop steps forward by PAGE_SIZE. In each iteration, it calls
get_page_bootmem() on the intermediate page table pages (like pgd_page
and pmd_page), unconditionally incrementing the page refcount.
Because a PMD covers 2MB, the loop visits the exact same pmd_page 512
times, incrementing its refcount by 512.
However, during memory hot-remove, when the page table is emptied,
free_pmd_table() calls free_pagetable() exactly once, which decrements
the refcount by only 1:
arch/x86/mm/init_64.c:free_pmd_table() {
...
free_pagetable(pud_page(*pud));
...
}
Will the refcount fail to reach 0, permanently leaking the page table
page during hot-remove?
> - pte_t *pte = NULL;
> -
> pgd = pgd_offset_k(addr);
> if (pgd_none(*pgd)) {
> next = (addr + PAGE_SIZE) & PAGE_MASK;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260708-bootmem_info_part2-v1-0-156ce4986598@kernel.org?part=5
next prev parent reply other threads:[~2026-07-08 15:10 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 14:10 [PATCH 00/10] mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE (Part 2) David Hildenbrand (Arm)
2026-07-08 14:10 ` [PATCH 01/10] x86/mm: drop order parameter from free_pagetable() David Hildenbrand (Arm)
2026-07-08 14:22 ` sashiko-bot
2026-07-08 15:15 ` David Hildenbrand (Arm)
2026-07-09 2:32 ` Muchun Song
2026-07-08 14:10 ` [PATCH 02/10] mm: provide free_reserved_pages(), removing x86 variant David Hildenbrand (Arm)
2026-07-08 15:13 ` David Hildenbrand (Arm)
2026-07-09 6:19 ` Muchun Song
2026-07-08 14:10 ` [PATCH 03/10] s390/mm: use free_reserved_pages() in vmem_free_pages() David Hildenbrand (Arm)
2026-07-09 6:12 ` Heiko Carstens
2026-07-09 6:21 ` Muchun Song
2026-07-08 14:10 ` [PATCH 04/10] mm/bootmem_info: allow calling free_bootmem_page() on pages without a bootmem_type David Hildenbrand (Arm)
2026-07-08 14:53 ` sashiko-bot
2026-07-09 6:23 ` Muchun Song
2026-07-08 14:11 ` [PATCH 05/10] x86/mm: stop marking vmemmap as SECTION_INFO David Hildenbrand (Arm)
2026-07-08 15:10 ` sashiko-bot [this message]
2026-07-08 15:20 ` David Hildenbrand (Arm)
2026-07-08 14:11 ` [PATCH 06/10] x86/mm: stop marking page tables as MIX_SECTION_INFO David Hildenbrand (Arm)
2026-07-08 15:24 ` sashiko-bot
2026-07-08 15:27 ` David Hildenbrand (Arm)
2026-07-08 14:11 ` [PATCH 07/10] x86/mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE David Hildenbrand (Arm)
2026-07-08 15:38 ` sashiko-bot
2026-07-08 14:11 ` [PATCH 08/10] mm/hugetlb_vmemmap: remove bootmem_info leftovers David Hildenbrand (Arm)
2026-07-09 6:26 ` Muchun Song
2026-07-08 14:11 ` [PATCH 09/10] mm/sparse: remove bootmem_info.h include David Hildenbrand (Arm)
2026-07-09 6:26 ` Muchun Song
2026-07-08 14:11 ` [PATCH 10/10] mm/bootmem_info: remove CONFIG_HAVE_BOOTMEM_INFO_NODE David Hildenbrand (Arm)
2026-07-09 6:27 ` Muchun Song
2026-07-08 21:24 ` [PATCH 00/10] mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE (Part 2) Andrew Morton
2026-07-09 9:36 ` Mike Rapoport
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=20260708151003.843391F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=david@kernel.org \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.