mm: page_alloc: check the order of compound page even when the order is zero
authorHyesoo Yu <hyesoo.yu@samsung.com>
Mon, 23 Oct 2023 08:32:16 +0000 (17:32 +0900)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 25 Oct 2023 23:47:14 +0000 (16:47 -0700)
For compound pages, the head sets the PG_head flag and the tail sets the
compound_head to indicate the head page.  If a user allocates a compound
page and frees it with a different order, the compound page information
will not be properly initialized.  To detect this problem,
compound_order(page) and the order argument are compared, but this is not
checked when the order argument is zero.  That error should be checked
regardless of the order.

Link: https://lkml.kernel.org/r/20231023083217.1866451-1-hyesoo.yu@samsung.com
Signed-off-by: Hyesoo Yu <hyesoo.yu@samsung.com>
Reviewed-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/page_alloc.c

index aa90758..5f46c7f 100644 (file)
@@ -1079,6 +1079,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
        int bad = 0;
        bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
        bool init = want_init_on_free();
+       bool compound = PageCompound(page);
 
        VM_BUG_ON_PAGE(PageTail(page), page);
 
@@ -1097,16 +1098,15 @@ static __always_inline bool free_pages_prepare(struct page *page,
                return false;
        }
 
+       VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
+
        /*
         * Check tail pages before head page information is cleared to
         * avoid checking PageCompound for order-0 pages.
         */
        if (unlikely(order)) {
-               bool compound = PageCompound(page);
                int i;
 
-               VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
-
                if (compound)
                        page[1].flags &= ~PAGE_FLAGS_SECOND;
                for (i = 1; i < (1 << order); i++) {