linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/6] KASAN for arm64
@ 2015-09-17  9:38 Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 1/6] arm64: introduce VA_START macro - the first kernel virtual address Andrey Ryabinin
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

As usual patches available in git
	git://github.com/aryabinin/linux.git kasan/arm64v6

Changes since v5:
 - Rebase on top of 4.3-rc1
 - Fixed EFI boot.
 - Updated Doc/features/KASAN.

Changes since v4:
 - Generate KASAN_SHADOW_OFFSET using 32 bit arithmetic
 - merge patches x86/kasan: switch to generic kasan_populate_zero_shadow()
    and mm: introduce generic kasan_populate_zero_shadow() into one.
 - remove useless check for start != 0 in clear_pgds()
 - Don't generate KASAN_SHADOW_OFFSET in Makefile for x86,
   assign it in Makefile.kasan if CONFIG_KASAN_SHADOW_OFFSET was defined.
 
Changes since v3:
 - Generate KASAN_SHADOW_OFFSET in Makefile
 - zero_p*_populate() functions now return void
 - Switch x86 to generic kasan_populate_zero_shadow() too
 - Add license headers
 - fix memleak in kasan_populate_zero_shadow:
       Following code could leak memory when pgd_populate() is nop:
                void *p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
                pgd_populate(&init_mm, pgd, p);
        This was replaced by:
                 pgd_populate(&init_mm, pgd, early_alloc(PAGE_SIZE, NUMA_NO_NODE));

Changes since v2:
 - Rebase on top of v4.2-rc3
 - Address feedback from Catalin.
 - Print memory assignment from Linus
 - Add message about KASAN being initialized

Changes since v1:
 - Address feedback from Catalin.
 - Generalize some kasan init code from arch/x86/mm/kasan_init_64.c
    and reuse it for arm64.
 - Some bugfixes, including:
        add missing arm64/include/asm/kasan.h
        add tlb flush after changing ttbr1
 - Add code comments.


Andrey Ryabinin (5):
  arm64: introduce VA_START macro - the first kernel virtual address.
  arm64: move PGD_SIZE definition to pgalloc.h
  x86, efi, kasan: #undef memset/memcpy/memmove per arch.
  arm64: add KASAN support
  Documentation/features/KASAN: arm64 supports KASAN now

Linus Walleij (1):
  ARM64: kasan: print memory assignment

 .../features/debug/KASAN/arch-support.txt          |   2 +-
 arch/arm64/Kconfig                                 |   1 +
 arch/arm64/Makefile                                |   7 +
 arch/arm64/include/asm/kasan.h                     |  36 +++++
 arch/arm64/include/asm/memory.h                    |   2 +
 arch/arm64/include/asm/pgalloc.h                   |   1 +
 arch/arm64/include/asm/pgtable.h                   |   9 +-
 arch/arm64/include/asm/string.h                    |  16 ++
 arch/arm64/kernel/Makefile                         |   2 +
 arch/arm64/kernel/arm64ksyms.c                     |   3 +
 arch/arm64/kernel/head.S                           |   3 +
 arch/arm64/kernel/module.c                         |  16 +-
 arch/arm64/kernel/setup.c                          |   4 +
 arch/arm64/lib/memcpy.S                            |   3 +
 arch/arm64/lib/memmove.S                           |   7 +-
 arch/arm64/lib/memset.S                            |   3 +
 arch/arm64/mm/Makefile                             |   3 +
 arch/arm64/mm/init.c                               |   6 +
 arch/arm64/mm/kasan_init.c                         | 165 +++++++++++++++++++++
 arch/arm64/mm/pgd.c                                |   2 -
 arch/x86/include/asm/efi.h                         |  12 ++
 drivers/firmware/efi/Makefile                      |   8 +
 drivers/firmware/efi/libstub/efistub.h             |   4 -
 lib/Makefile                                       |   3 +-
 scripts/Makefile.kasan                             |   4 +-
 25 files changed, 307 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm64/include/asm/kasan.h
 create mode 100644 arch/arm64/mm/kasan_init.c

-- 
2.4.6

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 1/6] arm64: introduce VA_START macro - the first kernel virtual address.
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 2/6] arm64: move PGD_SIZE definition to pgalloc.h Andrey Ryabinin
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

In order to not use lengthy (UL(0xffffffffffffffff) << VA_BITS) everywhere,
replace it with VA_START.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/memory.h  | 2 ++
 arch/arm64/include/asm/pgtable.h | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 6b4c3ad..11ccf6c 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -42,12 +42,14 @@
  * PAGE_OFFSET - the virtual address of the start of the kernel image (top
  *		 (VA_BITS - 1))
  * VA_BITS - the maximum number of bits for virtual addresses.
+ * VA_START - the first kernel virtual address.
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 128MB of the kernel text.
  */
 #define VA_BITS			(CONFIG_ARM64_VA_BITS)
+#define VA_START		(UL(0xffffffffffffffff) << VA_BITS)
 #define PAGE_OFFSET		(UL(0xffffffffffffffff) << (VA_BITS - 1))
 #define MODULES_END		(PAGE_OFFSET)
 #define MODULES_VADDR		(MODULES_END - SZ_64M)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6900b2d9..a53a126 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -45,7 +45,7 @@
  *	fixed mappings and modules
  */
 #define VMEMMAP_SIZE		ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
-#define VMALLOC_START		(UL(0xffffffffffffffff) << VA_BITS)
+#define VMALLOC_START		(VA_START)
 #define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 2/6] arm64: move PGD_SIZE definition to pgalloc.h
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 1/6] arm64: introduce VA_START macro - the first kernel virtual address Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 3/6] x86, efi, kasan: #undef memset/memcpy/memmove per arch Andrey Ryabinin
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

This will be used by KASAN latter.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/pgalloc.h | 1 +
 arch/arm64/mm/pgd.c              | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 7642056..c150539 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -27,6 +27,7 @@
 #define check_pgt_cache()		do { } while (0)
 
 #define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
 
 #if CONFIG_PGTABLE_LEVELS > 2
 
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 71ca104..cb3ba1b 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -28,8 +28,6 @@
 
 #include "mm.h"
 
-#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
-
 static struct kmem_cache *pgd_cache;
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 3/6] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 1/6] arm64: introduce VA_START macro - the first kernel virtual address Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 2/6] arm64: move PGD_SIZE definition to pgalloc.h Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
       [not found]   ` <20150929083814.GA32127@gmail.com>
  2015-09-17  9:38 ` [PATCH v6 4/6] arm64: add KASAN support Andrey Ryabinin
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

In not-instrumented code KASAN replaces instrumented
memset/memcpy/memmove with not-instrumented analogues
__memset/__memcpy/__memove.
However, on x86 the EFI stub is not linked with the kernel.
It uses not-instrumented mem*() functions from
arch/x86/boot/compressed/string.c
So we don't replace them with __mem*() variants in EFI stub.

On ARM64 the EFI stub is linked with the kernel, so we should
replace mem*() functions with __mem*(), because the EFI stub
runs before KASAN sets up early shadow.

So let's move these #undef mem* into arch's asm/efi.h which is
also included by the EFI stub.

Also, this will fix the warning in 32-bit build reported by
kbuild test robot <fengguang.wu@intel.com>:
	efi-stub-helper.c:599:2: warning: implicit declaration of function 'memcpy'

Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
---
 arch/x86/include/asm/efi.h             | 12 ++++++++++++
 drivers/firmware/efi/libstub/efistub.h |  4 ----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 155162e..6db2742 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -86,6 +86,18 @@ extern u64 asmlinkage efi_call(void *fp, ...);
 extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
 					u32 type, u64 attribute);
 
+/*
+ * CONFIG_KASAN may redefine memset to __memset.
+ * __memset function is present only in kernel binary.
+ * Since the EFI stub linked into a separate binary it
+ * doesn't have __memset(). So we should use standard
+ * memset from arch/x86/boot/compressed/string.c
+ * The same applies to memcpy and memmove.
+ */
+#undef memcpy
+#undef memset
+#undef memmove
+
 #endif /* CONFIG_X86_32 */
 
 extern struct efi_scratch efi_scratch;
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index e334a01..6b6548f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -5,10 +5,6 @@
 /* error code which can't be mistaken for valid address */
 #define EFI_ERROR	(~0UL)
 
-#undef memcpy
-#undef memset
-#undef memmove
-
 void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 4/6] arm64: add KASAN support
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
                   ` (2 preceding siblings ...)
  2015-09-17  9:38 ` [PATCH v6 3/6] x86, efi, kasan: #undef memset/memcpy/memmove per arch Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 5/6] ARM64: kasan: print memory assignment Andrey Ryabinin
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds arch specific code for kernel address sanitizer
(see Documentation/kasan.txt).

1/8 of kernel addresses reserved for shadow memory. There was no
big enough hole for this, so virtual addresses for shadow were
stolen from vmalloc area.

At early boot stage the whole shadow region populated with just
one physical page (kasan_zero_page). Later, this page reused
as readonly zero shadow for some memory that KASan currently
don't track (vmalloc).
After mapping the physical memory, pages for shadow memory are
allocated and mapped.

Functions like memset/memmove/memcpy do a lot of memory accesses.
If bad pointer passed to one of these function it is important
to catch this. Compiler's instrumentation cannot do this since
these functions are written in assembly.
KASan replaces memory functions with manually instrumented variants.
Original functions declared as weak symbols so strong definitions
in mm/kasan/kasan.c could replace them. Original functions have aliases
with '__' prefix in name, so we could call non-instrumented variant
if needed.
Some files built without kasan instrumentation (e.g. mm/slub.c).
Original mem* function replaced (via #define) with prefixed variants
to disable memory access checks for such files.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/Kconfig               |   1 +
 arch/arm64/Makefile              |   7 ++
 arch/arm64/include/asm/kasan.h   |  36 +++++++++
 arch/arm64/include/asm/pgtable.h |   7 ++
 arch/arm64/include/asm/string.h  |  16 ++++
 arch/arm64/kernel/Makefile       |   2 +
 arch/arm64/kernel/arm64ksyms.c   |   3 +
 arch/arm64/kernel/head.S         |   3 +
 arch/arm64/kernel/module.c       |  16 +++-
 arch/arm64/kernel/setup.c        |   4 +
 arch/arm64/lib/memcpy.S          |   3 +
 arch/arm64/lib/memmove.S         |   7 +-
 arch/arm64/lib/memset.S          |   3 +
 arch/arm64/mm/Makefile           |   3 +
 arch/arm64/mm/kasan_init.c       | 165 +++++++++++++++++++++++++++++++++++++++
 drivers/firmware/efi/Makefile    |   8 ++
 lib/Makefile                     |   3 +-
 scripts/Makefile.kasan           |   4 +-
 18 files changed, 284 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm64/include/asm/kasan.h
 create mode 100644 arch/arm64/mm/kasan_init.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7d95663..87202a1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -47,6 +47,7 @@ config ARM64
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_BITREVERSE
 	select HAVE_ARCH_JUMP_LABEL
+	select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 15ff5b4..6e957b8 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -51,6 +51,13 @@ else
 TEXT_OFFSET := 0x00080000
 endif
 
+# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - 3)) - (1 << 61)
+# in 32-bit arithmetic
+KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
+			(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
+			+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - 3)) \
+			- (1 << (64 - 32 - 3)) )) )
+
 export	TEXT_OFFSET GZFLAGS
 
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
new file mode 100644
index 0000000..71dfe14
--- /dev/null
+++ b/arch/arm64/include/asm/kasan.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_KASAN
+
+#include <asm/memory.h>
+
+/*
+ * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
+ * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
+ */
+#define KASAN_SHADOW_START      (VA_START)
+#define KASAN_SHADOW_END        (KASAN_SHADOW_START + (1UL << (VA_BITS - 3)))
+
+/*
+ * This value is used to map an address to the corresponding shadow
+ * address by the following formula:
+ *     shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *
+ * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
+ * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
+ * should satisfy the following equation:
+ *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ */
+#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+
+void kasan_init(void);
+
+#else
+static inline void kasan_init(void) { }
+#endif
+
+#endif
+#endif
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index a53a126..860c37a 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -45,7 +45,14 @@
  *	fixed mappings and modules
  */
 #define VMEMMAP_SIZE		ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
+
+#ifndef CONFIG_KASAN
 #define VMALLOC_START		(VA_START)
+#else
+#include <asm/kasan.h>
+#define VMALLOC_START		(KASAN_SHADOW_END + SZ_64K)
+#endif
+
 #define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 64d2d48..2eb714c 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -36,17 +36,33 @@ extern __kernel_size_t strnlen(const char *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCPY
 extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *__memcpy(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *, const void *, __kernel_size_t);
+extern void *__memmove(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCHR
 extern void *memchr(const void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *, int, __kernel_size_t);
+extern void *__memset(void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCMP
 extern int memcmp(const void *, const void *, size_t);
 
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
 #endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 22dc9bc..a0519a3 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -7,6 +7,8 @@ AFLAGS_head.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_efi-stub.o 	:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_armv8_deprecated.o := -I$(src)
 
+KASAN_SANITIZE_efi-stub.o	:= n
+
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_insn.o = -pg
 CFLAGS_REMOVE_return_address.o = -pg
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
index a85843d..3b6d8cc 100644
--- a/arch/arm64/kernel/arm64ksyms.c
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -51,6 +51,9 @@ EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__memset);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(__memmove);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcmp);
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index a055be6..5085108 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -444,6 +444,9 @@ __mmap_switched:
 	str_l	x21, __fdt_pointer, x5		// Save FDT pointer
 	str_l	x24, memstart_addr, x6		// Save PHYS_OFFSET
 	mov	x29, #0
+#ifdef CONFIG_KASAN
+	bl	kasan_early_init
+#endif
 	b	start_kernel
 ENDPROC(__mmap_switched)
 
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 67bf410..7d90c0f 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/elf.h>
 #include <linux/gfp.h>
+#include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/moduleloader.h>
@@ -34,9 +35,18 @@
 
 void *module_alloc(unsigned long size)
 {
-	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
-				    GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
-				    NUMA_NO_NODE, __builtin_return_address(0));
+	void *p;
+
+	p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
+				GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
+				NUMA_NO_NODE, __builtin_return_address(0));
+
+	if (p && (kasan_module_alloc(p, size) < 0)) {
+		vfree(p);
+		return NULL;
+	}
+
+	return p;
 }
 
 enum aarch64_reloc_op {
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 6bab21f..79df79a 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -54,6 +54,7 @@
 #include <asm/elf.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
+#include <asm/kasan.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -434,6 +435,9 @@ void __init setup_arch(char **cmdline_p)
 
 	paging_init();
 	relocate_initrd();
+
+	kasan_init();
+
 	request_standard_resources();
 
 	early_ioremap_reset();
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index 8a9a96d..42cc4b7 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -56,6 +56,8 @@ C_h	.req	x12
 D_l	.req	x13
 D_h	.req	x14
 
+	.weak memcpy
+ENTRY(__memcpy)
 ENTRY(memcpy)
 	mov	dst, dstin
 	cmp	count, #16
@@ -199,3 +201,4 @@ ENTRY(memcpy)
 	b.ne	.Ltail63
 	ret
 ENDPROC(memcpy)
+ENDPROC(__memcpy)
diff --git a/arch/arm64/lib/memmove.S b/arch/arm64/lib/memmove.S
index 57b19ea..8819433 100644
--- a/arch/arm64/lib/memmove.S
+++ b/arch/arm64/lib/memmove.S
@@ -57,12 +57,14 @@ C_h	.req	x12
 D_l	.req	x13
 D_h	.req	x14
 
+	.weak memmove
+ENTRY(__memmove)
 ENTRY(memmove)
 	cmp	dstin, src
-	b.lo	memcpy
+	b.lo	__memcpy
 	add	tmp1, src, count
 	cmp	dstin, tmp1
-	b.hs	memcpy		/* No overlap.  */
+	b.hs	__memcpy		/* No overlap.  */
 
 	add	dst, dstin, count
 	add	src, src, count
@@ -195,3 +197,4 @@ ENTRY(memmove)
 	b.ne	.Ltail63
 	ret
 ENDPROC(memmove)
+ENDPROC(__memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
index 7c72dfd..edc0e7d 100644
--- a/arch/arm64/lib/memset.S
+++ b/arch/arm64/lib/memset.S
@@ -54,6 +54,8 @@ dst		.req	x8
 tmp3w		.req	w9
 tmp3		.req	x9
 
+	.weak memset
+ENTRY(__memset)
 ENTRY(memset)
 	mov	dst, dstin	/* Preserve return value.  */
 	and	A_lw, val, #255
@@ -214,3 +216,4 @@ ENTRY(memset)
 	b.ne	.Ltail_maybe_long
 	ret
 ENDPROC(memset)
+ENDPROC(__memset)
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 773d37a..57f57fd 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,3 +4,6 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+
+obj-$(CONFIG_KASAN)		+= kasan_init.o
+KASAN_SANITIZE_kasan_init.o	:= n
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
new file mode 100644
index 0000000..b6a92f5
--- /dev/null
+++ b/arch/arm64/mm/kasan_init.c
@@ -0,0 +1,165 @@
+/*
+ * This file contains kasan initialization code for ARM64.
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define pr_fmt(fmt) "kasan: " fmt
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/start_kernel.h>
+
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+
+static void __init kasan_early_pte_populate(pmd_t *pmd, unsigned long addr,
+					unsigned long end)
+{
+	pte_t *pte;
+	unsigned long next;
+
+	if (pmd_none(*pmd))
+		pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+
+	pte = pte_offset_kernel(pmd, addr);
+	do {
+		next = addr + PAGE_SIZE;
+		set_pte(pte, pfn_pte(virt_to_pfn(kasan_zero_page),
+					PAGE_KERNEL));
+	} while (pte++, addr = next, addr != end && pte_none(*pte));
+}
+
+static void __init kasan_early_pmd_populate(pud_t *pud,
+					unsigned long addr,
+					unsigned long end)
+{
+	pmd_t *pmd;
+	unsigned long next;
+
+	if (pud_none(*pud))
+		pud_populate(&init_mm, pud, kasan_zero_pmd);
+
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		kasan_early_pte_populate(pmd, addr, next);
+	} while (pmd++, addr = next, addr != end && pmd_none(*pmd));
+}
+
+static void __init kasan_early_pud_populate(pgd_t *pgd,
+					unsigned long addr,
+					unsigned long end)
+{
+	pud_t *pud;
+	unsigned long next;
+
+	if (pgd_none(*pgd))
+		pgd_populate(&init_mm, pgd, kasan_zero_pud);
+
+	pud = pud_offset(pgd, addr);
+	do {
+		next = pud_addr_end(addr, end);
+		kasan_early_pmd_populate(pud, addr, next);
+	} while (pud++, addr = next, addr != end && pud_none(*pud));
+}
+
+static void __init kasan_map_early_shadow(void)
+{
+	unsigned long addr = KASAN_SHADOW_START;
+	unsigned long end = KASAN_SHADOW_END;
+	unsigned long next;
+	pgd_t *pgd;
+
+	pgd = pgd_offset_k(addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		kasan_early_pud_populate(pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+}
+
+void __init kasan_early_init(void)
+{
+	BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+	kasan_map_early_shadow();
+}
+
+static void __init clear_pgds(unsigned long start,
+			unsigned long end)
+{
+	/*
+	 * Remove references to kasan page tables from
+	 * swapper_pg_dir. pgd_clear() can't be used
+	 * here because it's nop on 2,3-level pagetable setups
+	 */
+	for (; start < end; start += PGDIR_SIZE)
+		set_pgd(pgd_offset_k(start), __pgd(0));
+}
+
+static void __init cpu_set_ttbr1(unsigned long ttbr1)
+{
+	asm(
+	"	msr	ttbr1_el1, %0\n"
+	"	isb"
+	:
+	: "r" (ttbr1));
+}
+
+void __init kasan_init(void)
+{
+	struct memblock_region *reg;
+
+	/*
+	 * We are going to perform proper setup of shadow memory.
+	 * At first we should unmap early shadow (clear_pgds() call bellow).
+	 * However, instrumented code couldn't execute without shadow memory.
+	 * tmp_pg_dir used to keep early shadow mapped until full shadow
+	 * setup will be finished.
+	 */
+	memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+	cpu_set_ttbr1(__pa(tmp_pg_dir));
+	flush_tlb_all();
+
+	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+
+	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
+			kasan_mem_to_shadow((void *)MODULES_VADDR));
+
+	for_each_memblock(memory, reg) {
+		void *start = (void *)__phys_to_virt(reg->base);
+		void *end = (void *)__phys_to_virt(reg->base + reg->size);
+
+		if (start >= end)
+			break;
+
+		/*
+		 * end + 1 here is intentional. We check several shadow bytes in
+		 * advance to slightly speed up fastpath. In some rare cases
+		 * we could cross boundary of mapped shadow, so we just map
+		 * some more here.
+		 */
+		vmemmap_populate((unsigned long)kasan_mem_to_shadow(start),
+				(unsigned long)kasan_mem_to_shadow(end) + 1,
+				pfn_to_nid(virt_to_pfn(start)));
+	}
+
+	memset(kasan_zero_page, 0, PAGE_SIZE);
+	cpu_set_ttbr1(__pa(swapper_pg_dir));
+	flush_tlb_all();
+
+	/* At this point kasan is fully initialized. Enable error messages */
+	init_task.kasan_depth = 0;
+	pr_info("KernelAddressSanitizer initialized\n");
+}
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 6fd3da9..413fcf2 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -1,6 +1,14 @@
 #
 # Makefile for linux kernel
 #
+
+#
+# ARM64 maps efi runtime services in userspace addresses
+# which don't have KASAN shadow. So dereference of these addresses
+# in efi_call_virt() will cause crash if this code instrumented.
+#
+KASAN_SANITIZE_runtime-wrappers.o	:= n
+
 obj-$(CONFIG_EFI)			+= efi.o vars.o reboot.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_ESRT)			+= esrt.o
diff --git a/lib/Makefile b/lib/Makefile
index 13a7c6a..1874547 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -166,7 +166,8 @@ obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
 libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
 	       fdt_empty_tree.o
 $(foreach file, $(libfdt_files), \
-	$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
+	$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt) \
+	$(eval KASAN_SANITIZE_$(file) := n))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 3f874d2..37323b0 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -5,10 +5,12 @@ else
 	call_threshold := 0
 endif
 
+KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
+
 CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
 
 CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
-		-fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \
+		-fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \
 		--param asan-stack=1 --param asan-globals=1 \
 		--param asan-instrumentation-with-call-threshold=$(call_threshold))
 
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 5/6] ARM64: kasan: print memory assignment
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
                   ` (3 preceding siblings ...)
  2015-09-17  9:38 ` [PATCH v6 4/6] arm64: add KASAN support Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
  2015-09-17  9:38 ` [PATCH v6 6/6] Documentation/features/KASAN: arm64 supports KASAN now Andrey Ryabinin
  2015-10-07 10:04 ` [PATCH v6 0/6] KASAN for arm64 Catalin Marinas
  6 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

From: Linus Walleij <linus.walleij@linaro.org>

This prints out the virtual memory assigned to KASan in the
boot crawl along with other memory assignments, if and only
if KASan is activated.

Example dmesg from the Juno Development board:

Memory: 1691156K/2080768K available (5465K kernel code, 444K rwdata,
2160K rodata, 340K init, 217K bss, 373228K reserved, 16384K cma-reserved)
Virtual kernel memory layout:
    kasan   : 0xffffff8000000000 - 0xffffff9000000000   (    64 GB)
    vmalloc : 0xffffff9000000000 - 0xffffffbdbfff0000   (   182 GB)
    vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
              0xffffffbdc2000000 - 0xffffffbdc3fc0000   (    31 MB actual)
    fixed   : 0xffffffbffabfd000 - 0xffffffbffac00000   (    12 KB)
    PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000   (    16 MB)
    modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
    memory  : 0xffffffc000000000 - 0xffffffc07f000000   (  2032 MB)
      .init : 0xffffffc0007f5000 - 0xffffffc00084a000   (   340 KB)
      .text : 0xffffffc000080000 - 0xffffffc0007f45b4   (  7634 KB)
      .data : 0xffffffc000850000 - 0xffffffc0008bf200   (   445 KB)

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/mm/init.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5c0680..7a1f9a0 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -298,6 +298,9 @@ void __init mem_init(void)
 #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
 
 	pr_notice("Virtual kernel memory layout:\n"
+#ifdef CONFIG_KASAN
+		  "    kasan   : 0x%16lx - 0x%16lx   (%6ld GB)\n"
+#endif
 		  "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 		  "    vmemmap : 0x%16lx - 0x%16lx   (%6ld GB maximum)\n"
@@ -310,6 +313,9 @@ void __init mem_init(void)
 		  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
 		  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
 		  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n",
+#ifdef CONFIG_KASAN
+		  MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
+#endif
 		  MLG(VMALLOC_START, VMALLOC_END),
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 		  MLG((unsigned long)vmemmap,
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 6/6] Documentation/features/KASAN: arm64 supports KASAN now
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
                   ` (4 preceding siblings ...)
  2015-09-17  9:38 ` [PATCH v6 5/6] ARM64: kasan: print memory assignment Andrey Ryabinin
@ 2015-09-17  9:38 ` Andrey Ryabinin
  2015-10-07 10:04 ` [PATCH v6 0/6] KASAN for arm64 Catalin Marinas
  6 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-17  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
---
 Documentation/features/debug/KASAN/arch-support.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt
index 14531da..703f578 100644
--- a/Documentation/features/debug/KASAN/arch-support.txt
+++ b/Documentation/features/debug/KASAN/arch-support.txt
@@ -9,7 +9,7 @@
     |       alpha: | TODO |
     |         arc: | TODO |
     |         arm: | TODO |
-    |       arm64: | TODO |
+    |       arm64: |  ok  |
     |       avr32: | TODO |
     |    blackfin: | TODO |
     |         c6x: | TODO |
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 3/6] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
       [not found]   ` <20150929083814.GA32127@gmail.com>
@ 2015-09-29 15:34     ` Andrey Ryabinin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-09-29 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

2015-09-29 11:38 GMT+03:00 Ingo Molnar <mingo@kernel.org>:
>
> * Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
>
>> In not-instrumented code KASAN replaces instrumented
>> memset/memcpy/memmove with not-instrumented analogues
>> __memset/__memcpy/__memove.
>> However, on x86 the EFI stub is not linked with the kernel.
>> It uses not-instrumented mem*() functions from
>> arch/x86/boot/compressed/string.c
>> So we don't replace them with __mem*() variants in EFI stub.
>>
>> On ARM64 the EFI stub is linked with the kernel, so we should
>> replace mem*() functions with __mem*(), because the EFI stub
>> runs before KASAN sets up early shadow.
>>
>> So let's move these #undef mem* into arch's asm/efi.h which is
>> also included by the EFI stub.
>>
>> Also, this will fix the warning in 32-bit build reported by
>> kbuild test robot <fengguang.wu@intel.com>:
>>       efi-stub-helper.c:599:2: warning: implicit declaration of function 'memcpy'
>>
>> Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
>> ---
>>  arch/x86/include/asm/efi.h             | 12 ++++++++++++
>>  drivers/firmware/efi/libstub/efistub.h |  4 ----
>>  2 files changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
>> index 155162e..6db2742 100644
>> --- a/arch/x86/include/asm/efi.h
>> +++ b/arch/x86/include/asm/efi.h
>> @@ -86,6 +86,18 @@ extern u64 asmlinkage efi_call(void *fp, ...);
>>  extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
>>                                       u32 type, u64 attribute);
>>
>> +/*
>> + * CONFIG_KASAN may redefine memset to __memset.
>> + * __memset function is present only in kernel binary.
>> + * Since the EFI stub linked into a separate binary it
>> + * doesn't have __memset(). So we should use standard
>> + * memset from arch/x86/boot/compressed/string.c
>> + * The same applies to memcpy and memmove.
>> + */
>> +#undef memcpy
>> +#undef memset
>> +#undef memmove
>
> Hm, so this hack got upstream via -mm, and it breaks the 64-bit x86 build with
> some configs:
>
>  arch/x86/platform/efi/efi.c:673:3: error: implicit declaration of function ?memcpy? [-Werror=implicit-function-declaration]
>  arch/x86/platform/efi/efi_64.c:139:2: error: implicit declaration of function ?memcpy? [-Werror=implicit-function-declaration]
>  ./arch/x86/include/asm/desc.h:121:2: error: implicit declaration of function ?memcpy? [-Werror=implicit-function-declaration]
>
> I guess it's about EFI=y but KASAN=n. Config attached.

It's actually, it's about KMEMCHECK=y and KASAN=n, because declaration
of memcpy() is hidden under ifndef.

arch/x86/include/asm/string_64.h:
    #ifndef CONFIG_KMEMCHECK
    #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
    extern void *memcpy(void *to, const void *from, size_t len);
    #else
    #define memcpy(dst, src, len)                                   \
    .......
    #endif
    #else
    /*
     * kmemcheck becomes very happy if we use the REP instructions
unconditionally,
     * because it means that we know both memory operands in advance.
     */
    #define memcpy(dst, src, len) __inline_memcpy((dst), (src), (len))
    #endif

So it also broke build with GCCs 4.0 - 4.3.
And it also breaks clang build, because AFAIK clang defines GNUC,
GNUC_MINOR as 4.2.

>
> beyond fixing the build bug ... could we also engineer this in a better fashion
> than spreading random #undefs across various KASAN unrelated headers?

I think we can add something like -DNOT_KERNEL (anyone has a better name ?)
to the CFLAGS for everything that is not linked with the kernel binary
(efistub, arch/x86/boot)

So, if NOT_KERNEL is defined we will not #define memcpy(), so we won't
need these undefs.


> Thanks,
>
>         Ingo

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
                   ` (5 preceding siblings ...)
  2015-09-17  9:38 ` [PATCH v6 6/6] Documentation/features/KASAN: arm64 supports KASAN now Andrey Ryabinin
@ 2015-10-07 10:04 ` Catalin Marinas
  2015-10-08 10:36   ` Andrey Ryabinin
  6 siblings, 1 reply; 22+ messages in thread
From: Catalin Marinas @ 2015-10-07 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
> As usual patches available in git
> 	git://github.com/aryabinin/linux.git kasan/arm64v6
> 
> Changes since v5:
>  - Rebase on top of 4.3-rc1
>  - Fixed EFI boot.
>  - Updated Doc/features/KASAN.

I tried to merge these patches (apart from the x86 one which is already
merged) but it still doesn't boot on Juno as an EFI application.

-- 
Catalin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-07 10:04 ` [PATCH v6 0/6] KASAN for arm64 Catalin Marinas
@ 2015-10-08 10:36   ` Andrey Ryabinin
  2015-10-08 11:06     ` Mark Rutland
  2015-10-08 11:11     ` Mark Rutland
  0 siblings, 2 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-08 10:36 UTC (permalink / raw)
  To: linux-arm-kernel

2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>> As usual patches available in git
>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>>
>> Changes since v5:
>>  - Rebase on top of 4.3-rc1
>>  - Fixed EFI boot.
>>  - Updated Doc/features/KASAN.
>
> I tried to merge these patches (apart from the x86 one which is already
> merged) but it still doesn't boot on Juno as an EFI application.
>

4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
regions")
It introduced sort() call in efi_get_virtmap().
sort() is generic kernel function and it's instrumented, so we crash
when KASAN tries to access shadow in sort().

[+CC efi some guys]

Comment in drivers/firmware/efi/libstub/Makefile says that EFI stub
executes with MMU disabled:
    # The stub may be linked into the kernel proper or into a separate
boot binary,
    # but in either case, it executes before the kernel does (with MMU
disabled) so
    # things like ftrace and stack-protector are likely to cause trouble if left
    # enabled, even if doing so doesn't break the build.

But in arch/arm64/kernel/efi-entry.S:
* We arrive here from the EFI boot manager with:
*
*    * CPU in little-endian mode
*    * MMU on with identity-mapped RAM

So is MMU enabled in ARM64 efi-stub?
If yes, we could solve this issue by mapping KASAN early shadow in efi stub.

> --
> Catalin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 10:36   ` Andrey Ryabinin
@ 2015-10-08 11:06     ` Mark Rutland
  2015-10-08 11:11     ` Mark Rutland
  1 sibling, 0 replies; 22+ messages in thread
From: Mark Rutland @ 2015-10-08 11:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
> > On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
> >> As usual patches available in git
> >>       git://github.com/aryabinin/linux.git kasan/arm64v6
> >>
> >> Changes since v5:
> >>  - Rebase on top of 4.3-rc1
> >>  - Fixed EFI boot.
> >>  - Updated Doc/features/KASAN.
> >
> > I tried to merge these patches (apart from the x86 one which is already
> > merged) but it still doesn't boot on Juno as an EFI application.
> >
> 
> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
> regions")
> It introduced sort() call in efi_get_virtmap().
> sort() is generic kernel function and it's instrumented, so we crash
> when KASAN tries to access shadow in sort().
> 
> [+CC efi some guys]
> 
> Comment in drivers/firmware/efi/libstub/Makefile says that EFI stub
> executes with MMU disabled:
>     # The stub may be linked into the kernel proper or into a separate
> boot binary,
>     # but in either case, it executes before the kernel does (with MMU
> disabled) so
>     # things like ftrace and stack-protector are likely to cause trouble if left
>     # enabled, even if doing so doesn't break the build.
> 
> But in arch/arm64/kernel/efi-entry.S:
> * We arrive here from the EFI boot manager with:
> *
> *    * CPU in little-endian mode
> *    * MMU on with identity-mapped RAM
> 
> So is MMU enabled in ARM64 efi-stub?

The stub is executed as an EFI application, which means that the MMU is
on, and the page tables are an idmap owned by the EFI implementation.

> If yes, we could solve this issue by mapping KASAN early shadow in efi stub.

As the page tables are owned by the implemenation and not the kernel, we
cannot alter them (at least not until we've called ExitBootServices(),
which happens relatively late).

Can we not build the stub without ASAN protections?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 10:36   ` Andrey Ryabinin
  2015-10-08 11:06     ` Mark Rutland
@ 2015-10-08 11:11     ` Mark Rutland
  2015-10-08 11:23       ` Andrey Ryabinin
  1 sibling, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-10-08 11:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
> > On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
> >> As usual patches available in git
> >>       git://github.com/aryabinin/linux.git kasan/arm64v6
> >>
> >> Changes since v5:
> >>  - Rebase on top of 4.3-rc1
> >>  - Fixed EFI boot.
> >>  - Updated Doc/features/KASAN.
> >
> > I tried to merge these patches (apart from the x86 one which is already
> > merged) but it still doesn't boot on Juno as an EFI application.
> >
> 
> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
> regions")
> It introduced sort() call in efi_get_virtmap().
> sort() is generic kernel function and it's instrumented, so we crash
> when KASAN tries to access shadow in sort().

I believe this is solved by Ard's stub isolation series [1,2], which
will build a stub-specific copy of sort() and various other functions
(see the arm-deps in [2]).

So long as the stub is not built with ASAN, that should work.

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373807.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373808.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 11:11     ` Mark Rutland
@ 2015-10-08 11:23       ` Andrey Ryabinin
  2015-10-08 12:09         ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-08 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/08/2015 02:11 PM, Mark Rutland wrote:
> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>>>> As usual patches available in git
>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>>>>
>>>> Changes since v5:
>>>>  - Rebase on top of 4.3-rc1
>>>>  - Fixed EFI boot.
>>>>  - Updated Doc/features/KASAN.
>>>
>>> I tried to merge these patches (apart from the x86 one which is already
>>> merged) but it still doesn't boot on Juno as an EFI application.
>>>
>>
>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
>> regions")
>> It introduced sort() call in efi_get_virtmap().
>> sort() is generic kernel function and it's instrumented, so we crash
>> when KASAN tries to access shadow in sort().
> 
> I believe this is solved by Ard's stub isolation series [1,2], which
> will build a stub-specific copy of sort() and various other functions
> (see the arm-deps in [2]).
> 
> So long as the stub is not built with ASAN, that should work.

Thanks, this should help, as we already build the stub without ASAN instrumentation.

> 
> Mark.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373807.html
> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/373808.html
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 11:23       ` Andrey Ryabinin
@ 2015-10-08 12:09         ` Ard Biesheuvel
  2015-10-08 15:11           ` Catalin Marinas
  0 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-10-08 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 8 October 2015 at 13:23, Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
> On 10/08/2015 02:11 PM, Mark Rutland wrote:
>> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
>>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>>>>> As usual patches available in git
>>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>>>>>
>>>>> Changes since v5:
>>>>>  - Rebase on top of 4.3-rc1
>>>>>  - Fixed EFI boot.
>>>>>  - Updated Doc/features/KASAN.
>>>>
>>>> I tried to merge these patches (apart from the x86 one which is already
>>>> merged) but it still doesn't boot on Juno as an EFI application.
>>>>
>>>
>>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
>>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
>>> regions")
>>> It introduced sort() call in efi_get_virtmap().
>>> sort() is generic kernel function and it's instrumented, so we crash
>>> when KASAN tries to access shadow in sort().
>>
>> I believe this is solved by Ard's stub isolation series [1,2], which
>> will build a stub-specific copy of sort() and various other functions
>> (see the arm-deps in [2]).
>>
>> So long as the stub is not built with ASAN, that should work.
>
> Thanks, this should help, as we already build the stub without ASAN instrumentation.
>

Indeed. I did not mention instrumentation in the commit log for those
patches, but obviously, something like KASAN instrumentation cannot be
tolerated in the stub since it makes assumptions about the memory
layout

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 12:09         ` Ard Biesheuvel
@ 2015-10-08 15:11           ` Catalin Marinas
  2015-10-08 16:01             ` Ard Biesheuvel
  2015-10-08 16:07             ` Andrey Ryabinin
  0 siblings, 2 replies; 22+ messages in thread
From: Catalin Marinas @ 2015-10-08 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 08, 2015 at 02:09:26PM +0200, Ard Biesheuvel wrote:
> On 8 October 2015 at 13:23, Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
> > On 10/08/2015 02:11 PM, Mark Rutland wrote:
> >> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
> >>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
> >>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
> >>>>> As usual patches available in git
> >>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
> >>>>>
> >>>>> Changes since v5:
> >>>>>  - Rebase on top of 4.3-rc1
> >>>>>  - Fixed EFI boot.
> >>>>>  - Updated Doc/features/KASAN.
> >>>>
> >>>> I tried to merge these patches (apart from the x86 one which is already
> >>>> merged) but it still doesn't boot on Juno as an EFI application.
> >>>>
> >>>
> >>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
> >>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
> >>> regions")
> >>> It introduced sort() call in efi_get_virtmap().
> >>> sort() is generic kernel function and it's instrumented, so we crash
> >>> when KASAN tries to access shadow in sort().
> >>
> >> I believe this is solved by Ard's stub isolation series [1,2], which
> >> will build a stub-specific copy of sort() and various other functions
> >> (see the arm-deps in [2]).
> >>
> >> So long as the stub is not built with ASAN, that should work.
> >
> > Thanks, this should help, as we already build the stub without ASAN instrumentation.
> 
> Indeed. I did not mention instrumentation in the commit log for those
> patches, but obviously, something like KASAN instrumentation cannot be
> tolerated in the stub since it makes assumptions about the memory
> layout

I'll review your latest EFI stub isolation patches and try Kasan again
on top (most likely tomorrow).

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 15:11           ` Catalin Marinas
@ 2015-10-08 16:01             ` Ard Biesheuvel
  2015-10-08 16:07             ` Andrey Ryabinin
  1 sibling, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-10-08 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

(+ Matt)

On 8 October 2015 at 17:11, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Thu, Oct 08, 2015 at 02:09:26PM +0200, Ard Biesheuvel wrote:
>> On 8 October 2015 at 13:23, Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
>> > On 10/08/2015 02:11 PM, Mark Rutland wrote:
>> >> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
>> >>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>> >>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>> >>>>> As usual patches available in git
>> >>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>> >>>>>
>> >>>>> Changes since v5:
>> >>>>>  - Rebase on top of 4.3-rc1
>> >>>>>  - Fixed EFI boot.
>> >>>>>  - Updated Doc/features/KASAN.
>> >>>>
>> >>>> I tried to merge these patches (apart from the x86 one which is already
>> >>>> merged) but it still doesn't boot on Juno as an EFI application.
>> >>>>
>> >>>
>> >>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
>> >>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
>> >>> regions")
>> >>> It introduced sort() call in efi_get_virtmap().
>> >>> sort() is generic kernel function and it's instrumented, so we crash
>> >>> when KASAN tries to access shadow in sort().
>> >>
>> >> I believe this is solved by Ard's stub isolation series [1,2], which
>> >> will build a stub-specific copy of sort() and various other functions
>> >> (see the arm-deps in [2]).
>> >>
>> >> So long as the stub is not built with ASAN, that should work.
>> >
>> > Thanks, this should help, as we already build the stub without ASAN instrumentation.
>>
>> Indeed. I did not mention instrumentation in the commit log for those
>> patches, but obviously, something like KASAN instrumentation cannot be
>> tolerated in the stub since it makes assumptions about the memory
>> layout
>
> I'll review your latest EFI stub isolation patches and try Kasan again
> on top (most likely tomorrow).
>

OK.

If you (and Matt) are ok with those, I'd like to spin a new version
that only adds strcmp(). We need that in a separate series that only
touches libstub, so with strcmp() added, we are completely independent
in terms of merging order.

Thanks,
Ard.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 15:11           ` Catalin Marinas
  2015-10-08 16:01             ` Ard Biesheuvel
@ 2015-10-08 16:07             ` Andrey Ryabinin
  2015-10-09  9:32               ` Andrey Ryabinin
  1 sibling, 1 reply; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-08 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

2015-10-08 18:11 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
> On Thu, Oct 08, 2015 at 02:09:26PM +0200, Ard Biesheuvel wrote:
>> On 8 October 2015 at 13:23, Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
>> > On 10/08/2015 02:11 PM, Mark Rutland wrote:
>> >> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
>> >>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>> >>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>> >>>>> As usual patches available in git
>> >>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>> >>>>>
>> >>>>> Changes since v5:
>> >>>>>  - Rebase on top of 4.3-rc1
>> >>>>>  - Fixed EFI boot.
>> >>>>>  - Updated Doc/features/KASAN.
>> >>>>
>> >>>> I tried to merge these patches (apart from the x86 one which is already
>> >>>> merged) but it still doesn't boot on Juno as an EFI application.
>> >>>>
>> >>>
>> >>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
>> >>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
>> >>> regions")
>> >>> It introduced sort() call in efi_get_virtmap().
>> >>> sort() is generic kernel function and it's instrumented, so we crash
>> >>> when KASAN tries to access shadow in sort().
>> >>
>> >> I believe this is solved by Ard's stub isolation series [1,2], which
>> >> will build a stub-specific copy of sort() and various other functions
>> >> (see the arm-deps in [2]).
>> >>
>> >> So long as the stub is not built with ASAN, that should work.
>> >
>> > Thanks, this should help, as we already build the stub without ASAN instrumentation.
>>
>> Indeed. I did not mention instrumentation in the commit log for those
>> patches, but obviously, something like KASAN instrumentation cannot be
>> tolerated in the stub since it makes assumptions about the memory
>> layout
>
> I'll review your latest EFI stub isolation patches and try Kasan again
> on top (most likely tomorrow).

You'd better wait for v7, because kasan patches will need some adjustment.
Since stub is isolated,  we need to handle memcpy vs __memcpy stuff the same
way as we do in x86. Now we also need to #undef memset/memcpy/memmove in ARM64
(just like this was done for x86).

But instead of spreading these #undef across various headers, I will
make a patch (most likely tomorrow)
which will get rid of these #undefs completely (the idea was described
here: https://lkml.org/lkml/2015/9/29/607)
And I'll will send v7 on top of that patch + Ard's work.


> Thanks.
>
> --
> Catalin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-08 16:07             ` Andrey Ryabinin
@ 2015-10-09  9:32               ` Andrey Ryabinin
  2015-10-09  9:48                 ` Mark Rutland
  0 siblings, 1 reply; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-09  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/08/2015 07:07 PM, Andrey Ryabinin wrote:
> 2015-10-08 18:11 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>> On Thu, Oct 08, 2015 at 02:09:26PM +0200, Ard Biesheuvel wrote:
>>> On 8 October 2015 at 13:23, Andrey Ryabinin <ryabinin.a.a@gmail.com> wrote:
>>>> On 10/08/2015 02:11 PM, Mark Rutland wrote:
>>>>> On Thu, Oct 08, 2015 at 01:36:09PM +0300, Andrey Ryabinin wrote:
>>>>>> 2015-10-07 13:04 GMT+03:00 Catalin Marinas <catalin.marinas@arm.com>:
>>>>>>> On Thu, Sep 17, 2015 at 12:38:06PM +0300, Andrey Ryabinin wrote:
>>>>>>>> As usual patches available in git
>>>>>>>>       git://github.com/aryabinin/linux.git kasan/arm64v6
>>>>>>>>
>>>>>>>> Changes since v5:
>>>>>>>>  - Rebase on top of 4.3-rc1
>>>>>>>>  - Fixed EFI boot.
>>>>>>>>  - Updated Doc/features/KASAN.
>>>>>>>
>>>>>>> I tried to merge these patches (apart from the x86 one which is already
>>>>>>> merged) but it still doesn't boot on Juno as an EFI application.
>>>>>>>
>>>>>>
>>>>>> 4.3-rc1 was ok and 4.3-rc4 is not. Break caused by 0ce3cc008ec04
>>>>>> ("arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME
>>>>>> regions")
>>>>>> It introduced sort() call in efi_get_virtmap().
>>>>>> sort() is generic kernel function and it's instrumented, so we crash
>>>>>> when KASAN tries to access shadow in sort().
>>>>>
>>>>> I believe this is solved by Ard's stub isolation series [1,2], which
>>>>> will build a stub-specific copy of sort() and various other functions
>>>>> (see the arm-deps in [2]).
>>>>>
>>>>> So long as the stub is not built with ASAN, that should work.
>>>>
>>>> Thanks, this should help, as we already build the stub without ASAN instrumentation.
>>>
>>> Indeed. I did not mention instrumentation in the commit log for those
>>> patches, but obviously, something like KASAN instrumentation cannot be
>>> tolerated in the stub since it makes assumptions about the memory
>>> layout
>>
>> I'll review your latest EFI stub isolation patches and try Kasan again
>> on top (most likely tomorrow).
> 
> You'd better wait for v7, because kasan patches will need some adjustment.
> Since stub is isolated,  we need to handle memcpy vs __memcpy stuff the same
> way as we do in x86. Now we also need to #undef memset/memcpy/memmove in ARM64
> (just like this was done for x86).
> 

Hm, I was wrong, we don't need that.

I thought the EFI stub isolation patches create a copy of mem*() functions in the stub,
but they are just create aliases with __efistub_ prefix.

We only need to create some more aliases for KASAN.
The following patch on top of the EFI stub isolation series works for me.


Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
---
 arch/arm64/kernel/image.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
index e083af0..6eb8fee 100644
--- a/arch/arm64/kernel/image.h
+++ b/arch/arm64/kernel/image.h
@@ -80,6 +80,12 @@ __efistub_strcmp		= __pi_strcmp;
 __efistub_strncmp		= __pi_strncmp;
 __efistub___flush_dcache_area	= __pi___flush_dcache_area;
 
+#ifdef CONFIG_KASAN
+__efistub___memcpy		= __pi_memcpy;
+__efistub___memmove		= __pi_memmove;
+__efistub___memset		= __pi_memset;
+#endif
+
 __efistub__text			= _text;
 __efistub__end			= _end;
 __efistub__edata		= _edata;
-- 
2.4.9

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-09  9:32               ` Andrey Ryabinin
@ 2015-10-09  9:48                 ` Mark Rutland
  2015-10-09 10:18                   ` Andrey Ryabinin
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-10-09  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 09, 2015 at 12:32:18PM +0300, Andrey Ryabinin wrote:
[...]

> I thought the EFI stub isolation patches create a copy of mem*() functions in the stub,
> but they are just create aliases with __efistub_ prefix.
> 
> We only need to create some more aliases for KASAN.
> The following patch on top of the EFI stub isolation series works for me.
> 
> 
> Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> ---
>  arch/arm64/kernel/image.h | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
> index e083af0..6eb8fee 100644
> --- a/arch/arm64/kernel/image.h
> +++ b/arch/arm64/kernel/image.h
> @@ -80,6 +80,12 @@ __efistub_strcmp		= __pi_strcmp;
>  __efistub_strncmp		= __pi_strncmp;
>  __efistub___flush_dcache_area	= __pi___flush_dcache_area;
>  
> +#ifdef CONFIG_KASAN
> +__efistub___memcpy		= __pi_memcpy;
> +__efistub___memmove		= __pi_memmove;
> +__efistub___memset		= __pi_memset;
> +#endif

Ard's v4 stub isolation series has these aliases [1], as the stub
requires these aliases regardless of KASAN in order to link.

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/375708.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-09  9:48                 ` Mark Rutland
@ 2015-10-09 10:18                   ` Andrey Ryabinin
  2015-10-09 12:42                     ` Mark Rutland
  0 siblings, 1 reply; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-09 10:18 UTC (permalink / raw)
  To: linux-arm-kernel

2015-10-09 12:48 GMT+03:00 Mark Rutland <mark.rutland@arm.com>:
> On Fri, Oct 09, 2015 at 12:32:18PM +0300, Andrey Ryabinin wrote:
> [...]
>
>> I thought the EFI stub isolation patches create a copy of mem*() functions in the stub,
>> but they are just create aliases with __efistub_ prefix.
>>
>> We only need to create some more aliases for KASAN.
>> The following patch on top of the EFI stub isolation series works for me.
>>
>>
>> Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
>> ---
>>  arch/arm64/kernel/image.h | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
>> index e083af0..6eb8fee 100644
>> --- a/arch/arm64/kernel/image.h
>> +++ b/arch/arm64/kernel/image.h
>> @@ -80,6 +80,12 @@ __efistub_strcmp           = __pi_strcmp;
>>  __efistub_strncmp            = __pi_strncmp;
>>  __efistub___flush_dcache_area        = __pi___flush_dcache_area;
>>
>> +#ifdef CONFIG_KASAN
>> +__efistub___memcpy           = __pi_memcpy;
>> +__efistub___memmove          = __pi_memmove;
>> +__efistub___memset           = __pi_memset;
>> +#endif
>
> Ard's v4 stub isolation series has these aliases [1], as the stub
> requires these aliases regardless of KASAN in order to link.

Stub isolation series has __efistub_memcpy, not __efistub___memcpy
(two additional '_').
The thing is, KASAN provides own implementation of memcpy() which
checks memory before access.
The original 'memcpy()' becomes __memcpy(), so we could still use it.
In code that not instrumented by KASAN (like the EFI stub) we replace
KASAN's memcpy() with the original __mempcy():
#define memcpy() __memcpy()

So with CONFIG_KASAN=y the EFI stub uses __memcpy, thus we need to
create the __efistub___memcpy alias.

>
> Thanks,
> Mark.
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/375708.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-09 10:18                   ` Andrey Ryabinin
@ 2015-10-09 12:42                     ` Mark Rutland
  2015-10-09 14:34                       ` Andrey Ryabinin
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-10-09 12:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 09, 2015 at 01:18:09PM +0300, Andrey Ryabinin wrote:
> 2015-10-09 12:48 GMT+03:00 Mark Rutland <mark.rutland@arm.com>:
> > On Fri, Oct 09, 2015 at 12:32:18PM +0300, Andrey Ryabinin wrote:
> > [...]
> >
> >> I thought the EFI stub isolation patches create a copy of mem*() functions in the stub,
> >> but they are just create aliases with __efistub_ prefix.
> >>
> >> We only need to create some more aliases for KASAN.
> >> The following patch on top of the EFI stub isolation series works for me.
> >>
> >>
> >> Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> >> ---
> >>  arch/arm64/kernel/image.h | 6 ++++++
> >>  1 file changed, 6 insertions(+)
> >>
> >> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
> >> index e083af0..6eb8fee 100644
> >> --- a/arch/arm64/kernel/image.h
> >> +++ b/arch/arm64/kernel/image.h
> >> @@ -80,6 +80,12 @@ __efistub_strcmp           = __pi_strcmp;
> >>  __efistub_strncmp            = __pi_strncmp;
> >>  __efistub___flush_dcache_area        = __pi___flush_dcache_area;
> >>
> >> +#ifdef CONFIG_KASAN
> >> +__efistub___memcpy           = __pi_memcpy;
> >> +__efistub___memmove          = __pi_memmove;
> >> +__efistub___memset           = __pi_memset;
> >> +#endif
> >
> > Ard's v4 stub isolation series has these aliases [1], as the stub
> > requires these aliases regardless of KASAN in order to link.
> 
> Stub isolation series has __efistub_memcpy, not __efistub___memcpy
> (two additional '_').

Ah, I see, sorry for my sloppy reading.

> The thing is, KASAN provides own implementation of memcpy() which
> checks memory before access.
> The original 'memcpy()' becomes __memcpy(), so we could still use it.

Ok.

> In code that not instrumented by KASAN (like the EFI stub) we replace
> KASAN's memcpy() with the original __mempcy():
> #define memcpy() __memcpy()

I'm a little confused by this. Surely that doesn't override implicit
calls generated by the compiler, leaving us with a mixture of calls to
memcpy and __memcpy?

That doesn't matter for the stub, as both __efistub_mem* and
__efistub___mem* would point at __pe_mem*, but doesn't that matter for
other users that shouldn't be instrumented?

Is that not a problem, or do we inhibit/override that somehow?

> So with CONFIG_KASAN=y the EFI stub uses __memcpy, thus we need to
> create the __efistub___memcpy alias.

Ok, that makes sense to me.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6 0/6] KASAN for arm64
  2015-10-09 12:42                     ` Mark Rutland
@ 2015-10-09 14:34                       ` Andrey Ryabinin
  0 siblings, 0 replies; 22+ messages in thread
From: Andrey Ryabinin @ 2015-10-09 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

2015-10-09 15:42 GMT+03:00 Mark Rutland <mark.rutland@arm.com>:
> On Fri, Oct 09, 2015 at 01:18:09PM +0300, Andrey Ryabinin wrote:
>> 2015-10-09 12:48 GMT+03:00 Mark Rutland <mark.rutland@arm.com>:
>> > On Fri, Oct 09, 2015 at 12:32:18PM +0300, Andrey Ryabinin wrote:
>> > [...]
>> >
>> >> I thought the EFI stub isolation patches create a copy of mem*() functions in the stub,
>> >> but they are just create aliases with __efistub_ prefix.
>> >>
>> >> We only need to create some more aliases for KASAN.
>> >> The following patch on top of the EFI stub isolation series works for me.
>> >>
>> >>
>> >> Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
>> >> ---
>> >>  arch/arm64/kernel/image.h | 6 ++++++
>> >>  1 file changed, 6 insertions(+)
>> >>
>> >> diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h
>> >> index e083af0..6eb8fee 100644
>> >> --- a/arch/arm64/kernel/image.h
>> >> +++ b/arch/arm64/kernel/image.h
>> >> @@ -80,6 +80,12 @@ __efistub_strcmp           = __pi_strcmp;
>> >>  __efistub_strncmp            = __pi_strncmp;
>> >>  __efistub___flush_dcache_area        = __pi___flush_dcache_area;
>> >>
>> >> +#ifdef CONFIG_KASAN
>> >> +__efistub___memcpy           = __pi_memcpy;
>> >> +__efistub___memmove          = __pi_memmove;
>> >> +__efistub___memset           = __pi_memset;
>> >> +#endif
>> >
>> > Ard's v4 stub isolation series has these aliases [1], as the stub
>> > requires these aliases regardless of KASAN in order to link.
>>
>> Stub isolation series has __efistub_memcpy, not __efistub___memcpy
>> (two additional '_').
>
> Ah, I see, sorry for my sloppy reading.
>
>> The thing is, KASAN provides own implementation of memcpy() which
>> checks memory before access.
>> The original 'memcpy()' becomes __memcpy(), so we could still use it.
>
> Ok.
>
>> In code that not instrumented by KASAN (like the EFI stub) we replace
>> KASAN's memcpy() with the original __mempcy():
>> #define memcpy() __memcpy()
>
> I'm a little confused by this. Surely that doesn't override implicit
> calls generated by the compiler, leaving us with a mixture of calls to
> memcpy and __memcpy?
>
> That doesn't matter for the stub, as both __efistub_mem* and
> __efistub___mem* would point at __pe_mem*, but doesn't that matter for
> other users that shouldn't be instrumented?
>
> Is that not a problem, or do we inhibit/override that somehow?
>

You are right, GCC could emit memcpy() call. It's just not a problem so far.
The amount of not instrumented code is fairly small (some low-level
x86 code, kasan internals and slub allocator).

The purpose of these defines is to not spread kasan-specific details
across unrelated code.
E.g. there are a lot of memcpy()/memset() calls in slub that used to
access object's redzone or
freed objects. So it simpler to redefine memset, rather then somehow
mangle that code.

>> So with CONFIG_KASAN=y the EFI stub uses __memcpy, thus we need to
>> create the __efistub___memcpy alias.
>
> Ok, that makes sense to me.
>
> Thanks,
> Mark.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2015-10-09 14:34 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-17  9:38 [PATCH v6 0/6] KASAN for arm64 Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 1/6] arm64: introduce VA_START macro - the first kernel virtual address Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 2/6] arm64: move PGD_SIZE definition to pgalloc.h Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 3/6] x86, efi, kasan: #undef memset/memcpy/memmove per arch Andrey Ryabinin
     [not found]   ` <20150929083814.GA32127@gmail.com>
2015-09-29 15:34     ` Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 4/6] arm64: add KASAN support Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 5/6] ARM64: kasan: print memory assignment Andrey Ryabinin
2015-09-17  9:38 ` [PATCH v6 6/6] Documentation/features/KASAN: arm64 supports KASAN now Andrey Ryabinin
2015-10-07 10:04 ` [PATCH v6 0/6] KASAN for arm64 Catalin Marinas
2015-10-08 10:36   ` Andrey Ryabinin
2015-10-08 11:06     ` Mark Rutland
2015-10-08 11:11     ` Mark Rutland
2015-10-08 11:23       ` Andrey Ryabinin
2015-10-08 12:09         ` Ard Biesheuvel
2015-10-08 15:11           ` Catalin Marinas
2015-10-08 16:01             ` Ard Biesheuvel
2015-10-08 16:07             ` Andrey Ryabinin
2015-10-09  9:32               ` Andrey Ryabinin
2015-10-09  9:48                 ` Mark Rutland
2015-10-09 10:18                   ` Andrey Ryabinin
2015-10-09 12:42                     ` Mark Rutland
2015-10-09 14:34                       ` Andrey Ryabinin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).