forked from Minki/linux
kasan: add proper page allocator tests
The currently existing page allocator tests rely on kmalloc fallback with large sizes that is only present for SLUB. Add proper tests that use alloc/free_pages(). Link: https://linux-review.googlesource.com/id/Ia173d5a1b215fe6b2548d814ef0f4433cf983570 Link: https://lkml.kernel.org/r/a2648930e55ff75b8e700f2e0d905c2b55a67483.1610733117.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Reviewed-by: Marco Elver <elver@google.com> Reviewed-by: Alexander Potapenko <glider@google.com> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Branislav Rankov <Branislav.Rankov@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Evgenii Stepanov <eugenis@google.com> Cc: Kevin Brodsky <kevin.brodsky@arm.com> Cc: Peter Collingbourne <pcc@google.com> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
611806b4bf
commit
858bdeb046
@ -147,6 +147,12 @@ static void kmalloc_node_oob_right(struct kunit *test)
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* These kmalloc_pagealloc_* tests try allocating a memory chunk that doesn't
|
||||
* fit into a slab cache and therefore is allocated via the page allocator
|
||||
* fallback. Since this kind of fallback is only implemented for SLUB, these
|
||||
* tests are limited to that allocator.
|
||||
*/
|
||||
static void kmalloc_pagealloc_oob_right(struct kunit *test)
|
||||
{
|
||||
char *ptr;
|
||||
@ -154,14 +160,11 @@ static void kmalloc_pagealloc_oob_right(struct kunit *test)
|
||||
|
||||
KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_SLUB);
|
||||
|
||||
/*
|
||||
* Allocate a chunk that does not fit into a SLUB cache to trigger
|
||||
* the page allocator fallback.
|
||||
*/
|
||||
ptr = kmalloc(size, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
|
||||
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0);
|
||||
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
@ -174,8 +177,8 @@ static void kmalloc_pagealloc_uaf(struct kunit *test)
|
||||
|
||||
ptr = kmalloc(size, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
|
||||
|
||||
kfree(ptr);
|
||||
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = 0);
|
||||
}
|
||||
|
||||
@ -192,6 +195,42 @@ static void kmalloc_pagealloc_invalid_free(struct kunit *test)
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, kfree(ptr + 1));
|
||||
}
|
||||
|
||||
static void pagealloc_oob_right(struct kunit *test)
|
||||
{
|
||||
char *ptr;
|
||||
struct page *pages;
|
||||
size_t order = 4;
|
||||
size_t size = (1UL << (PAGE_SHIFT + order));
|
||||
|
||||
/*
|
||||
* With generic KASAN page allocations have no redzones, thus
|
||||
* out-of-bounds detection is not guaranteed.
|
||||
* See https://bugzilla.kernel.org/show_bug.cgi?id=210503.
|
||||
*/
|
||||
KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
|
||||
|
||||
pages = alloc_pages(GFP_KERNEL, order);
|
||||
ptr = page_address(pages);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
|
||||
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
|
||||
free_pages((unsigned long)ptr, order);
|
||||
}
|
||||
|
||||
static void pagealloc_uaf(struct kunit *test)
|
||||
{
|
||||
char *ptr;
|
||||
struct page *pages;
|
||||
size_t order = 4;
|
||||
|
||||
pages = alloc_pages(GFP_KERNEL, order);
|
||||
ptr = page_address(pages);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
|
||||
free_pages((unsigned long)ptr, order);
|
||||
|
||||
KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = 0);
|
||||
}
|
||||
|
||||
static void kmalloc_large_oob_right(struct kunit *test)
|
||||
{
|
||||
char *ptr;
|
||||
@ -903,6 +942,8 @@ static struct kunit_case kasan_kunit_test_cases[] = {
|
||||
KUNIT_CASE(kmalloc_pagealloc_oob_right),
|
||||
KUNIT_CASE(kmalloc_pagealloc_uaf),
|
||||
KUNIT_CASE(kmalloc_pagealloc_invalid_free),
|
||||
KUNIT_CASE(pagealloc_oob_right),
|
||||
KUNIT_CASE(pagealloc_uaf),
|
||||
KUNIT_CASE(kmalloc_large_oob_right),
|
||||
KUNIT_CASE(kmalloc_oob_krealloc_more),
|
||||
KUNIT_CASE(kmalloc_oob_krealloc_less),
|
||||
|
Loading…
Reference in New Issue
Block a user