mirror of
https://github.com/lkl/linux.git
synced 2025-12-20 00:23:14 +09:00
lkl: add KASAN support
To enable KASAN support the kasan=yes parameters should be passed to the host build, e.g.: make -C tools/lkl kasan=yes Signed-off-by: Eugene Rodionov <rodionov@google.com> Signed-off-by: Octavian Purdila <tavip@google.com>
This commit is contained in:
committed by
Octavian Purdila
parent
7deea5c421
commit
facd006081
@@ -40,6 +40,7 @@ config LKL
|
||||
select UACCESS_MEMCPY
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select HAVE_ARCH_KASAN
|
||||
|
||||
config OUTPUT_FORMAT
|
||||
string "Output format"
|
||||
@@ -105,3 +106,13 @@ config RAID6_PQ_BENCHMARK
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
if KASAN
|
||||
config KASAN_SHADOW_OFFSET
|
||||
hex "KASAN shadow offset"
|
||||
default "0"
|
||||
|
||||
config KASAN_SHADOW_SIZE
|
||||
hex "KASAN shadow size"
|
||||
default "0"
|
||||
endif
|
||||
|
||||
|
||||
36
arch/lkl/include/asm/kasan.h
Normal file
36
arch/lkl/include/asm/kasan.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_LKL_KASAN_H
|
||||
#define _ASM_LKL_KASAN_H
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
#include <linux/const.h>
|
||||
#include <linux/pgtable.h>
|
||||
|
||||
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
|
||||
#define KASAN_SHADOW_SIZE _AC(CONFIG_KASAN_SHADOW_SIZE, UL)
|
||||
|
||||
#define KASAN_SHADOW_SCALE_SHIFT 3
|
||||
|
||||
#define KASAN_SHADOW_START KASAN_SHADOW_OFFSET
|
||||
#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
|
||||
|
||||
extern int kasan_init(void);
|
||||
extern int kasan_cleanup(void);
|
||||
extern void kasan_unpoison_stack(void);
|
||||
#else
|
||||
static inline int kasan_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kasan_cleanup(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void kasan_unpoison_stack(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,15 +1,13 @@
|
||||
#ifndef _LKL_PGTABLE_H
|
||||
#define _LKL_PGTABLE_H
|
||||
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
|
||||
/*
|
||||
* (C) Copyright 2000-2002, Greg Ungerer <gerg@snapgear.com>
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define pgd_present(pgd) (1)
|
||||
@@ -51,4 +49,7 @@ extern void *empty_zero_page;
|
||||
#define KMAP_START 0
|
||||
#define KMAP_END 0xffffffff
|
||||
|
||||
#define PTRS_PER_PTE 0
|
||||
#define PTRS_PER_PMD 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _ASM_LKL_SCHED_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/kasan.h>
|
||||
#include <uapi/asm/host_ops.h>
|
||||
|
||||
static inline void thread_sched_jb(void)
|
||||
@@ -11,6 +12,11 @@ static inline void thread_sched_jb(void)
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
lkl_ops->jmp_buf_set(¤t_thread_info()->sched_jb,
|
||||
schedule);
|
||||
/*
|
||||
* The previous call to setjmp/longjmp won't unwind the stack
|
||||
* and, as a result, shadow memory will remain poisoned.
|
||||
*/
|
||||
kasan_unpoison_stack();
|
||||
} else {
|
||||
lkl_bug("thread_sched_jb() can be used only for host task");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
extra-y := vmlinux.lds
|
||||
|
||||
KASAN_SANITIZE_init.o := n
|
||||
KASAN_SANITIZE_stacktrace.o := n
|
||||
|
||||
obj-y = setup.o threads.o irq.o time.o syscalls.o misc.o console.o \
|
||||
syscalls_32.o cpu.o init.o stacktrace.o
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <asm/host_ops.h>
|
||||
#include <asm/kasan.h>
|
||||
|
||||
int lkl_init(struct lkl_host_operations *ops)
|
||||
{
|
||||
lkl_ops = ops;
|
||||
|
||||
return kasan_init();
|
||||
}
|
||||
|
||||
void lkl_cleanup(void)
|
||||
{
|
||||
if (kasan_cleanup() < 0)
|
||||
lkl_printf("kasan: failed to cleanup\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,10 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||
lkl_ops->sem_down(_prev->sched_sem);
|
||||
}
|
||||
|
||||
if (_prev->dead)
|
||||
if (_prev->dead) {
|
||||
kasan_unpoison_stack();
|
||||
lkl_ops->thread_exit();
|
||||
}
|
||||
|
||||
return abs_prev;
|
||||
}
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
|
||||
KASAN_SANITIZE_kasan.o := n
|
||||
|
||||
obj-y = bootmem.o
|
||||
obj-$(CONFIG_KASAN) += kasan.o
|
||||
|
||||
38
arch/lkl/mm/kasan.c
Normal file
38
arch/lkl/mm/kasan.c
Normal file
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <asm/host_ops.h>
|
||||
|
||||
void kasan_unpoison_stack(void)
|
||||
{
|
||||
void *stack = NULL;
|
||||
unsigned long stack_size;
|
||||
|
||||
if (lkl_ops->thread_stack)
|
||||
stack = lkl_ops->thread_stack(&stack_size);
|
||||
|
||||
if (stack)
|
||||
kasan_unpoison_range(stack, stack_size);
|
||||
}
|
||||
|
||||
int kasan_cleanup(void)
|
||||
{
|
||||
return lkl_ops->munmap((void *)KASAN_SHADOW_OFFSET, KASAN_SHADOW_SIZE);
|
||||
}
|
||||
|
||||
int kasan_init(void)
|
||||
{
|
||||
void *offset = (void *)KASAN_SHADOW_OFFSET;
|
||||
int prot = LKL_PROT_READ | LKL_PROT_WRITE;
|
||||
|
||||
/* reserve address range for KASAN shadow memory */
|
||||
if (lkl_ops->mmap(offset, KASAN_SHADOW_SIZE, prot) != offset) {
|
||||
lkl_printf("kasan: failed to map shadow memory\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
init_task.kasan_depth = 0;
|
||||
pr_info("KernelAddressSanitizer initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
POSIX_HOSTS=elf64 elf32
|
||||
KASAN_HOSTS=elf64-x86-64
|
||||
NT_HOSTS=pe
|
||||
|
||||
define set_autoconf_var
|
||||
@@ -117,6 +118,22 @@ define 64bit_host
|
||||
$(call set_kernel_config,64BIT,y)
|
||||
endef
|
||||
|
||||
define kasan_x86_64
|
||||
$(call set_autoconf_var,KASAN_SHADOW_OFFSET,0x0000200000000000)
|
||||
$(call set_kernel_config,KASAN_SHADOW_OFFSET,0x0000200000000000)
|
||||
$(call set_autoconf_var,KASAN_SHADOW_SIZE,0x0000100000000000)
|
||||
$(call set_kernel_config,KASAN_SHADOW_SIZE,0x0000100000000000)
|
||||
endef
|
||||
|
||||
define kasan_enable
|
||||
$(call set_autoconf_var,KASAN,y)
|
||||
$(call set_kernel_config,KASAN,y)
|
||||
# default is 20 which should be 1MB but observed 8MB of reserved
|
||||
# memory - half of what we use
|
||||
$(call set_kernel_config,STACK_HASH_ORDER,12)
|
||||
$(if $(filter $(1),elf64-x86-64),$(call kasan_x86_64))
|
||||
endef
|
||||
|
||||
define do_autoconf
|
||||
export CROSS_COMPILE := $(CROSS_COMPILE)
|
||||
export CC := $(CROSS_COMPILE)gcc
|
||||
@@ -131,6 +148,7 @@ define do_autoconf
|
||||
$(if $(filter $(EXEC_FMT),elf64-s390),$(call s390_host))
|
||||
$(if $(filter $(EXEC_FMT),$(POSIX_HOSTS)),$(call posix_host,$(LD_FMT)))
|
||||
$(if $(filter $(EXEC_FMT),$(NT_HOSTS)),$(call nt_host,$(LD_FMT)))
|
||||
$(if $(and $(filter yes,$(kasan)),$(filter $(LD_FMT),$(KASAN_HOSTS))),$(call kasan_enable,$(LD_FMT)))
|
||||
endef
|
||||
|
||||
export do_autoconf
|
||||
|
||||
Reference in New Issue
Block a user