kasan: various fixes
Subsystems (5)
cover kasan: various fixes
This patchset contains various fixes for KASAN. That includes:
1. Improving reported bug types.
Making KASAN distinguish and report the following types of bugs:
slab-out-of-bounds, stack-out-of-bounds, global-out-of-bounds use-after-free, null-ptr-deref, user-memory-access, wild-memory-access.
2. Making references to the tool name consistent.
We decided to use KASAN as the short name of the tool since a lot of people already use it, and KernelAddressSanitizer as the full name to be consistent with the userspace AddressSantizer.
Andrey Konovalov (7):
kasan: update reported bug types for not user nor kernel memory
accesses
kasan: update reported bug types for kernel memory accesses
kasan: accurately determine the type of the bad access
kasan: update log messages
kasan: various fixes in documentation
kasan: move KASAN_SANITIZE in arch/x86/boot/Makefile
kasan: update reference to kasan prototype repo
Documentation/kasan.txt | 43 +++++++++++------------ arch/x86/boot/Makefile | 4 +-- arch/x86/mm/kasan_init_64.c | 2 +- mm/kasan/kasan.c | 12 ++----- mm/kasan/kasan.h | 3 -- mm/kasan/report.c | 84 +++++++++++++++++++++++++++------------------ 6 files changed, 78 insertions(+), 70 deletions(-)
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/7 kasan: update reported bug types for not user nor kernel memory accesses
Each access with address lower than kasan_shadow_to_mem(KASAN_SHADOW_START) is reported as user-memory-access. This is not always true, the accessed address might not be in user space. Fix this by reporting such accesses as null-ptr-derefs or wild-memory-accesses.
There's another reason for this change. For userspace ASan we have a bunch of systems that analyze error types for the purpose of classification and deduplication. Sooner of later we will write them to KASAN as well. Then clearly and explicitly stated error types will bring value.
--- mm/kasan/kasan.c | 8 +------- mm/kasan/kasan.h | 3 --- mm/kasan/report.c | 45 +++++++++++++++++++++++---------------------- 3 files changed, 24 insertions(+), 32 deletions(-)
mm/kasan/kasan.c +1 -7
@@ -236,18 +236,12 @@ static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size) static __always_inline void check_memory_region(unsigned long addr,size_t size,bool write) { -struct kasan_access_info info; -if (unlikely (size ==0 ))return ;if (unlikely ((void *)addr <kasan_shadow_to_mem ((void *)KASAN_SHADOW_START ))) { - info.access_addr = (void *)addr; - info.access_size = size; - info.is_write = write; - info.ip = _RET_IP_; -kasan_report_user_access (&info); +kasan_report (addr, size, write, _RET_IP_);return ; }
mm/kasan/kasan.h +0 -3
@@ -54,9 +54,6 @@ struct kasan_global {#endif }; -void kasan_report_error (struct kasan_access_info *info); -void kasan_report_user_access (struct kasan_access_info *info); -static inline const void *kasan_shadow_to_mem (const void *shadow_addr) { return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
mm/kasan/report.c +23 -22
63 lines not on this page · raw message
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/7 kasan: update reported bug types for kernel memory accesses
In reply to Andrey KonovalovUpdate the names of the bad access types to better reflect the type of the access that happended and make these error types "literals" that can be used for classification and deduplication in scripts.
--- mm/kasan/report.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
mm/kasan/report.c +11 -7
@@ -48,7 +48,7 @@ static const void *find_first_bad_addr(const void *addr, size_t size)static void print_error_description (struct kasan_access_info *info) { -const char *bug_type ="unknown crash" ; +const char *bug_type ="unknown-crash" ;u8 shadow_val; info->first_bad_addr = find_first_bad_addr(info->access_addr,
@@ -57,21 +57,25 @@ static void print_error_description(struct kasan_access_info *info) shadow_val = *(u8 *)kasan_mem_to_shadow (info->first_bad_addr);switch (shadow_val) { -case KASAN_FREE_PAGE : -case KASAN_KMALLOC_FREE : - bug_type ="use after free" ; + case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: + bug_type ="out-of-bounds" ;break ;case KASAN_PAGE_REDZONE :case KASAN_KMALLOC_REDZONE : + bug_type ="slab-out-of-bounds" ; +break ;case KASAN_GLOBAL_REDZONE : - case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: - bug_type ="out of bounds access" ; + bug_type ="global-out-of-bounds" ;break ;case KASAN_STACK_LEFT :case KASAN_STACK_MID :case KASAN_STACK_RIGHT :case KASAN_STACK_PARTIAL : - bug_type ="out of bounds on stack" ; + bug_type ="stack-out-of-bounds" ; +break ; +case KASAN_FREE_PAGE : +case KASAN_KMALLOC_FREE : + bug_type ="use-after-free" ;break ; }
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/7 kasan: accurately determine the type of the bad access
In reply to Andrey KonovalovMakes KASAN accurately determine the type of the bad access. If the shadow byte value is in the [0, KASAN_SHADOW_SCALE_SIZE) range we can look at the next shadow byte to determine the type of the access.
--- mm/kasan/report.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
mm/kasan/report.c +14 -3
@@ -49,15 +49,26 @@ static const void *find_first_bad_addr(const void *addr, size_t size)static void print_error_description (struct kasan_access_info *info) {const char *bug_type ="unknown-crash" ; -u8 shadow_val; +u8 *shadow_addr; info->first_bad_addr =find_first_bad_addr (info->access_addr, info->access_size); - shadow_val = *(u8 *)kasan_mem_to_shadow (info->first_bad_addr); + shadow_addr = (u8 *)kasan_mem_to_shadow (info->first_bad_addr); -switch (shadow_val) { +/* +* If shadow byte value is in [0, KASAN_SHADOW_SCALE_SIZE) we can look +* at the next shadow byte to determine the type of the bad access. +*/ +if (*shadow_addr >0 && *shadow_addr <=KASAN_SHADOW_SCALE_SIZE -1 ) + shadow_addr++; + +switch (*shadow_addr) { case 0 ... KASAN_SHADOW_SCALE_SIZE - 1: +/* +* In theory it's still possible to see these shadow values +* due to a data race in the kernel code. +*/ bug_type ="out-of-bounds" ;break ;case KASAN_PAGE_REDZONE :
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/7 kasan: update log messages
In reply to Andrey KonovalovWe decided to use KASAN as the short name of the tool and KernelAddressSanitizer as the full one.
Update log messages according to that.
--- arch/x86/mm/kasan_init_64.c | 2 +- mm/kasan/kasan.c | 2 +- mm/kasan/report.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/mm/kasan_init_64.c +1 -1
@@ -126,5 +126,5 @@ void __init kasan_init(void)__flush_tlb_all (); init_task.kasan_depth =0 ; -pr_info ("Kernel address sanitizer initialized\n" ); +pr_info ("KernelAddressSanitizer initialized\n" ); }
mm/kasan/kasan.c +1 -1
@@ -519,7 +519,7 @@ static int kasan_mem_notifier(struct notifier_block *nb,static int __init kasan_memhotplug_init (void ) { -pr_err ("WARNING: KASan doesn't support memory hot-add\n" ); +pr_err ("WARNING: KASAN doesn't support memory hot-add\n" );pr_err ("Memory hot-add will be disabled\n" );hotplug_memory_notifier (kasan_mem_notifier,0 );
mm/kasan/report.c +2 -2
@@ -90,7 +90,7 @@ static void print_error_description(struct kasan_access_info *info)break ; } -pr_err ("BUG: KASan: %s in %pS at addr %p\n" , +pr_err ("BUG: KASAN: %s in %pS at addr %p\n" , bug_type, (void *)info->ip, info->access_addr); pr_err("%s of size %zu by task %s/%d\n",
@@ -213,7 +213,7 @@ static void kasan_report_error(struct kasan_access_info *info) bug_type ="user-memory-access" ; else bug_type ="wild-memory-access" ; -pr_err ("BUG: KASan: %s on address %p\n" , +pr_err ("BUG: KASAN: %s on address %p\n" , bug_type, info->access_addr); pr_err("%s of size %zu by task %s/%d\n", info->is_write ? "Write" : "Read",
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 5/7 kasan: various fixes in documentation
In reply to Andrey Konovalov--- Documentation/kasan.txt | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-)
Documentation/kasan.txt +22 -21
@@ -1,32 +1,31 @@ -Kernel address sanitizer -================ +KernelAddressSanitizer (KASAN) +============================== 0. Overview =========== -Kernel Address sanitizer (KASan) is a dynamic memory error detector. It provides +KernelAddressSANitizer (KASAN) is a dynamic memory error detector. It provides a fast and comprehensive solution for finding use-after-free and out-of-bounds bugs. -KASan uses compile-time instrumentation for checking every memory access, -therefore you will need a gcc version of 4.9.2 or later. KASan could detect out -of bounds accesses to stack or global variables, but only if gcc 5.0 or later was -used to built the kernel. +KASAN uses compile-time instrumentation for checking every memory access, +therefore you will need a GCC version 4.9.2 or later. GCC 5.0 or later is +required for detection of out-of-bounds accesses to stack or global variables. -Currently KASan is supported only for x86_64 architecture and requires that the -kernel be built with the SLUB allocator. +Currently KASAN is supported only for x86_64 architecture and requires the +kernel to be built with the SLUB allocator. 1. Usage -========= +======== To enable KASAN configure kernel with: CONFIG_KASAN = y -and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline/inline -is compiler instrumentation types. The former produces smaller binary the -latter is 1.1 - 2 times faster. Inline instrumentation requires a gcc version -of 5.0 or later. +and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline and +inline are compiler instrumentation types. The former produces smaller binary +the latter is 1.1 - 2 times faster. Inline instrumentation requires a GCC +version 5.0 or later. Currently KASAN works only with the SLUB memory allocator. For better bug detection and nicer report, enable CONFIG_STACKTRACE and put
@@ -42,7 +41,7 @@ similar to the following to the respective kernel Makefile: KASAN_SANITIZE := n 1.1 Error reports -========== +================= A typical out of bounds access report looks like this:
@@ -119,14 +118,16 @@ Memory state around the buggy address: ffff8800693bc800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== -First sections describe slub object where bad access happened. -See 'SLUB Debug output' section in Documentation/vm/slub.txt for details. +The header of the report discribe what kind of bug happend and what kind of +access caused it. It's followed by the description of the accessed slub object +(see 'SLUB Debug output' section in Documentation/vm/slub.txt for details) and +the description of the accessed memory page. In the last section the report shows memory state around the accessed address. -Reading this part requires some more understanding of how KASAN works. +Reading this part requires some understanding of how KASAN works. -Each 8 bytes of memory are encoded in one shadow byte as accessible, -partially accessible, freed or they can be part of a redzone. +The state of each 8 aligned bytes of memory is encoded in one shadow byte. +Those 8 bytes can be accessible, partially accessible, freed or be a redzone. We use the following encoding for each shadow byte: 0 means that all 8 bytes of the corresponding memory region are accessible; number N (1 <= N <= 7) means that the first N bytes are accessible, and other (8 - N) bytes are not;
@@ -139,7 +140,7 @@ the accessed address is partially accessible. 2. Implementation details -======================== +========================= From a high level, our approach to memory error detection is similar to that of kmemcheck: use shadow memory to record whether each byte of memory is safe
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/7 kasan: move KASAN_SANITIZE in arch/x86/boot/Makefile
In reply to Andrey KonovalovMove KASAN_SANITIZE in arch/x86/boot/Makefile above the comment related to SVGA_MODE, since the comment refers to 'the next line'.
--- arch/x86/boot/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/boot/Makefile +2 -2
@@ -9,13 +9,13 @@ # Changed by many, many contributors over the years. # +KASAN_SANITIZE := n + # If you want to preset the SVGA mode, uncomment the next line and # set SVGA_MODE to whatever number you want. # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. # The number is the same as you would ordinarily press at bootup. -KASAN_SANITIZE := n - SVGA_MODE := -DSVGA_MODE=NORMAL_VGA targets := vmlinux.bin setup.bin setup.elf bzImage
Signature · 7 lines
2.5.0.457.gab17608 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/7 kasan: update reference to kasan prototype repo
In reply to Andrey KonovalovUpdate the reference to the kasan prototype repository on github, since it was renamed.
--- mm/kasan/kasan.c | 2 +- mm/kasan/report.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
mm/kasan/kasan.c +1 -1
@@ -4,7 +4,7 @@* Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Andrey Ryabinin <[email protected]> * -* Some of code borrowed from https://github.com/xairy/linux by +* Some code borrowed from https://github.com/xairy/kasan-prototype by * Andrey Konovalov <[email protected]> * * This program is free software; you can redistribute it and/or modify
mm/kasan/report.c +1 -1
@@ -4,7 +4,7 @@* Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Andrey Ryabinin <[email protected]> * -* Some of code borrowed from https://github.com/xairy/linux by +* Some code borrowed from https://github.com/xairy/kasan-prototype by * Andrey Konovalov <[email protected]> * * This program is free software; you can redistribute it and/or modify
Signature · 1 line
2.5.0.457.gab17608