Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kasan: remove use after scope bugs detection.

Use after scope bugs detector seems to be almost entirely useless for
the linux kernel. It exists over two years, but I've seen only one
valid bug so far [1]. And the bug was fixed before it has been
reported. There were some other use-after-scope reports, but they were
false-positives due to different reasons like incompatibility with
structleak plugin.

This feature significantly increases stack usage, especially with GCC <
9 version, and causes a 32K stack overflow. It probably adds
performance penalty too.

Given all that, let's remove use-after-scope detector entirely.

While preparing this patch I've noticed that we mistakenly enable
use-after-scope detection for clang compiler regardless of
CONFIG_KASAN_EXTRA setting. This is also fixed now.

[1] http://lkml.kernel.org/r/<20171129052106.rhgbjhhis53hkgfn@wfg-t540p.sh.intel.com>

Link: http://lkml.kernel.org/r/20190111185842.13978-1-aryabinin@virtuozzo.com
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Acked-by: Will Deacon <will.deacon@arm.com> [arm64]
Cc: Qian Cai <cai@lca.pw>
Cc: Alexander Potapenko <glider@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Andrey Ryabinin and committed by
Linus Torvalds
7771bdbb 46612b75

-73
-4
arch/arm64/include/asm/memory.h
··· 80 80 */ 81 81 #ifdef CONFIG_KASAN 82 82 #define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT)) 83 - #ifdef CONFIG_KASAN_EXTRA 84 - #define KASAN_THREAD_SHIFT 2 85 - #else 86 83 #define KASAN_THREAD_SHIFT 1 87 - #endif /* CONFIG_KASAN_EXTRA */ 88 84 #else 89 85 #define KASAN_SHADOW_SIZE (0) 90 86 #define KASAN_THREAD_SHIFT 0
-1
lib/Kconfig.debug
··· 222 222 config FRAME_WARN 223 223 int "Warn for stack frames larger than (needs gcc 4.4)" 224 224 range 0 8192 225 - default 3072 if KASAN_EXTRA 226 225 default 2048 if GCC_PLUGIN_LATENT_ENTROPY 227 226 default 1280 if (!64BIT && PARISC) 228 227 default 1024 if (!64BIT && !PARISC)
-10
lib/Kconfig.kasan
··· 78 78 79 79 endchoice 80 80 81 - config KASAN_EXTRA 82 - bool "KASAN: extra checks" 83 - depends on KASAN_GENERIC && DEBUG_KERNEL && !COMPILE_TEST 84 - help 85 - This enables further checks in generic KASAN, for now it only 86 - includes the address-use-after-scope check that can lead to 87 - excessive kernel stack usage, frame size warnings and longer 88 - compile time. 89 - See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 90 - 91 81 choice 92 82 prompt "Instrumentation type" 93 83 depends on KASAN
-24
lib/test_kasan.c
··· 480 480 kfree(kmem); 481 481 } 482 482 483 - static noinline void __init use_after_scope_test(void) 484 - { 485 - volatile char *volatile p; 486 - 487 - pr_info("use-after-scope on int\n"); 488 - { 489 - int local = 0; 490 - 491 - p = (char *)&local; 492 - } 493 - p[0] = 1; 494 - p[3] = 1; 495 - 496 - pr_info("use-after-scope on array\n"); 497 - { 498 - char local[1024] = {0}; 499 - 500 - p = local; 501 - } 502 - p[0] = 1; 503 - p[1023] = 1; 504 - } 505 - 506 483 static noinline void __init kasan_alloca_oob_left(void) 507 484 { 508 485 volatile int i = 10; ··· 659 682 kasan_alloca_oob_right(); 660 683 ksize_unpoisons_memory(); 661 684 copy_user_test(); 662 - use_after_scope_test(); 663 685 kmem_cache_double_free(); 664 686 kmem_cache_invalid_free(); 665 687 kasan_memchr();
-19
mm/kasan/generic.c
··· 275 275 void __asan_handle_no_return(void) {} 276 276 EXPORT_SYMBOL(__asan_handle_no_return); 277 277 278 - /* Emitted by compiler to poison large objects when they go out of scope. */ 279 - void __asan_poison_stack_memory(const void *addr, size_t size) 280 - { 281 - /* 282 - * Addr is KASAN_SHADOW_SCALE_SIZE-aligned and the object is surrounded 283 - * by redzones, so we simply round up size to simplify logic. 284 - */ 285 - kasan_poison_shadow(addr, round_up(size, KASAN_SHADOW_SCALE_SIZE), 286 - KASAN_USE_AFTER_SCOPE); 287 - } 288 - EXPORT_SYMBOL(__asan_poison_stack_memory); 289 - 290 - /* Emitted by compiler to unpoison large objects when they go into scope. */ 291 - void __asan_unpoison_stack_memory(const void *addr, size_t size) 292 - { 293 - kasan_unpoison_shadow(addr, size); 294 - } 295 - EXPORT_SYMBOL(__asan_unpoison_stack_memory); 296 - 297 278 /* Emitted by compiler to poison alloca()ed objects. */ 298 279 void __asan_alloca_poison(unsigned long addr, size_t size) 299 280 {
-3
mm/kasan/generic_report.c
··· 82 82 case KASAN_KMALLOC_FREE: 83 83 bug_type = "use-after-free"; 84 84 break; 85 - case KASAN_USE_AFTER_SCOPE: 86 - bug_type = "use-after-scope"; 87 - break; 88 85 case KASAN_ALLOCA_LEFT: 89 86 case KASAN_ALLOCA_RIGHT: 90 87 bug_type = "alloca-out-of-bounds";
-3
mm/kasan/kasan.h
··· 34 34 #define KASAN_STACK_MID 0xF2 35 35 #define KASAN_STACK_RIGHT 0xF3 36 36 #define KASAN_STACK_PARTIAL 0xF4 37 - #define KASAN_USE_AFTER_SCOPE 0xF8 38 37 39 38 /* 40 39 * alloca redzone shadow values ··· 186 187 void __asan_loadN(unsigned long addr, size_t size); 187 188 void __asan_storeN(unsigned long addr, size_t size); 188 189 void __asan_handle_no_return(void); 189 - void __asan_poison_stack_memory(const void *addr, size_t size); 190 - void __asan_unpoison_stack_memory(const void *addr, size_t size); 191 190 void __asan_alloca_poison(unsigned long addr, size_t size); 192 191 void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom); 193 192
-5
scripts/Makefile.kasan
··· 27 27 $(call cc-param,asan-globals=1) \ 28 28 $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ 29 29 $(call cc-param,asan-stack=$(CONFIG_KASAN_STACK)) \ 30 - $(call cc-param,asan-use-after-scope=1) \ 31 30 $(call cc-param,asan-instrument-allocas=1) 32 - endif 33 - 34 - ifdef CONFIG_KASAN_EXTRA 35 - CFLAGS_KASAN += $(call cc-option, -fsanitize-address-use-after-scope) 36 31 endif 37 32 38 33 endif # CONFIG_KASAN_GENERIC
-4
scripts/gcc-plugins/Kconfig
··· 68 68 69 69 config GCC_PLUGIN_STRUCTLEAK 70 70 bool "Force initialization of variables containing userspace addresses" 71 - # Currently STRUCTLEAK inserts initialization out of live scope of 72 - # variables from KASAN point of view. This leads to KASAN false 73 - # positive reports. Prohibit this combination for now. 74 - depends on !KASAN_EXTRA 75 71 help 76 72 This plugin zero-initializes any structures containing a 77 73 __user attribute. This can prevent some classes of information