From 04ad9908b0319210ef9e33775dd8a2adb0951586 Mon Sep 17 00:00:00 2001 From: Zi Yan Date: Thu, 9 Jul 2026 14:06:04 -0400 Subject: [PATCH] mm/page_alloc: make sure tail_page->private is zero at page free time Any code using tail_page->private of a folio, a compound page or a high-order page is supposed to reset it after use, otherwise ->private data can leak to new page user and cause unexpected issues. Add a bad_page() check at page free path for it. Link: https://lore.kernel.org/20260709-keep-subpage-private-zero-at-free-v3-4-7e4fe155f5b9@nvidia.com Signed-off-by: Zi Yan Reviewed-by: Vlastimil Babka (SUSE) Acked-by: David Hildenbrand (Arm) Cc: Alistair Popple Cc: Baolin Wang Cc: Barry Song Cc: Brendan Jackman Cc: Brendan Jackman Cc: Dennis Zhou Cc: Dev Jain Cc: Johannes Weiner Cc: Lance Yang Cc: Liam R. Howlett Cc: Lorenzo Stoakes Cc: Michal Hocko Cc: Mike Rapoport Cc: Nico Pache Cc: Ryan Roberts Cc: Suren Baghdasaryan Cc: Tejun Heo Signed-off-by: Andrew Morton --- mm/page_alloc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a63733dac659..cc45dfe89c76 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1377,15 +1377,23 @@ static __always_inline bool __free_pages_prepare(struct page *page, #endif } for (i = 1; i < (1 << order); i++) { + struct page *tail_page = page + i; + if (compound) - bad += free_tail_page_prepare(page, page + i); + bad += free_tail_page_prepare(page, tail_page); if (is_check_pages_enabled()) { - if (free_page_is_bad(page + i)) { + if (free_page_is_bad(tail_page)) { + bad++; + continue; + } + + if (tail_page->private) { + bad_page(tail_page, "nonzero private"); bad++; continue; } } - (page + i)->flags.f &= ~PAGE_FLAGS_CHECK_AT_PREP; + tail_page->flags.f &= ~PAGE_FLAGS_CHECK_AT_PREP; } } if (folio_test_anon(folio)) {