[RFC/PATCH RESEND -next 01/21] Add kernel address sanitizer infrastructure.
From: Andrey Ryabinin <hidden>
Date: 2014-07-10 13:56:07
Also in:
linux-kbuild, linux-mm, lkml
On 07/10/14 17:31, Sasha Levin wrote:
On 07/10/2014 09:01 AM, Andrey Ryabinin wrote:quoted
On 07/10/14 15:55, Sasha Levin wrote:quoted
quoted
On 07/09/2014 07:29 AM, Andrey Ryabinin wrote:quoted
quoted
Address sanitizer for kernel (kasan) is a dynamic memory error detector. The main features of kasan is: - is based on compiler instrumentation (fast), - detects out of bounds for both writes and reads, - provides use after free detection, This patch only adds infrastructure for kernel address sanitizer. It's not available for use yet. The idea and some code was borrowed from [1]. This feature requires pretty fresh GCC (revision r211699 from 2014-06-16 or latter). Implementation details: The main idea of KASAN is to use shadow memory to record whether each byte of memory is safe to access or not, and use compiler's instrumentation to check the shadow memory on each memory access. Address sanitizer dedicates 1/8 of the low memory to the shadow memory and uses direct mapping with a scale and offset to translate a memory address to its corresponding shadow address. Here is function to translate address to corresponding shadow address: unsigned long kasan_mem_to_shadow(unsigned long addr) { return ((addr - PAGE_OFFSET) >> KASAN_SHADOW_SCALE_SHIFT) + kasan_shadow_start; } where KASAN_SHADOW_SCALE_SHIFT = 3. So for every 8 bytes of lowmemory there is one corresponding byte of shadow memory. The following encoding used for each shadow byte: 0 means that all 8 bytes of the corresponding memory region are valid for access; k (1 <= k <= 7) means that the first k bytes are valid for access, and other (8 - k) bytes are not; Any negative value indicates that the entire 8-bytes are unaccessible. Different negative values used to distinguish between different kinds of unaccessible memory (redzones, freed memory) (see mm/kasan/kasan.h). To be able to detect accesses to bad memory we need a special compiler. Such compiler inserts a specific function calls (__asan_load*(addr), __asan_store*(addr)) before each memory access of size 1, 2, 4, 8 or 16. These functions check whether memory region is valid to access or not by checking corresponding shadow memory. If access is not valid an error printed. [1] https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel Signed-off-by: Andrey Ryabinin <redacted>I gave it a spin, and it seems that it fails for what you might call a "regular" memory size these days, in my case it was 18G: [ 0.000000] Kernel panic - not syncing: ERROR: Failed to allocate 0xe0c00000 bytes below 0x0. [ 0.000000] [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 3.16.0-rc4-next-20140710-sasha-00044-gb7b0579-dirty #784 [ 0.000000] ffffffffb9c2d3c8 cd9ce91adea4379a 0000000000000000 ffffffffb9c2d3c8 [ 0.000000] ffffffffb9c2d330 ffffffffb7fe89b7 ffffffffb93c8c28 ffffffffb9c2d3b8 [ 0.000000] ffffffffb7fcff1d 0000000000000018 ffffffffb9c2d3c8 ffffffffb9c2d360 [ 0.000000] Call Trace: [ 0.000000] <UNK> dump_stack (lib/dump_stack.c:52) [ 0.000000] panic (kernel/panic.c:119) [ 0.000000] memblock_alloc_base (mm/memblock.c:1092) [ 0.000000] memblock_alloc (mm/memblock.c:1097) [ 0.000000] kasan_alloc_shadow (mm/kasan/kasan.c:151) [ 0.000000] zone_sizes_init (arch/x86/mm/init.c:684) [ 0.000000] paging_init (arch/x86/mm/init_64.c:677) [ 0.000000] setup_arch (arch/x86/kernel/setup.c:1168) [ 0.000000] ? printk (kernel/printk/printk.c:1839) [ 0.000000] start_kernel (include/linux/mm_types.h:462 init/main.c:533) [ 0.000000] ? early_idt_handlers (arch/x86/kernel/head_64.S:344) [ 0.000000] x86_64_start_reservations (arch/x86/kernel/head64.c:194) [ 0.000000] x86_64_start_kernel (arch/x86/kernel/head64.c:183) It got better when I reduced memory to 1GB, but then my system just failed to boot at all because that's not enough to bring everything up.Thanks. I think memory size is not a problem here. I tested on my desktop with 16G. Seems it's a problem with memory holes cited by Dave. kasan tries to allocate ~3.5G. It means that lowmemsize is 28G in your case.That's correct (I've mistyped and got 18 instead of 28 above). However, I'm a bit confused here, I thought highmem/lowmem split was a 32bit thing, so I'm not sure how it applies here. Anyways, the machine won't boot with more than 1GB of RAM, is there a solution to get KASAN running on my machine?
It's not boot with the same Failed to allocate error?
Thanks, Sasha