Skip to content

Commit

Permalink
mm: open-code page_folio() in dump_page()
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/2096827

commit 6a7de1bf218d75f27f68d6a3f5ae1eb7332b941e upstream.

page_folio() calls page_fixed_fake_head() which will misidentify this page
as being a fake head and load off the end of 'precise'.  We may have a
pointer to a fake head, but that's OK because it contains the right
information for dump_page().

gcc-15 is smart enough to catch this with -Warray-bounds:

In function 'page_fixed_fake_head',
    inlined from '_compound_head' at ../include/linux/page-flags.h:251:24,
    inlined from '__dump_page' at ../mm/debug.c:123:11:
../include/asm-generic/rwonce.h:44:26: warning: array subscript 9 is outside
+array bounds of 'struct page[1]' [-Warray-bounds=]

Link: https://lkml.kernel.org/r/[email protected]
Fixes: fae7d83 ("mm: add __dump_folio()")
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
Reported-by: Kees Cook <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Koichiro Den <[email protected]>
  • Loading branch information
Matthew Wilcox (Oracle) authored and mehmetb0 committed Feb 14, 2025
1 parent 5f5ec37 commit c5760fe
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions mm/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,22 @@ static void __dump_page(const struct page *page)
{
struct folio *foliop, folio;
struct page precise;
unsigned long head;
unsigned long pfn = page_to_pfn(page);
unsigned long idx, nr_pages = 1;
int loops = 5;

again:
memcpy(&precise, page, sizeof(*page));
foliop = page_folio(&precise);
if (foliop == (struct folio *)&precise) {
head = precise.compound_head;
if ((head & 1) == 0) {
foliop = (struct folio *)&precise;
idx = 0;
if (!folio_test_large(foliop))
goto dump;
foliop = (struct folio *)page;
} else {
foliop = (struct folio *)(head - 1);
idx = folio_page_idx(foliop, page);
}

Expand Down

0 comments on commit c5760fe

Please sign in to comment.