[PATCH] mm/compaction: guard move_freelist_head() against invalid freepage

From: Giorgi Tchankvetadze

Date: Mon Jun 01 2026 - 06:28:27 EST


In fast_isolate_freepages(), freepage is declared uninitialized and
is only assigned a valid page pointer if list_for_each_entry_reverse
exits via break. If the loop runs to completion (all pages in the
freelist have pfn < min_pfn), freepage holds the list head sentinel
and high_pfn remains zero, so the high_pfn fallback does not update
it either.

The subsequent unconditional call to move_freelist_head(freelist,
freepage) then passes the sentinel as a page pointer, which is
invalid.

Guard move_freelist_head() inside the existing 'if (page)' block
where freepage is guaranteed to refer to a real page.

This issue was identified via Coccinelle (use_after_iter.cocci).

Fixes: 5a811889de10 ("mm, compaction: use free lists to quickly locate a migration target")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Giorgi Tchankvetadze <giorgitchankvetadze1997@xxxxxxxxx>
---
mm/compaction.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index 8f664fb09f24..320c082420fd 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1611,11 +1611,10 @@ static void fast_isolate_freepages(struct compact_control *cc)
freepage = page;
}

- /* Reorder to so a future search skips recent pages */
- move_freelist_head(freelist, freepage);
-
- /* Isolate the page if available */
if (page) {
+ /* Reorder so a future search skips recent pages */
+ move_freelist_head(freelist, freepage);
+ /* Isolate the page if available */
if (__isolate_free_page(page, order)) {
set_page_private(page, order);
nr_isolated = 1 << order;
--
2.52.0