Supporting VMAP_STACK with KASAN_VMALLOC is straightforward: - clear the shadow region of vmapped stacks when swapping them in - tweak Kconfig to allow VMAP_STACK to be turned on with KASAN
Unified · Split
| @@ -843,16 +843,17 @@ config HAVE_ARCH_VMAP_STACK · 842 unmodified lines | ||
| 843 | 843 | config VMAP_STACK |
| 844 | 844 | default y |
| 845 | 845 | bool "Use a virtually-mapped stack" |
| 846 | − depends on HAVE_ARCH_VMAP_STACK && !KASAN | |
| 846 | + depends on HAVE_ARCH_VMAP_STACK | |
| 847 | + depends on !KASAN || KASAN_VMALLOC | |
| 847 | 848 | ---help--- |
| 848 | 849 | Enable this if you want the use virtually-mapped kernel stacks |
| 849 | 850 | with guard pages. This causes kernel stack overflows to be |
| 850 | 851 | caught immediately rather than causing difficult-to-diagnose |
| 851 | 852 | corruption. |
| 852 | 853 | |
| 853 | − This is presently incompatible with KASAN because KASAN expects | |
| 854 | − the stack to map directly to the KASAN shadow map using a formula | |
| 855 | − that is incorrect if the stack is in vmalloc space. | |
| 854 | + To use this with KASAN, the architecture must support backing | |
| 855 | + virtual mappings with real shadow memory, and KASAN_VMALLOC must | |
| 856 | + be enabled. | |
| 856 | 857 | |
| 857 | 858 | config ARCH_OPTIONAL_KERNEL_RWX |
| 858 | 859 | def_bool n |
| @@ -93,6 +93,7 @@ · 92 unmodified lines | ||
| 93 | 93 | #include <linux/livepatch.h> |
| 94 | 94 | #include <linux/thread_info.h> |
| 95 | 95 | #include <linux/stackleak.h> |
| 96 | +#include <linux/kasan.h> | |
| 96 | 97 | |
| 97 | 98 | #include <asm/pgtable.h> |
| 98 | 99 | #include <asm/pgalloc.h> |
| @@ -223,6 +224,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) · 124 unmodified lines | ||
| 223 | 224 | if (!s) |
| 224 | 225 | continue; |
| 225 | 226 | |
| 227 | + /* Clear the KASAN shadow of the stack. */ | |
| 228 | + kasan_unpoison_shadow(s->addr, THREAD_SIZE); | |
| 229 | + | |
| 226 | 230 | /* Clear stale pointers from reused stack. */ |
| 227 | 231 | memset(s->addr, 0, THREAD_SIZE); |
| 228 | 232 | |