Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bebf56a1 authored by Andrey Ryabinin's avatar Andrey Ryabinin Committed by Linus Torvalds
Browse files

kasan: enable instrumentation of global variables



This feature let us to detect accesses out of bounds of global variables.
This will work as for globals in kernel image, so for globals in modules.
Currently this won't work for symbols in user-specified sections (e.g.
__init, __read_mostly, ...)

The idea of this is simple.  Compiler increases each global variable by
redzone size and add constructors invoking __asan_register_globals()
function.  Information about global variable (address, size, size with
redzone ...) passed to __asan_register_globals() so we could poison
variable's redzone.

This patch also forces module_alloc() to return 8*PAGE_SIZE aligned
address making shadow memory handling (
kasan_module_alloc()/kasan_module_free() ) more simple.  Such alignment
guarantees that each shadow page backing modules address space correspond
to only one module_alloc() allocation.

Signed-off-by: default avatarAndrey 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: default avatarAndrey 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6301939d
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -9,7 +9,7 @@ a fast and comprehensive solution for finding use-after-free and out-of-bounds
bugs.
bugs.


KASan uses compile-time instrumentation for checking every memory access,
KASan uses compile-time instrumentation for checking every memory access,
therefore you will need a certain version of GCC >= 4.9.2
therefore you will need a certain version of GCC > 4.9.2


Currently KASan is supported only for x86_64 architecture and requires that the
Currently KASan is supported only for x86_64 architecture and requires that the
kernel be built with the SLUB allocator.
kernel be built with the SLUB allocator.
+11 −1
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/kasan.h>
#include <linux/bug.h>
#include <linux/bug.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/gfp.h>
#include <linux/gfp.h>
@@ -83,13 +84,22 @@ static unsigned long int get_module_load_offset(void)


void *module_alloc(unsigned long size)
void *module_alloc(unsigned long size)
{
{
	void *p;

	if (PAGE_ALIGN(size) > MODULES_LEN)
	if (PAGE_ALIGN(size) > MODULES_LEN)
		return NULL;
		return NULL;
	return __vmalloc_node_range(size, 1,

	p = __vmalloc_node_range(size, MODULE_ALIGN,
				    MODULES_VADDR + get_module_load_offset(),
				    MODULES_VADDR + get_module_load_offset(),
				    MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
				    MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
				    PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
				    PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
				    __builtin_return_address(0));
				    __builtin_return_address(0));
	if (p && (kasan_module_alloc(p, size) < 0)) {
		vfree(p);
		return NULL;
	}

	return p;
}
}


#ifdef CONFIG_X86_32
#ifdef CONFIG_X86_32
+1 −1
Original line number Original line Diff line number Diff line
@@ -196,7 +196,7 @@ void __init kasan_init(void)
			(unsigned long)kasan_mem_to_shadow(_end),
			(unsigned long)kasan_mem_to_shadow(_end),
			NUMA_NO_NODE);
			NUMA_NO_NODE);


	populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_VADDR),
	populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
			(void *)KASAN_SHADOW_END);
			(void *)KASAN_SHADOW_END);


	memset(kasan_zero_page, 0, PAGE_SIZE);
	memset(kasan_zero_page, 0, PAGE_SIZE);
+4 −0
Original line number Original line Diff line number Diff line
@@ -85,3 +85,7 @@
#define __HAVE_BUILTIN_BSWAP16__
#define __HAVE_BUILTIN_BSWAP16__
#endif
#endif
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */

#if GCC_VERSION >= 40902
#define KASAN_ABI_VERSION 3
#endif
+2 −0
Original line number Original line Diff line number Diff line
@@ -63,3 +63,5 @@
#define __HAVE_BUILTIN_BSWAP64__
#define __HAVE_BUILTIN_BSWAP64__
#define __HAVE_BUILTIN_BSWAP16__
#define __HAVE_BUILTIN_BSWAP16__
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */

#define KASAN_ABI_VERSION 4
Loading