Unverified Commit 8ad8b727 authored by Nick Hu's avatar Nick Hu Committed by Palmer Dabbelt
Browse files

riscv: Add KASAN support



This patch ports the feature Kernel Address SANitizer (KASAN).

Note: The start address of shadow memory is at the beginning of kernel
space, which is 2^64 - (2^39 / 2) in SV39. The size of the kernel space is
2^38 bytes so the size of shadow memory should be 2^38 / 8. Thus, the
shadow memory would not overlap with the fixmap area.

There are currently two limitations in this port,

1. RV64 only: KASAN need large address space for extra shadow memory
region.

2. KASAN can't debug the modules since the modules are allocated in VMALLOC
area. We mapped the shadow memory, which corresponding to VMALLOC area, to
the kasan_early_shadow_page because we don't have enough physical space for
all the shadow memory corresponding to VMALLOC area.

Signed-off-by: default avatarNick Hu <nickhu@andestech.com>
Reported-by: default avatarGreentime Hu <green.hu@gmail.com>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 57ee58e3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ config RISCV
	select HAVE_ARCH_MMAP_RND_BITS if MMU
	select ARCH_HAS_GCOV_PROFILE_ALL
	select HAVE_COPY_THREAD_TLS
	select HAVE_ARCH_KASAN if MMU && 64BIT

config ARCH_MMAP_RND_BITS_MIN
	default 18 if 64BIT
+27 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2019 Andes Technology Corporation */

#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H

#ifndef __ASSEMBLY__

#ifdef CONFIG_KASAN

#include <asm/pgtable.h>

#define KASAN_SHADOW_SCALE_SHIFT	3

#define KASAN_SHADOW_SIZE	(UL(1) << (38 - KASAN_SHADOW_SCALE_SHIFT))
#define KASAN_SHADOW_START	0xffffffc000000000 /* 2^64 - 2^38 */
#define KASAN_SHADOW_END	(KASAN_SHADOW_START + KASAN_SHADOW_SIZE)

#define KASAN_SHADOW_OFFSET	(KASAN_SHADOW_END - (1ULL << \
					(64 - KASAN_SHADOW_SCALE_SHIFT)))

void kasan_init(void);
asmlinkage void kasan_early_init(void);

#endif
#endif
#endif /* __ASM_KASAN_H */
+5 −0
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
	return (unsigned long)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
}

static inline struct page *pud_page(pud_t pud)
{
	return pfn_to_page(pud_val(pud) >> _PAGE_PFN_SHIFT);
}

#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))

static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+9 −0
Original line number Diff line number Diff line
@@ -11,8 +11,17 @@

#define __HAVE_ARCH_MEMSET
extern asmlinkage void *memset(void *, int, size_t);
extern asmlinkage void *__memset(void *, int, size_t);

#define __HAVE_ARCH_MEMCPY
extern asmlinkage void *memcpy(void *, const void *, size_t);
extern asmlinkage void *__memcpy(void *, const void *, size_t);

/* For those files which don't want to check by kasan. */
#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)

#define memcpy(dst, src, len) __memcpy(dst, src, len)
#define memset(s, c, n) __memset(s, c, n)

#endif
#endif /* _ASM_RISCV_STRING_H */
+3 −0
Original line number Diff line number Diff line
@@ -121,6 +121,9 @@ clear_bss_done:
	sw zero, TASK_TI_CPU(tp)
	la sp, init_thread_union + THREAD_SIZE

#ifdef CONFIG_KASAN
	call kasan_early_init
#endif
	/* Start the kernel */
	call parse_dtb
	tail start_kernel
Loading