diff --git a/include/linux/poison.h b/include/linux/poison.h index 4a27153574e283..51334edec50681 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -30,7 +30,11 @@ #define TIMER_ENTRY_STATIC ((void *) 0x300 + POISON_POINTER_DELTA) /********** mm/debug-pagealloc.c **********/ +#ifdef CONFIG_PAGE_POISONING_ZERO +#define PAGE_POISON 0x00 +#else #define PAGE_POISON 0xaa +#endif /********** mm/page_alloc.c ************/ diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug index ddf71d7cb6ba8d..20973e865fb46c 100644 --- a/mm/Kconfig.debug +++ b/mm/Kconfig.debug @@ -62,3 +62,16 @@ config PAGE_POISONING_NO_SANITY If you are only interested in sanitization, say Y. Otherwise say N. + +config PAGE_POISONING_ZERO + bool "Use zero for poisoning instead of random data" + depends on !HIBERNATION + depends on PAGE_POISONING + ---help--- + Instead of using the existing poison value, fill the pages with + zeros. This makes it harder to detect when errors are occuring + due to sanitization but the zeroing at free means that it is + no longer necessary to write zeros when GFP_ZERO is used on + allocation. + + If unsure, say N diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8987902186b842..ada80bb7a65915 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1387,6 +1387,12 @@ static inline int check_new_page(struct page *page) return 0; } +static inline bool should_zero(void) +{ + return !IS_ENABLED(CONFIG_PAGE_POISONING_ZERO) || + !page_poisoning_enabled(); +} + static int prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags, int alloc_flags) { @@ -1406,7 +1412,7 @@ static int prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags, kernel_map_pages(page, 1 << order, 1); kasan_alloc_pages(page, order); - if (gfp_flags & __GFP_ZERO) + if (should_zero() && gfp_flags & __GFP_ZERO) for (i = 0; i < (1 << order); i++) clear_highpage(page + i);