On Mon, May 13, 2024 at 09:33:57PM -0700, Kees Cook wrote: > 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=] > > (Not noted in this warning is that the code passes through page_folio() > _Generic macro.) > > It doesn't like that it can see that "precise" is exactly one page, so > looking at page[1] later is going to freak out. I suspect this may be > "impossible" at run-time, but I'm not 100% sure. Regardless, the compiler > can't tell. Actually, I'm not sure that I can tell that it's impossible. I think we just need to open-code page_folio() here so that we don't get into the fixed fake head palaver. Something like this, although it's only compile-tested. diff --git a/mm/debug.c b/mm/debug.c index e3ff3ac19fa1..47ba8b0a4872 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -110,19 +110,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); }