aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Ryabinin <a.ryabinin@samsung.com>2015-02-13 17:39:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-14 00:21:41 -0500
commitc420f167db8c799d69fe43a801c58a7f02e9d57c (patch)
tree3dff6731a0459d554ae81d07b557721d6b72f773
parent393f203f5fd54421fddb1e2a263f64d3876eeadb (diff)
kasan: enable stack instrumentation
Stack instrumentation allows to detect out of bounds memory accesses for variables allocated on stack. Compiler adds redzones around every variable on stack and poisons redzones in function's prologue. Such approach significantly increases stack usage, so all in-kernel stacks size were doubled. Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Konstantin Serebryany <kcc@google.com> Cc: Dmitry Chernenkov <dmitryc@google.com> Signed-off-by: Andrey Konovalov <adech.fo@gmail.com> Cc: Yuri Gribov <tetra2005@gmail.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: Christoph Lameter <cl@linux.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/include/asm/page_64_types.h12
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/mm/kasan_init_64.c11
-rw-r--r--include/linux/init_task.h8
-rw-r--r--mm/kasan/kasan.h9
-rw-r--r--mm/kasan/report.c6
-rw-r--r--scripts/Makefile.kasan1
7 files changed, 44 insertions, 5 deletions
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index 75450b2c7be4..4edd53b79a81 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -1,17 +1,23 @@
1#ifndef _ASM_X86_PAGE_64_DEFS_H 1#ifndef _ASM_X86_PAGE_64_DEFS_H
2#define _ASM_X86_PAGE_64_DEFS_H 2#define _ASM_X86_PAGE_64_DEFS_H
3 3
4#define THREAD_SIZE_ORDER 2 4#ifdef CONFIG_KASAN
5#define KASAN_STACK_ORDER 1
6#else
7#define KASAN_STACK_ORDER 0
8#endif
9
10#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER)
5#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) 11#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
6#define CURRENT_MASK (~(THREAD_SIZE - 1)) 12#define CURRENT_MASK (~(THREAD_SIZE - 1))
7 13
8#define EXCEPTION_STACK_ORDER 0 14#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER)
9#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) 15#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
10 16
11#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) 17#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
12#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) 18#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
13 19
14#define IRQ_STACK_ORDER 2 20#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
15#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) 21#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
16 22
17#define DOUBLEFAULT_STACK 1 23#define DOUBLEFAULT_STACK 1
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index b13b70634124..cdb1b70ddad0 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -17,6 +17,8 @@ CFLAGS_REMOVE_early_printk.o = -pg
17endif 17endif
18 18
19KASAN_SANITIZE_head$(BITS).o := n 19KASAN_SANITIZE_head$(BITS).o := n
20KASAN_SANITIZE_dumpstack.o := n
21KASAN_SANITIZE_dumpstack_$(BITS).o := n
20 22
21CFLAGS_irq.o := -I$(src)/../include/asm/trace 23CFLAGS_irq.o := -I$(src)/../include/asm/trace
22 24
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 3e4d9a1a39fa..53508708b7aa 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -189,11 +189,18 @@ void __init kasan_init(void)
189 if (map_range(&pfn_mapped[i])) 189 if (map_range(&pfn_mapped[i]))
190 panic("kasan: unable to allocate shadow!"); 190 panic("kasan: unable to allocate shadow!");
191 } 191 }
192
193 populate_zero_shadow(kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM), 192 populate_zero_shadow(kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
194 (void *)KASAN_SHADOW_END); 193 kasan_mem_to_shadow((void *)__START_KERNEL_map));
194
195 vmemmap_populate((unsigned long)kasan_mem_to_shadow(_stext),
196 (unsigned long)kasan_mem_to_shadow(_end),
197 NUMA_NO_NODE);
198
199 populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_VADDR),
200 (void *)KASAN_SHADOW_END);
195 201
196 memset(kasan_zero_page, 0, PAGE_SIZE); 202 memset(kasan_zero_page, 0, PAGE_SIZE);
197 203
198 load_cr3(init_level4_pgt); 204 load_cr3(init_level4_pgt);
205 init_task.kasan_depth = 0;
199} 206}
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d3d43ecf148c..696d22312b31 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -175,6 +175,13 @@ extern struct task_group root_task_group;
175# define INIT_NUMA_BALANCING(tsk) 175# define INIT_NUMA_BALANCING(tsk)
176#endif 176#endif
177 177
178#ifdef CONFIG_KASAN
179# define INIT_KASAN(tsk) \
180 .kasan_depth = 1,
181#else
182# define INIT_KASAN(tsk)
183#endif
184
178/* 185/*
179 * INIT_TASK is used to set up the first task table, touch at 186 * INIT_TASK is used to set up the first task table, touch at
180 * your own risk!. Base=0, limit=0x1fffff (=2MB) 187 * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -250,6 +257,7 @@ extern struct task_group root_task_group;
250 INIT_RT_MUTEXES(tsk) \ 257 INIT_RT_MUTEXES(tsk) \
251 INIT_VTIME(tsk) \ 258 INIT_VTIME(tsk) \
252 INIT_NUMA_BALANCING(tsk) \ 259 INIT_NUMA_BALANCING(tsk) \
260 INIT_KASAN(tsk) \
253} 261}
254 262
255 263
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 5b052ab40cf9..1fcc1d81a9cf 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -12,6 +12,15 @@
12#define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ 12#define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */
13#define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */ 13#define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */
14 14
15/*
16 * Stack redzone shadow values
17 * (Those are compiler's ABI, don't change them)
18 */
19#define KASAN_STACK_LEFT 0xF1
20#define KASAN_STACK_MID 0xF2
21#define KASAN_STACK_RIGHT 0xF3
22#define KASAN_STACK_PARTIAL 0xF4
23
15 24
16struct kasan_access_info { 25struct kasan_access_info {
17 const void *access_addr; 26 const void *access_addr;
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 2760edb4d0a8..866732ef3db3 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -64,6 +64,12 @@ static void print_error_description(struct kasan_access_info *info)
64 case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: 64 case 0 ... KASAN_SHADOW_SCALE_SIZE - 1:
65 bug_type = "out of bounds access"; 65 bug_type = "out of bounds access";
66 break; 66 break;
67 case KASAN_STACK_LEFT:
68 case KASAN_STACK_MID:
69 case KASAN_STACK_RIGHT:
70 case KASAN_STACK_PARTIAL:
71 bug_type = "out of bounds on stack";
72 break;
67 } 73 }
68 74
69 pr_err("BUG: KASan: %s in %pS at addr %p\n", 75 pr_err("BUG: KASan: %s in %pS at addr %p\n",
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 7acd6faa0335..2163b8cc446e 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -9,6 +9,7 @@ CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
9 9
10CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \ 10CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
11 -fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \ 11 -fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \
12 --param asan-stack=1 \
12 --param asan-instrumentation-with-call-threshold=$(call_threshold)) 13 --param asan-instrumentation-with-call-threshold=$(call_threshold))
13 14
14ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),) 15ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),)