Commit 9c4f6ebc authored by Kees Cook's avatar Kees Cook Committed by Greg Kroah-Hartman
Browse files

lkdtm/heap: Add vmalloc linear overflow test



Similar to the existing slab overflow and stack exhaustion tests, add
VMALLOC_LINEAR_OVERFLOW (and rename the slab test SLAB_LINEAR_OVERFLOW).
Additionally unmarks the test as destructive. (It should be safe in the
face of misbehavior.)

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210623203936.3151093-6-keescook@chromium.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a15676ac
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -120,7 +120,8 @@ static const struct crashtype crashtypes[] = {
	CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
	CRASHTYPE(FORTIFY_OBJECT),
	CRASHTYPE(FORTIFY_SUBOBJECT),
	CRASHTYPE(OVERWRITE_ALLOCATION),
	CRASHTYPE(SLAB_LINEAR_OVERFLOW),
	CRASHTYPE(VMALLOC_LINEAR_OVERFLOW),
	CRASHTYPE(WRITE_AFTER_FREE),
	CRASHTYPE(READ_AFTER_FREE),
	CRASHTYPE(WRITE_BUDDY_AFTER_FREE),
+21 −1
Original line number Diff line number Diff line
@@ -5,24 +5,44 @@
 */
#include "lkdtm.h"
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>

static struct kmem_cache *double_free_cache;
static struct kmem_cache *a_cache;
static struct kmem_cache *b_cache;

/*
 * If there aren't guard pages, it's likely that a consecutive allocation will
 * let us overflow into the second allocation without overwriting something real.
 */
void lkdtm_VMALLOC_LINEAR_OVERFLOW(void)
{
	char *one, *two;

	one = vzalloc(PAGE_SIZE);
	two = vzalloc(PAGE_SIZE);

	pr_info("Attempting vmalloc linear overflow ...\n");
	memset(one, 0xAA, PAGE_SIZE + 1);

	vfree(two);
	vfree(one);
}

/*
 * This tries to stay within the next largest power-of-2 kmalloc cache
 * to avoid actually overwriting anything important if it's not detected
 * correctly.
 */
void lkdtm_OVERWRITE_ALLOCATION(void)
void lkdtm_SLAB_LINEAR_OVERFLOW(void)
{
	size_t len = 1020;
	u32 *data = kmalloc(len, GFP_KERNEL);
	if (!data)
		return;

	pr_info("Attempting slab linear overflow ...\n");
	data[1024 / sizeof(u32)] = 0x12345678;
	kfree(data);
}
+2 −1
Original line number Diff line number Diff line
@@ -39,7 +39,8 @@ void lkdtm_FORTIFY_SUBOBJECT(void);
/* heap.c */
void __init lkdtm_heap_init(void);
void __exit lkdtm_heap_exit(void);
void lkdtm_OVERWRITE_ALLOCATION(void);
void lkdtm_VMALLOC_LINEAR_OVERFLOW(void);
void lkdtm_SLAB_LINEAR_OVERFLOW(void);
void lkdtm_WRITE_AFTER_FREE(void);
void lkdtm_READ_AFTER_FREE(void);
void lkdtm_WRITE_BUDDY_AFTER_FREE(void);
+2 −1
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@ UNSET_SMEP pinned CR4 bits changed:
DOUBLE_FAULT
CORRUPT_PAC
UNALIGNED_LOAD_STORE_WRITE
#OVERWRITE_ALLOCATION Corrupts memory on failure
SLAB_LINEAR_OVERFLOW
VMALLOC_LINEAR_OVERFLOW
#WRITE_AFTER_FREE Corrupts memory on failure
READ_AFTER_FREE call trace:|Memory correctly poisoned
#WRITE_BUDDY_AFTER_FREE Corrupts memory on failure