Skip to content

Commit c5760fe

Browse files
Matthew Wilcox (Oracle)mehmetb0
Matthew Wilcox (Oracle)
authored andcommitted
mm: open-code page_folio() in dump_page()
BugLink: https://bugs.launchpad.net/bugs/2096827 commit 6a7de1b 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]>
1 parent 5f5ec37 commit c5760fe

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

mm/debug.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,22 @@ static void __dump_page(const struct page *page)
107107
{
108108
struct folio *foliop, folio;
109109
struct page precise;
110+
unsigned long head;
110111
unsigned long pfn = page_to_pfn(page);
111112
unsigned long idx, nr_pages = 1;
112113
int loops = 5;
113114

114115
again:
115116
memcpy(&precise, page, sizeof(*page));
116-
foliop = page_folio(&precise);
117-
if (foliop == (struct folio *)&precise) {
117+
head = precise.compound_head;
118+
if ((head & 1) == 0) {
119+
foliop = (struct folio *)&precise;
118120
idx = 0;
119121
if (!folio_test_large(foliop))
120122
goto dump;
121123
foliop = (struct folio *)page;
122124
} else {
125+
foliop = (struct folio *)(head - 1);
123126
idx = folio_page_idx(foliop, page);
124127
}
125128

0 commit comments

Comments
 (0)