BACKPORT: FROMGIT: kasan: disable freed user page poisoning with HW tags
Poisoning freed pages protects against kernel use-after-free. The likelihood of such a bug involving kernel pages is significantly higher than that for user pages. At the same time, poisoning freed pages can impose a significant performance cost, which cannot always be justified for user pages given the lower probability of finding a bug. Therefore, disable freed user page poisoning when using HW tags. We identify "user" pages via the flag set GFP_HIGHUSER_MOVABLE, which indicates a strong likelihood of not being directly accessible to the kernel. Signed-off-by: Peter Collingbourne <pcc@google.com> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> Link: https://linux-review.googlesource.com/id/I716846e2de8ef179f44e835770df7e6307be96c9 Link: https://lore.kernel.org/r/20210602235230.3928842-5-pcc@google.com Signed-off-by: Will Deacon <will@kernel.org> (cherry picked from commit c275c5c6d50a0518cdb0584e85905d10e7cefc6e https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/mte) [pcc: adjust definition of new GFP flag for compatibility with GFP_CMA] Change-Id: I716846e2de8ef179f44e835770df7e6307be96c9 Bug: 186816853
This commit is contained in:

committed by
Sandeep Patil

parent
339a43c9bd
commit
0c24ee770c
@@ -407,11 +407,12 @@ static DEFINE_STATIC_KEY_TRUE(deferred_pages);
|
||||
* on-demand allocation and then freed again before the deferred pages
|
||||
* initialization is done, but this is not likely to happen.
|
||||
*/
|
||||
static inline bool should_skip_kasan_poison(fpi_t fpi_flags)
|
||||
static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
|
||||
{
|
||||
return static_branch_unlikely(&deferred_pages) ||
|
||||
(!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
|
||||
(fpi_flags & FPI_SKIP_KASAN_POISON));
|
||||
(fpi_flags & FPI_SKIP_KASAN_POISON)) ||
|
||||
PageSkipKASanPoison(page);
|
||||
}
|
||||
|
||||
/* Returns true if the struct page for the pfn is uninitialised */
|
||||
@@ -462,10 +463,11 @@ defer_init(int nid, unsigned long pfn, unsigned long end_pfn)
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
static inline bool should_skip_kasan_poison(fpi_t fpi_flags)
|
||||
static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
|
||||
{
|
||||
return (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
|
||||
(fpi_flags & FPI_SKIP_KASAN_POISON));
|
||||
(fpi_flags & FPI_SKIP_KASAN_POISON)) ||
|
||||
PageSkipKASanPoison(page);
|
||||
}
|
||||
|
||||
static inline bool early_page_uninitialised(unsigned long pfn)
|
||||
@@ -1275,7 +1277,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
|
||||
unsigned int order, bool check_free, fpi_t fpi_flags)
|
||||
{
|
||||
int bad = 0;
|
||||
bool skip_kasan_poison = should_skip_kasan_poison(fpi_flags);
|
||||
bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
|
||||
|
||||
VM_BUG_ON_PAGE(PageTail(page), page);
|
||||
|
||||
|
Reference in New Issue
Block a user