lkdtm/heap: Add init_on_alloc tests

Add SLAB and page allocator tests for init_on_alloc. Testing for
init_on_free was already happening via the poisoning tests.

Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210623203936.3151093-10-keescook@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Kees Cook 2021-06-23 13:39:36 -07:00 committed by Greg Kroah-Hartman
parent b61ce4d81b
commit 37a0ca7f3e
5 changed files with 72 additions and 0 deletions

View File

@ -127,6 +127,8 @@ static const struct crashtype crashtypes[] = {
CRASHTYPE(READ_AFTER_FREE),
CRASHTYPE(WRITE_BUDDY_AFTER_FREE),
CRASHTYPE(READ_BUDDY_AFTER_FREE),
CRASHTYPE(SLAB_INIT_ON_ALLOC),
CRASHTYPE(BUDDY_INIT_ON_ALLOC),
CRASHTYPE(SLAB_FREE_DOUBLE),
CRASHTYPE(SLAB_FREE_CROSS),
CRASHTYPE(SLAB_FREE_PAGE),

View File

@ -174,6 +174,71 @@ void lkdtm_READ_BUDDY_AFTER_FREE(void)
kfree(val);
}
void lkdtm_SLAB_INIT_ON_ALLOC(void)
{
u8 *first;
u8 *val;
first = kmalloc(512, GFP_KERNEL);
if (!first) {
pr_info("Unable to allocate 512 bytes the first time.\n");
return;
}
memset(first, 0xAB, 512);
kfree(first);
val = kmalloc(512, GFP_KERNEL);
if (!val) {
pr_info("Unable to allocate 512 bytes the second time.\n");
return;
}
if (val != first) {
pr_warn("Reallocation missed clobbered memory.\n");
}
if (memchr(val, 0xAB, 512) == NULL) {
pr_info("Memory appears initialized (%x, no earlier values)\n", *val);
} else {
pr_err("FAIL: Slab was not initialized\n");
pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc");
}
kfree(val);
}
void lkdtm_BUDDY_INIT_ON_ALLOC(void)
{
u8 *first;
u8 *val;
first = (u8 *)__get_free_page(GFP_KERNEL);
if (!first) {
pr_info("Unable to allocate first free page\n");
return;
}
memset(first, 0xAB, PAGE_SIZE);
free_page((unsigned long)first);
val = (u8 *)__get_free_page(GFP_KERNEL);
if (!val) {
pr_info("Unable to allocate second free page\n");
return;
}
if (val != first) {
pr_warn("Reallocation missed clobbered memory.\n");
}
if (memchr(val, 0xAB, PAGE_SIZE) == NULL) {
pr_info("Memory appears initialized (%x, no earlier values)\n", *val);
} else {
pr_err("FAIL: Slab was not initialized\n");
pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc");
}
free_page((unsigned long)val);
}
void lkdtm_SLAB_FREE_DOUBLE(void)
{
int *val;

View File

@ -86,6 +86,8 @@ void lkdtm_WRITE_AFTER_FREE(void);
void lkdtm_READ_AFTER_FREE(void);
void lkdtm_WRITE_BUDDY_AFTER_FREE(void);
void lkdtm_READ_BUDDY_AFTER_FREE(void);
void lkdtm_SLAB_INIT_ON_ALLOC(void);
void lkdtm_BUDDY_INIT_ON_ALLOC(void);
void lkdtm_SLAB_FREE_DOUBLE(void);
void lkdtm_SLAB_FREE_CROSS(void);
void lkdtm_SLAB_FREE_PAGE(void);

View File

@ -5,3 +5,4 @@ CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y

View File

@ -21,6 +21,8 @@ VMALLOC_LINEAR_OVERFLOW
READ_AFTER_FREE call trace:|Memory correctly poisoned
#WRITE_BUDDY_AFTER_FREE Corrupts memory on failure
READ_BUDDY_AFTER_FREE call trace:|Memory correctly poisoned
SLAB_INIT_ON_ALLOC Memory appears initialized
BUDDY_INIT_ON_ALLOC Memory appears initialized
SLAB_FREE_DOUBLE
SLAB_FREE_CROSS
SLAB_FREE_PAGE