linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5 v2] KASan for ARM
@ 2020-04-12  0:24 Linus Walleij
  2020-04-12  0:24 ` [PATCH 1/5 v2] ARM: Disable KASan instrumentation for some code Linus Walleij
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Linus Walleij, linux-arm-kernel

I am trying to pick up this series.

I rebased it on what is soon v5.7-rc1 and fixed some bug
or two (see individual ChangeLog on the patches).

The main thing I need to fix here is the usage of TTBR0
in patch 4. This isn't working for machines without
TTBR0 obviously. I need help with the right approach
here.

I want to support all ARM CPUs that we support with the
kernel and it is not far off: I tried it in Faraday's
FA526 and it mostly works until we reach userspace
and my guess is that that is because of the TTBR0
shortcut it is taking.

What is interesting is that if I compile in the KASan
test module into the kernel, it performs most of the
tests correctly even on this old platform, so we only
have a few things to fix.

Abbott Liu (1):
  ARM: Define the virtual space of KASan's shadow region

Andrey Ryabinin (4):
  ARM: Disable KASan instrumentation for some code
  ARM: Replace memory functions for KASan
  ARM: Initialize the mapping of KASan shadow memory
  ARM: Enable KASan for ARM

 Documentation/dev-tools/kasan.rst     |   4 +-
 arch/arm/Kconfig                      |  10 +
 arch/arm/boot/compressed/Makefile     |   3 +
 arch/arm/include/asm/kasan.h          |  32 +++
 arch/arm/include/asm/kasan_def.h      |  81 +++++++
 arch/arm/include/asm/memory.h         |   5 +
 arch/arm/include/asm/pgalloc.h        |   9 +-
 arch/arm/include/asm/string.h         |  17 ++
 arch/arm/include/asm/thread_info.h    |   4 +
 arch/arm/kernel/entry-armv.S          |   5 +-
 arch/arm/kernel/entry-common.S        |   9 +-
 arch/arm/kernel/head-common.S         |   7 +-
 arch/arm/kernel/setup.c               |   2 +
 arch/arm/kernel/unwind.c              |   6 +-
 arch/arm/lib/memcpy.S                 |   3 +
 arch/arm/lib/memmove.S                |   5 +-
 arch/arm/lib/memset.S                 |   3 +
 arch/arm/mm/Makefile                  |   4 +
 arch/arm/mm/kasan_init.c              | 324 ++++++++++++++++++++++++++
 arch/arm/mm/mmu.c                     |   7 +-
 arch/arm/mm/pgd.c                     |  14 ++
 arch/arm/vdso/Makefile                |   2 +
 drivers/firmware/efi/libstub/Makefile |   5 +-
 23 files changed, 546 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/include/asm/kasan.h
 create mode 100644 arch/arm/include/asm/kasan_def.h
 create mode 100644 arch/arm/mm/kasan_init.c

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/5 v2] ARM: Disable KASan instrumentation for some code
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
@ 2020-04-12  0:24 ` Linus Walleij
  2020-04-12  0:24 ` [PATCH 2/5 v2] ARM: Replace memory functions for KASan Linus Walleij
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Marc Zyngier, Linus Walleij, linux-arm-kernel

From: Andrey Ryabinin <aryabinin@virtuozzo.com>

Disable instrumentation for arch/arm/boot/compressed/*
since that code is executed before the kernel has even
set up its mappings and definately out of scope for
KASan.

Disable instrumentation of arch/arm/vdso/* because that code
is not linked with the kernel image, so the KASan management
code would fail to link.

Disable instrumentation of arch/arm/mm/physaddr.c. See commit
ec6d06efb0ba ("arm64: Add support for CONFIG_DEBUG_VIRTUAL")
for more details.

Disable kasan check in the function unwind_pop_register because
it does not matter that kasan checks failed when unwind_pop_register()
reads the stack memory of a task.

Reported-by: Florian Fainelli <f.fainelli@gmail.com>
Reported-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Abbott Liu <liuwenliang@huawei.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Removed the KVM instrumentaton disablement since KVM
  on ARM32 is gone.
---
 arch/arm/boot/compressed/Makefile | 1 +
 arch/arm/kernel/unwind.c          | 6 +++++-
 arch/arm/mm/Makefile              | 1 +
 arch/arm/vdso/Makefile            | 2 ++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 9c11e7490292..abd6f3d5c2ba 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -24,6 +24,7 @@ OBJS		+= hyp-stub.o
 endif
 
 GCOV_PROFILE		:= n
+KASAN_SANITIZE		:= n
 
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT		:= n
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 11a964fd66f4..739a77f39a8f 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -236,7 +236,11 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
 		if (*vsp >= (unsigned long *)ctrl->sp_high)
 			return -URC_FAILURE;
 
-	ctrl->vrs[reg] = *(*vsp)++;
+	/* Use READ_ONCE_NOCHECK here to avoid this memory access
+	 * from being tracked by KASAN.
+	 */
+	ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp));
+	(*vsp)++;
 	return URC_OK;
 }
 
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 7cb1699fbfc4..432302911d6e 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -16,6 +16,7 @@ endif
 obj-$(CONFIG_ARM_PTDUMP_CORE)	+= dump.o
 obj-$(CONFIG_ARM_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
 obj-$(CONFIG_MODULES)		+= proc-syms.o
+KASAN_SANITIZE_physaddr.o	:= n
 obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index d3c9f03e7e79..71d18d59bd35 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -42,6 +42,8 @@ GCOV_PROFILE := n
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT := n
 
+KASAN_SANITIZE := n
+
 # Force dependency
 $(obj)/vdso.o : $(obj)/vdso.so
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/5 v2] ARM: Replace memory functions for KASan
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
  2020-04-12  0:24 ` [PATCH 1/5 v2] ARM: Disable KASan instrumentation for some code Linus Walleij
@ 2020-04-12  0:24 ` Linus Walleij
  2020-04-12  0:24 ` [PATCH 3/5 v2] ARM: Define the virtual space of KASan's shadow region Linus Walleij
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Linus Walleij, linux-arm-kernel

From: Andrey Ryabinin <aryabinin@virtuozzo.com>

Functions like memset()/memmove()/memcpy() do a lot of memory
accesses.

If a bad pointer is passed to one of these functions it is important
to catch this. Compiler instrumentation cannot do this since these
functions are written in assembly.

KASan replaces these memory functions with instrumented variants.

The original functions are declared as weak symbols so that
the strong definitions in mm/kasan/kasan.c can replace them.

The original functions have aliases with a '__' prefix in their
name, so we can call the non-instrumented variant if needed.

We must use __memcpy()/__memset() in place of memcpy()/memset()
when we copy .data to RAM and when we clear .bss, because
kasan_early_init cannot be called before the initialization of
.data and .bss.

For the kernel compression and EFI libstub we need to tag on
the -D__SANITIZE_ADDRESS__ CFLAG, which is unfortunate: this is
used only when building with KASan enabled.

When building with KASan, all mem*() functions such as memcpy()
etc are instrumented. However, code that disable KASan for an
entire directory with KASAN_SANITIZE := n in the Kconfig file will
run into problems if they try to use the mem*() functions, as the
define that guards the uninstrumented variants look like so:

  #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
  (...)
  define memcpy(dst, src, len) __memcpy(dst, src, len)
  (...)

As you see, KASAN is enabled, but the compilation procedure
relies on the Makefile passing -fsanitize=kernel-address
to the compiler for each instrumented file so that in turn
__SANITIZE_ADDRESS__ gets set and these weakly defined functions
are usually replaced with instrumented KASan variants.

If KASAN is enabled but __SANITIZE_ADDRESS__ is not set,
i.e. -fsanitize is not passed, the idea is that these #defines
kick in and define e.g. memcpy() to __memcpy() - all good.

Uncompress and libstub uses memcpy(), disables KASan with
KASAN_SANITIZE := n so CONFIG_KASAN is defined, but not
__SANITIZE_ADDRESS__ and we get a compilation error unless
we patch in -D__SANITIZE_ADDRESS__ to these Makefiles.

Reported-by: Russell King - ARM Linux <linux@armlinux.org.uk>
Signed-off-by: Abbott Liu <liuwenliang@huawei.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Move the hacks around __SANITIZE_ADDRESS__ into this file
- Edit the commit message
- Rebase on the other v2 patches
---
 arch/arm/boot/compressed/Makefile     |  2 ++
 arch/arm/include/asm/string.h         | 17 +++++++++++++++++
 arch/arm/kernel/head-common.S         |  4 ++--
 arch/arm/lib/memcpy.S                 |  3 +++
 arch/arm/lib/memmove.S                |  5 ++++-
 arch/arm/lib/memset.S                 |  3 +++
 drivers/firmware/efi/libstub/Makefile |  5 ++++-
 7 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index abd6f3d5c2ba..9d0316876052 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -25,6 +25,8 @@ endif
 
 GCOV_PROFILE		:= n
 KASAN_SANITIZE		:= n
+# Make sure we get the uninstrumented __mem*() functions
+CFLAGS_KERNEL		:= -D__SANITIZE_ADDRESS__
 
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT		:= n
diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index 111a1d8a41dd..2e1dd7a0cf63 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -15,15 +15,18 @@ extern char * strchr(const char * s, int c);
 
 #define __HAVE_ARCH_MEMCPY
 extern void * memcpy(void *, const void *, __kernel_size_t);
+extern void *__memcpy(void *dest, const void *src, __kernel_size_t n);
 
 #define __HAVE_ARCH_MEMMOVE
 extern void * memmove(void *, const void *, __kernel_size_t);
+extern void *__memmove(void *dest, const void *src, __kernel_size_t n);
 
 #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 *s, int c, __kernel_size_t n);
 
 #define __HAVE_ARCH_MEMSET32
 extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t);
@@ -39,4 +42,18 @@ static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n)
 	return __memset64(p, v, n * 8, v >> 32);
 }
 
+
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * must use non-instrumented versions of the 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/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 4a3982812a40..6840c7c60a85 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -95,7 +95,7 @@ __mmap_switched:
  THUMB(	ldmia	r4!, {r0, r1, r2, r3} )
  THUMB(	mov	sp, r3 )
 	sub	r2, r2, r1
-	bl	memcpy				@ copy .data to RAM
+	bl	__memcpy			@ copy .data to RAM
 #endif
 
    ARM(	ldmia	r4!, {r0, r1, sp} )
@@ -103,7 +103,7 @@ __mmap_switched:
  THUMB(	mov	sp, r3 )
 	sub	r2, r1, r0
 	mov	r1, #0
-	bl	memset				@ clear .bss
+	bl	__memset			@ clear .bss
 
 	ldmia	r4, {r0, r1, r2, r3}
 	str	r9, [r0]			@ Save processor ID
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index 09a333153dc6..ad4625d16e11 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -58,6 +58,8 @@
 
 /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
 
+.weak memcpy
+ENTRY(__memcpy)
 ENTRY(mmiocpy)
 ENTRY(memcpy)
 
@@ -65,3 +67,4 @@ ENTRY(memcpy)
 
 ENDPROC(memcpy)
 ENDPROC(mmiocpy)
+ENDPROC(__memcpy)
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index b50e5770fb44..fd123ea5a5a4 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -24,12 +24,14 @@
  * occurring in the opposite direction.
  */
 
+.weak memmove
+ENTRY(__memmove)
 ENTRY(memmove)
 	UNWIND(	.fnstart			)
 
 		subs	ip, r0, r1
 		cmphi	r2, ip
-		bls	memcpy
+		bls	__memcpy
 
 		stmfd	sp!, {r0, r4, lr}
 	UNWIND(	.fnend				)
@@ -222,3 +224,4 @@ ENTRY(memmove)
 18:		backward_copy_shift	push=24	pull=8
 
 ENDPROC(memmove)
+ENDPROC(__memmove)
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 6ca4535c47fb..0e7ff0423f50 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -13,6 +13,8 @@
 	.text
 	.align	5
 
+.weak memset
+ENTRY(__memset)
 ENTRY(mmioset)
 ENTRY(memset)
 UNWIND( .fnstart         )
@@ -132,6 +134,7 @@ UNWIND( .fnstart            )
 UNWIND( .fnend   )
 ENDPROC(memset)
 ENDPROC(mmioset)
+ENDPROC(__memset)
 
 ENTRY(__memset32)
 UNWIND( .fnstart         )
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 094eabdecfe6..ea37c9c21273 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -19,9 +19,12 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ -O2 \
 # disable the stackleak plugin
 cflags-$(CONFIG_ARM64)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 				   -fpie $(DISABLE_STACKLEAK_PLUGIN)
+# Define __SANITIZE_ADDRESS__ in order to get the weak __mem*() functions
+# when building with KASan.
 cflags-$(CONFIG_ARM)		:= $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
 				   -fno-builtin -fpic \
-				   $(call cc-option,-mno-single-pic-base)
+				   $(call cc-option,-mno-single-pic-base) \
+				   -D__SANITIZE_ADDRESS__
 
 cflags-$(CONFIG_EFI_ARMSTUB)	+= -I$(srctree)/scripts/dtc/libfdt
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 3/5 v2] ARM: Define the virtual space of KASan's shadow region
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
  2020-04-12  0:24 ` [PATCH 1/5 v2] ARM: Disable KASan instrumentation for some code Linus Walleij
  2020-04-12  0:24 ` [PATCH 2/5 v2] ARM: Replace memory functions for KASan Linus Walleij
@ 2020-04-12  0:24 ` Linus Walleij
  2020-04-12  0:24 ` [PATCH 4/5 v2] ARM: Initialize the mapping of KASan shadow memory Linus Walleij
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Linus Walleij, linux-arm-kernel, Ard Biesheuvel

From: Abbott Liu <liuwenliang@huawei.com>

Define KASAN_SHADOW_OFFSET,KASAN_SHADOW_START and KASAN_SHADOW_END for
the Arm kernel address sanitizer. We are "stealing" lowmem (the 4GB
addressable by a 32bit architecture) out of the virtual address
space to use as shadow memory for KASan as follows:

 +----+ 0xffffffff
 |    |\
 |    | |-> Static kernel image (vmlinux) BSS and page table
 |    |/
 +----+ PAGE_OFFSET
 |    |\
 |    | |->  Loadable kernel modules virtual address space area
 |    |/
 +----+ MODULES_VADDR = KASAN_SHADOW_END
 |    |\
 |    | |-> The shadow area of kernel virtual address.
 |    |/
 +----+->  TASK_SIZE (start of kernel space) = KASAN_SHADOW_START the
 |    |\   shadow address of MODULES_VADDR
 |    | |
 |    | |
 |    | |-> The user space area in lowmem. The kernel address
 |    | |   sanitizer do not use this space, nor does it map it.
 |    | |
 |    | |
 |    | |
 |    | |
 |    |/
 ------ 0

0 .. TASK_SIZE is the memory that can be used by shared
userspace/kernelspace. It us used for userspace processes and for
passing parameters and memory buffers in system calls etc. We do not
need to shadow this area.

KASAN_SHADOW_START:
 This value begins with the MODULE_VADDR's shadow address. It is the
 start of kernel virtual space. Since we have modules to load, we need
 to cover also that area with shadow memory so we can find memory
 bugs in modules.

KASAN_SHADOW_END
 This value is the 0x100000000's shadow address: the mapping that would
 be after the end of the kernel memory at 0xffffffff. It is the end of
 kernel address sanitizer shadow area. It is also the start of the
 module area.

KASAN_SHADOW_OFFSET:
 This value is used to map an address to the corresponding shadow
 address by the following formula:

   shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;

 As you would expect, >> 3 is equal to dividing by 8, meaning each
 byte in the shadow memory covers 8 bytes of kernel memory, so one
 bit shadow memory per byte of kernel memory is used.

 The KASAN_SHADOW_OFFSET is provided in a Kconfig option depending
 on the VMSPLIT layout of the system: the kernel and userspace can
 split up lowmem in different ways according to needs, so we calculate
 the shadow offset depending on this.

When kasan is enabled, the definition of TASK_SIZE is not an 8-bit
rotated constant, so we need to modify the TASK_SIZE access code in the
*.s file.

The kernel and modules may use different amounts of memory,
according to the VMSPLIT configuration, which in turn
determines the PAGE_OFFSET.

We use the following KASAN_SHADOW_OFFSETs depending on how the
virtual memory is split up:

- 0x1f000000 if we have 1G userspace / 3G kernelspace split:
  - The kernel address space is 3G (0xc0000000)
  - PAGE_OFFSET is then set to 0x40000000 so the kernel static
    image (vmlinux) uses addresses 0x40000000 .. 0xffffffff
  - On top of that we have the MODULES_VADDR which under
    the worst case (using ARM instructions) is
    PAGE_OFFSET - 16M (0x01000000) = 0x3f000000
    so the modules use addresses 0x3f000000 .. 0x3fffffff
  - So the addresses 0x3f000000 .. 0xffffffff need to be
    covered with shadow memory. That is 0xc1000000 bytes
    of memory.
  - 1/8 of that is needed for its shadow memory, so
    0x18200000 bytes of shadow memory is needed. We
    "steal" that from the remaining lowmem.
  - The KASAN_SHADOW_START becomes 0x26e00000, to
    KASAN_SHADOW_END at 0x3effffff.
  - Now we can calculate the KASAN_SHADOW_OFFSET for any
    kernel address as 0x3f000000 needs to map to the first
    byte of shadow memory and 0xffffffff needs to map to
    the last byte of shadow memory. Since:
    SHADOW_ADDR = (address >> 3) + KASAN_SHADOW_OFFSET
    0x26e00000 = (0x3f000000 >> 3) + KASAN_SHADOW_OFFSET
    KASAN_SHADOW_OFFSET = 0x26e00000 - (0x3f000000 >> 3)
    KASAN_SHADOW_OFFSET = 0x26e00000 - 0x07e00000
    KASAN_SHADOW_OFFSET = 0x1f000000

- 0x5f000000 if we have 2G userspace / 2G kernelspace split:
  - The kernel space is 2G (0x80000000)
  - PAGE_OFFSET is set to 0x80000000 so the kernel static
    image uses 0x80000000 .. 0xffffffff.
  - On top of that we have the MODULES_VADDR which under
    the worst case (using ARM instructions) is
    PAGE_OFFSET - 16M (0x01000000) = 0x7f000000
    so the modules use addresses 0x7f000000 .. 0x7fffffff
  - So the addresses 0x7f000000 .. 0xffffffff need to be
    covered with shadow memory. That is 0x81000000 bytes
    of memory.
  - 1/8 of that is needed for its shadow memory, so
    0x10200000 bytes of shadow memory is needed. We
    "steal" that from the remaining lowmem.
  - The KASAN_SHADOW_START becomes 0x6ee00000, to
    KASAN_SHADOW_END at 0x7effffff.
  - Now we can calculate the KASAN_SHADOW_OFFSET for any
    kernel address as 0x7f000000 needs to map to the first
    byte of shadow memory and 0xffffffff needs to map to
    the last byte of shadow memory. Since:
    SHADOW_ADDR = (address >> 3) + KASAN_SHADOW_OFFSET
    0x6ee00000 = (0x7f000000 >> 3) + KASAN_SHADOW_OFFSET
    KASAN_SHADOW_OFFSET = 0x6ee00000 - (0x7f000000 >> 3)
    KASAN_SHADOW_OFFSET = 0x6ee00000 - 0x0fe00000
    KASAN_SHADOW_OFFSET = 0x5f000000

- 0x9f000000 if we have 3G userspace / 1G kernelspace split,
  and this is the default split for ARM:
  - The kernel address space is 1GB (0x40000000)
  - PAGE_OFFSET is set to 0xc0000000 so the kernel static
    image uses 0xc0000000 .. 0xffffffff.
  - On top of that we have the MODULES_VADDR which under
    the worst case (using ARM instructions) is
    PAGE_OFFSET - 16M (0x01000000) = 0xbf000000
    so the modules use addresses 0xbf000000 .. 0xbfffffff
  - So the addresses 0xbf000000 .. 0xffffffff need to be
    covered with shadow memory. That is 0x41000000 bytes
    of memory.
  - 1/8 of that is needed for its shadow memory, so
    0x08200000 bytes of shadow memory is needed. We
    "steal" that from the remaining lowmem.
  - The KASAN_SHADOW_START becomes 0xb6e00000, to
    KASAN_SHADOW_END at 0xbfffffff.
  - Now we can calculate the KASAN_SHADOW_OFFSET for any
    kernel address as 0xbf000000 needs to map to the first
    byte of shadow memory and 0xffffffff needs to map to
    the last byte of shadow memory. Since:
    SHADOW_ADDR = (address >> 3) + KASAN_SHADOW_OFFSET
    0xb6e00000 = (0xbf000000 >> 3) + KASAN_SHADOW_OFFSET
    KASAN_SHADOW_OFFSET = 0xb6e00000 - (0xbf000000 >> 3)
    KASAN_SHADOW_OFFSET = 0xb6e00000 - 0x17e00000
    KASAN_SHADOW_OFFSET = 0x9f000000

- 0x8f000000 if we have 3G userspace / 1G kernelspace with
  full 1 GB low memory (VMSPLIT_3G_OPT):
  - The kernel address space is 1GB (0x40000000)
  - PAGE_OFFSET is set to 0xb0000000 so the kernel static
    image uses 0xb0000000 .. 0xffffffff.
  - On top of that we have the MODULES_VADDR which under
    the worst case (using ARM instructions) is
    PAGE_OFFSET - 16M (0x01000000) = 0xaf000000
    so the modules use addresses 0xaf000000 .. 0xaffffff
  - So the addresses 0xaf000000 .. 0xffffffff need to be
    covered with shadow memory. That is 0x51000000 bytes
    of memory.
  - 1/8 of that is needed for its shadow memory, so
    0x0a200000 bytes of shadow memory is needed. We
    "steal" that from the remaining lowmem.
  - The KASAN_SHADOW_START becomes 0xa4e00000, to
    KASAN_SHADOW_END at 0xaeffffff.
  - Now we can calculate the KASAN_SHADOW_OFFSET for any
    kernel address as 0xaf000000 needs to map to the first
    byte of shadow memory and 0xffffffff needs to map to
    the last byte of shadow memory. Since:
    SHADOW_ADDR = (address >> 3) + KASAN_SHADOW_OFFSET
    0xa4e00000 = (0xaf000000 >> 3) + KASAN_SHADOW_OFFSET
    KASAN_SHADOW_OFFSET = 0xa4e00000 - (0xaf000000 >> 3)
    KASAN_SHADOW_OFFSET = 0xa4e00000 - 0x15e00000
    KASAN_SHADOW_OFFSET = 0x8f000000

- The default value of 0xffffffff for KASAN_SHADOW_OFFSET
  is an error value. We should always match one of the
  above shadow offsets.

When we do this, TASK_SIZE will sometimes get a bit odd values
that will not fit into immediate mov assembly instructions.
To account for this, we need to rewrite some assembly using
TASK_SIZE like this:

-       mov     r1, #TASK_SIZE
+       ldr     r1, =TASK_SIZE

or

-       cmp     r4, #TASK_SIZE
+       ldr     r0, =TASK_SIZE
+       cmp     r4, r0

this is done to avoid the immediate #TASK_SIZE that need to
fit into a limited number of bits.

Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Abbott Liu <liuwenliang@huawei.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Use the SPDX license identifier.
- Rewrote the commit message and updates the illustration.
- Move KASAN_OFFSET Kconfig set-up into this patch and put it
  right after PAGE_OFFSET so it is clear how this works, and
  we have all defines in one patch.
- Added KASAN_SHADOW_OFFSET of 0x8f000000 for 3G_OPT.
  See the calculation in the commit message.
- Updated the commit message with detailed information on
  how KASAN_SHADOW_OFFSET is obtained for the different
  VMSPLIT/PAGE_OFFSET options.
---
 arch/arm/Kconfig                 |  9 ++++
 arch/arm/include/asm/kasan_def.h | 81 ++++++++++++++++++++++++++++++++
 arch/arm/include/asm/memory.h    |  5 ++
 arch/arm/kernel/entry-armv.S     |  5 +-
 arch/arm/kernel/entry-common.S   |  9 ++--
 arch/arm/mm/mmu.c                |  7 ++-
 6 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/include/asm/kasan_def.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 66a04f6f4775..f6f2d3b202f5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1325,6 +1325,15 @@ config PAGE_OFFSET
 	default 0xB0000000 if VMSPLIT_3G_OPT
 	default 0xC0000000
 
+config KASAN_SHADOW_OFFSET
+	hex
+	depends on KASAN
+	default 0x1f000000 if PAGE_OFFSET=0x40000000
+	default 0x5f000000 if PAGE_OFFSET=0x80000000
+	default 0x9f000000 if PAGE_OFFSET=0xC0000000
+	default 0x8f000000 if PAGE_OFFSET=0xB0000000
+	default 0xffffffff
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
diff --git a/arch/arm/include/asm/kasan_def.h b/arch/arm/include/asm/kasan_def.h
new file mode 100644
index 000000000000..5739605aa7cf
--- /dev/null
+++ b/arch/arm/include/asm/kasan_def.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  arch/arm/include/asm/kasan_def.h
+ *
+ *  Copyright (c) 2018 Huawei Technologies Co., Ltd.
+ *
+ *  Author: Abbott Liu <liuwenliang@huawei.com>
+ */
+
+#ifndef __ASM_KASAN_DEF_H
+#define __ASM_KASAN_DEF_H
+
+#ifdef CONFIG_KASAN
+
+/*
+ * Define KASAN_SHADOW_OFFSET,KASAN_SHADOW_START and KASAN_SHADOW_END for
+ * the Arm kernel address sanitizer. We are "stealing" lowmem (the 4GB
+ * addressable by a 32bit architecture) out of the virtual address
+ * space to use as shadow memory for KASan as follows:
+ *
+ * +----+ 0xffffffff
+ * |    |							\
+ * |    | |-> Static kernel image (vmlinux) BSS and page table
+ * |    |/
+ * +----+ PAGE_OFFSET
+ * |    |							\
+ * |    | |->  Loadable kernel modules virtual address space area
+ * |    |/
+ * +----+ MODULES_VADDR = KASAN_SHADOW_END
+ * |    |						\
+ * |    | |-> The shadow area of kernel virtual address.
+ * |    |/
+ * +----+->  TASK_SIZE (start of kernel space) = KASAN_SHADOW_START the
+ * |    |\   shadow address of MODULES_VADDR
+ * |    | |
+ * |    | |
+ * |    | |-> The user space area in lowmem. The kernel address
+ * |    | |   sanitizer do not use this space, nor does it map it.
+ * |    | |
+ * |    | |
+ * |    | |
+ * |    | |
+ * |    |/
+ * ------ 0
+ *
+ * 1) KASAN_SHADOW_START
+ *   This value begins with the MODULE_VADDR's shadow address. It is the
+ *   start of kernel virtual space. Since we have modules to load, we need
+ *   to cover also that area with shadow memory so we can find memory
+ *   bugs in modules.
+ *
+ * 2) KASAN_SHADOW_END
+ *   This value is the 0x100000000's shadow address: the mapping that would
+ *   be after the end of the kernel memory at 0xffffffff. It is the end of
+ *   kernel address sanitizer shadow area. It is also the start of the
+ *   module area.
+ *
+ * 3) KASAN_SHADOW_OFFSET:
+ *   This value is used to map an address to the corresponding shadow
+ *   address by the following formula:
+ *
+ *	shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *
+ *  As you would expect, >> 3 is equal to dividing by 8, meaning each
+ *  byte in the shadow memory covers 8 bytes of kernel memory, so one
+ *  bit shadow memory per byte of kernel memory is used.
+ *
+ *  The KASAN_SHADOW_OFFSET is provided in a Kconfig option depending
+ *  on the VMSPLIT layout of the system: the kernel and userspace can
+ *  split up lowmem in different ways according to needs, so we calculate
+ *  the shadow offset depending on this.
+ */
+
+#define KASAN_SHADOW_SCALE_SHIFT	3
+#define KASAN_SHADOW_OFFSET	_AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_END	((UL(1) << (32 - KASAN_SHADOW_SCALE_SHIFT)) \
+				 + KASAN_SHADOW_OFFSET)
+#define KASAN_SHADOW_START      ((KASAN_SHADOW_END >> 3) + KASAN_SHADOW_OFFSET)
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 99035b5891ef..5cfa9e5dc733 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -18,6 +18,7 @@
 #ifdef CONFIG_NEED_MACH_MEMORY_H
 #include <mach/memory.h>
 #endif
+#include <asm/kasan_def.h>
 
 /* PAGE_OFFSET - the virtual address of the start of the kernel image */
 #define PAGE_OFFSET		UL(CONFIG_PAGE_OFFSET)
@@ -28,7 +29,11 @@
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
  */
+#ifndef CONFIG_KASAN
 #define TASK_SIZE		(UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M))
+#else
+#define TASK_SIZE		(KASAN_SHADOW_START)
+#endif
 #define TASK_UNMAPPED_BASE	ALIGN(TASK_SIZE / 3, SZ_16M)
 
 /*
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 77f54830554c..7548d38599ae 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -180,7 +180,7 @@ ENDPROC(__und_invalid)
 
 	get_thread_info tsk
 	ldr	r0, [tsk, #TI_ADDR_LIMIT]
-	mov	r1, #TASK_SIZE
+	ldr	r1, =TASK_SIZE
 	str	r1, [tsk, #TI_ADDR_LIMIT]
 	str	r0, [sp, #SVC_ADDR_LIMIT]
 
@@ -434,7 +434,8 @@ ENDPROC(__fiq_abt)
 	@ if it was interrupted in a critical region.  Here we
 	@ perform a quick test inline since it should be false
 	@ 99.9999% of the time.  The rest is done out of line.
-	cmp	r4, #TASK_SIZE
+	ldr	r0, =TASK_SIZE
+	cmp	r4, r0
 	blhs	kuser_cmpxchg64_fixup
 #endif
 #endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 271cb8a1eba1..fee279e28a72 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -50,7 +50,8 @@ __ret_fast_syscall:
  UNWIND(.cantunwind	)
 	disable_irq_notrace			@ disable interrupts
 	ldr	r2, [tsk, #TI_ADDR_LIMIT]
-	cmp	r2, #TASK_SIZE
+	ldr	r1, =TASK_SIZE
+	cmp	r2, r1
 	blne	addr_limit_check_failed
 	ldr	r1, [tsk, #TI_FLAGS]		@ re-check for syscall tracing
 	tst	r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
@@ -87,7 +88,8 @@ __ret_fast_syscall:
 #endif
 	disable_irq_notrace			@ disable interrupts
 	ldr	r2, [tsk, #TI_ADDR_LIMIT]
-	cmp	r2, #TASK_SIZE
+	ldr     r1, =TASK_SIZE
+	cmp     r2, r1
 	blne	addr_limit_check_failed
 	ldr	r1, [tsk, #TI_FLAGS]		@ re-check for syscall tracing
 	tst	r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
@@ -128,7 +130,8 @@ ret_slow_syscall:
 	disable_irq_notrace			@ disable interrupts
 ENTRY(ret_to_user_from_irq)
 	ldr	r2, [tsk, #TI_ADDR_LIMIT]
-	cmp	r2, #TASK_SIZE
+	ldr     r1, =TASK_SIZE
+	cmp	r2, r1
 	blne	addr_limit_check_failed
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 69a337df619f..0cc53cc903ec 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1246,9 +1246,14 @@ static inline void prepare_page_table(void)
 	/*
 	 * Clear out all the mappings below the kernel image.
 	 */
-	for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE)
+	for (addr = 0; addr < TASK_SIZE; addr += PMD_SIZE)
 		pmd_clear(pmd_off_k(addr));
 
+#ifdef CONFIG_KASAN
+	/*TASK_SIZE ~ MODULES_VADDR is the KASAN's shadow area -- skip over it*/
+	addr = MODULES_VADDR;
+#endif
+
 #ifdef CONFIG_XIP_KERNEL
 	/* The XIP kernel is mapped in the module area -- skip over it */
 	addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/5 v2] ARM: Initialize the mapping of KASan shadow memory
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
                   ` (2 preceding siblings ...)
  2020-04-12  0:24 ` [PATCH 3/5 v2] ARM: Define the virtual space of KASan's shadow region Linus Walleij
@ 2020-04-12  0:24 ` Linus Walleij
  2020-04-12  0:24 ` [PATCH 5/5 v2] ARM: Enable KASan for ARM Linus Walleij
  2020-06-01  4:00 ` [PATCH 0/5 v2] " Florian Fainelli
  5 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Linus Walleij, linux-arm-kernel

From: Andrey Ryabinin <aryabinin@virtuozzo.com>

This patch initializes KASan shadow region's page table and memory.
There are two stage for KASan initializing:

1. At early boot stage the whole shadow region is mapped to just
   one physical page (kasan_zero_page). It is finished by the function
   kasan_early_init which is called by __mmap_switched(arch/arm/kernel/
   head-common.S)
             ---Andrey Ryabinin <aryabinin@virtuozzo.com>

2. After the calling of paging_init, we use kasan_zero_page as zero
   shadow for some memory that KASan does not need to track, and we
   allocate a new shadow space for the other memory that KASan need to
   track. These issues are finished by the function kasan_init which is
   call by setup_arch.
            ---Andrey Ryabinin <aryabinin@virtuozzo.com>

3. Add support ARM LPAE
   If LPAE is enabled, KASan shadow region's mapping table need be copied
   in the pgd_alloc() function.
            ---Abbott Liu <liuwenliang@huawei.com>

4. Change kasan_pte_populate,kasan_pmd_populate,kasan_pud_populate,
   kasan_pgd_populate from .meminit.text section to .init.text section.
           ---Reported by: Florian Fainelli <f.fainelli@gmail.com>
           ---Signed off by: Abbott Liu <liuwenliang@huawei.com>

Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Co-Developed-by: Abbott Liu <liuwenliang@huawei.com>
Reported-by: Russell King - ARM Linux <linux@armlinux.org.uk>
Reported-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Abbott Liu <liuwenliang@huawei.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Use SPDX identifer for the license.
- Move the TTBR0 accessor calls into this patch.
---
 arch/arm/include/asm/kasan.h       |  32 +++
 arch/arm/include/asm/pgalloc.h     |   9 +-
 arch/arm/include/asm/thread_info.h |   4 +
 arch/arm/kernel/head-common.S      |   3 +
 arch/arm/kernel/setup.c            |   2 +
 arch/arm/mm/Makefile               |   3 +
 arch/arm/mm/kasan_init.c           | 324 +++++++++++++++++++++++++++++
 arch/arm/mm/pgd.c                  |  14 ++
 8 files changed, 389 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/include/asm/kasan.h
 create mode 100644 arch/arm/mm/kasan_init.c

diff --git a/arch/arm/include/asm/kasan.h b/arch/arm/include/asm/kasan.h
new file mode 100644
index 000000000000..56b954db160e
--- /dev/null
+++ b/arch/arm/include/asm/kasan.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/include/asm/kasan.h
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+ *
+ */
+
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifdef CONFIG_KASAN
+
+#include <asm/kasan_def.h>
+
+#define KASAN_SHADOW_SCALE_SHIFT 3
+
+/*
+ * The compiler uses a shadow offset assuming that addresses start
+ * from 0. Kernel addresses don't start from 0, so shadow
+ * for kernel really starts from 'compiler's shadow offset' +
+ * ('kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT)
+ */
+
+extern void kasan_init(void);
+
+#else
+static inline void kasan_init(void) { }
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 069da393110c..d969f8058b26 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -21,6 +21,7 @@
 #define _PAGE_KERNEL_TABLE	(PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
 
 #ifdef CONFIG_ARM_LPAE
+#define PGD_SIZE		(PTRS_PER_PGD * sizeof(pgd_t))
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
@@ -39,14 +40,18 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 }
 
 #else	/* !CONFIG_ARM_LPAE */
+#define PGD_SIZE		(PAGE_SIZE << 2)
 
 /*
  * Since we have only two-level page tables, these are trivial
  */
 #define pmd_alloc_one(mm,addr)		({ BUG(); ((pmd_t *)2); })
 #define pmd_free(mm, pmd)		do { } while (0)
-#define pud_populate(mm,pmd,pte)	BUG()
-
+#ifndef CONFIG_KASAN
+#define pud_populate(mm, pmd, pte)	BUG()
+#else
+#define pud_populate(mm, pmd, pte)	do { } while (0)
+#endif
 #endif	/* CONFIG_ARM_LPAE */
 
 extern pgd_t *pgd_alloc(struct mm_struct *mm);
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 3609a6980c34..cf47cf9c4742 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -13,7 +13,11 @@
 #include <asm/fpstate.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_KASAN
+#define THREAD_SIZE_ORDER	2
+#else
 #define THREAD_SIZE_ORDER	1
+#endif
 #define THREAD_SIZE		(PAGE_SIZE << THREAD_SIZE_ORDER)
 #define THREAD_START_SP		(THREAD_SIZE - 8)
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 6840c7c60a85..89c80154b9ef 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -111,6 +111,9 @@ __mmap_switched:
 	str	r8, [r2]			@ Save atags pointer
 	cmp	r3, #0
 	strne	r10, [r3]			@ Save control register values
+#ifdef CONFIG_KASAN
+	bl	kasan_early_init
+#endif
 	mov	lr, #0
 	b	start_kernel
 ENDPROC(__mmap_switched)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d8e18cdd96d3..b0820847bb92 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -58,6 +58,7 @@
 #include <asm/unwind.h>
 #include <asm/memblock.h>
 #include <asm/virt.h>
+#include <asm/kasan.h>
 
 #include "atags.h"
 
@@ -1130,6 +1131,7 @@ void __init setup_arch(char **cmdline_p)
 	early_ioremap_reset();
 
 	paging_init(mdesc);
+	kasan_init();
 	request_standard_resources(mdesc);
 
 	if (mdesc->restart)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 432302911d6e..1c937135c9c4 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -112,3 +112,6 @@ obj-$(CONFIG_CACHE_L2X0_PMU)	+= cache-l2x0-pmu.o
 obj-$(CONFIG_CACHE_XSC3L2)	+= cache-xsc3l2.o
 obj-$(CONFIG_CACHE_TAUROS2)	+= cache-tauros2.o
 obj-$(CONFIG_CACHE_UNIPHIER)	+= cache-uniphier.o
+
+KASAN_SANITIZE_kasan_init.o    := n
+obj-$(CONFIG_KASAN)            += kasan_init.o
diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c
new file mode 100644
index 000000000000..b4a18863c29f
--- /dev/null
+++ b/arch/arm/mm/kasan_init.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file contains kasan initialization code for ARM.
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+ */
+
+#define pr_fmt(fmt) "kasan: " fmt
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/sched/task.h>
+#include <linux/start_kernel.h>
+#include <asm/cputype.h>
+#include <asm/highmem.h>
+#include <asm/mach/map.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/procinfo.h>
+#include <asm/proc-fns.h>
+#include <asm/tlbflush.h>
+#include <asm/cp15.h>
+
+#include "mm.h"
+
+static pgd_t tmp_pgd_table[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+
+pmd_t tmp_pmd_table[PTRS_PER_PMD] __page_aligned_bss;
+
+static __init void *kasan_alloc_block(size_t size, int node)
+{
+	return memblock_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS),
+				      MEMBLOCK_ALLOC_KASAN, node);
+}
+
+static void __init kasan_early_pmd_populate(unsigned long start,
+					unsigned long end, pud_t *pud)
+{
+	unsigned long addr;
+	unsigned long next;
+	pmd_t *pmd;
+
+	pmd = pmd_offset(pud, start);
+	for (addr = start; addr < end;) {
+		pmd_populate_kernel(&init_mm, pmd, kasan_early_shadow_pte);
+		next = pmd_addr_end(addr, end);
+		addr = next;
+		flush_pmd_entry(pmd);
+		pmd++;
+	}
+}
+
+static void __init kasan_early_pud_populate(unsigned long start,
+				unsigned long end, pgd_t *pgd)
+{
+	unsigned long addr;
+	unsigned long next;
+	pud_t *pud;
+
+	pud = pud_offset(pgd, start);
+	for (addr = start; addr < end;) {
+		next = pud_addr_end(addr, end);
+		kasan_early_pmd_populate(addr, next, pud);
+		addr = next;
+		pud++;
+	}
+}
+
+void __init kasan_map_early_shadow(pgd_t *pgdp)
+{
+	int i;
+	unsigned long start = KASAN_SHADOW_START;
+	unsigned long end = KASAN_SHADOW_END;
+	unsigned long addr;
+	unsigned long next;
+	pgd_t *pgd;
+
+	for (i = 0; i < PTRS_PER_PTE; i++)
+		set_pte_at(&init_mm, KASAN_SHADOW_START + i*PAGE_SIZE,
+			&kasan_early_shadow_pte[i], pfn_pte(
+				virt_to_pfn(kasan_early_shadow_page),
+				__pgprot(_L_PTE_DEFAULT | L_PTE_DIRTY
+					| L_PTE_XN)));
+
+	pgd = pgd_offset_k(start);
+	for (addr = start; addr < end;) {
+		next = pgd_addr_end(addr, end);
+		kasan_early_pud_populate(addr, next, pgd);
+		addr = next;
+		pgd++;
+	}
+}
+
+extern struct proc_info_list *lookup_processor_type(unsigned int);
+
+void __init kasan_early_init(void)
+{
+	struct proc_info_list *list;
+
+	/*
+	 * locate processor in the list of supported processor
+	 * types.  The linker builds this table for us from the
+	 * entries in arch/arm/mm/proc-*.S
+	 */
+	list = lookup_processor_type(read_cpuid_id());
+	if (list) {
+#ifdef MULTI_CPU
+		processor = *list->proc;
+#endif
+	}
+
+	BUILD_BUG_ON((KASAN_SHADOW_END - (1UL << 29)) != KASAN_SHADOW_OFFSET);
+	kasan_map_early_shadow(swapper_pg_dir);
+}
+
+static void __init clear_pgds(unsigned long start,
+			unsigned long end)
+{
+	for (; start && start < end; start += PMD_SIZE)
+		pmd_clear(pmd_off_k(start));
+}
+
+pte_t * __init kasan_pte_populate(pmd_t *pmd, unsigned long addr, int node)
+{
+	pte_t *pte = pte_offset_kernel(pmd, addr);
+
+	if (pte_none(*pte)) {
+		pte_t entry;
+		void *p = kasan_alloc_block(PAGE_SIZE, node);
+
+		if (!p)
+			return NULL;
+		entry = pfn_pte(virt_to_pfn(p),
+			__pgprot(pgprot_val(PAGE_KERNEL)));
+		set_pte_at(&init_mm, addr, pte, entry);
+	}
+	return pte;
+}
+
+pmd_t * __init kasan_pmd_populate(pud_t *pud, unsigned long addr, int node)
+{
+	pmd_t *pmd = pmd_offset(pud, addr);
+
+	if (pmd_none(*pmd)) {
+		void *p = kasan_alloc_block(PAGE_SIZE, node);
+
+		if (!p)
+			return NULL;
+		pmd_populate_kernel(&init_mm, pmd, p);
+	}
+	return pmd;
+}
+
+pud_t * __init kasan_pud_populate(pgd_t *pgd, unsigned long addr, int node)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+
+	if (pud_none(*pud)) {
+		void *p = kasan_alloc_block(PAGE_SIZE, node);
+
+		if (!p)
+			return NULL;
+		pr_err("populating pud addr %lx\n", addr);
+		pud_populate(&init_mm, pud, p);
+	}
+	return pud;
+}
+
+pgd_t * __init kasan_pgd_populate(unsigned long addr, int node)
+{
+	pgd_t *pgd = pgd_offset_k(addr);
+
+	if (pgd_none(*pgd)) {
+		void *p = kasan_alloc_block(PAGE_SIZE, node);
+
+		if (!p)
+			return NULL;
+		pgd_populate(&init_mm, pgd, p);
+	}
+	return pgd;
+}
+
+static int __init create_mapping(unsigned long start, unsigned long end,
+				int node)
+{
+	unsigned long addr = start;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	pr_info("populating shadow for %lx, %lx\n", start, end);
+
+	for (; addr < end; addr += PAGE_SIZE) {
+		pgd = kasan_pgd_populate(addr, node);
+		if (!pgd)
+			return -ENOMEM;
+
+		pud = kasan_pud_populate(pgd, addr, node);
+		if (!pud)
+			return -ENOMEM;
+
+		pmd = kasan_pmd_populate(pud, addr, node);
+		if (!pmd)
+			return -ENOMEM;
+
+		pte = kasan_pte_populate(pmd, addr, node);
+		if (!pte)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+/*
+ * TTBR0 accessors
+ *
+ * FIXME: this TTBR0 direct-manipulation does not seem to be the
+ * right solution at all: we need something that works on ALL ARM
+ * CPUs not just recent ones with TTBR0/1.
+ */
+#define TTBR0_32	__ACCESS_CP15(c2, 0, c0, 0)
+#define TTBR0_64	__ACCESS_CP15_64(0, c2)
+
+static inline void set_ttbr0(u64 val)
+{
+	if (IS_ENABLED(CONFIG_ARM_LPAE))
+		write_sysreg(val, TTBR0_64);
+	else
+		write_sysreg(val, TTBR0_32);
+}
+
+static inline u64 get_ttbr0(void)
+{
+	if (IS_ENABLED(CONFIG_ARM_LPAE))
+		return read_sysreg(TTBR0_64);
+	else
+		return read_sysreg(TTBR0_32);
+}
+
+void __init kasan_init(void)
+{
+	struct memblock_region *reg;
+	u64 orig_ttbr0;
+	int i;
+
+	/*
+	 * 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_pgd_table and tmp_pmd_table used to keep early shadow mapped
+	 * until full shadow setup will be finished.
+	 */
+	orig_ttbr0 = get_ttbr0();
+
+#ifdef CONFIG_ARM_LPAE
+	memcpy(tmp_pmd_table,
+		pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)),
+		sizeof(tmp_pmd_table));
+	memcpy(tmp_pgd_table, swapper_pg_dir, sizeof(tmp_pgd_table));
+	set_pgd(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)],
+		__pgd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
+	set_ttbr0(__pa(tmp_pgd_table));
+#else
+	memcpy(tmp_pgd_table, swapper_pg_dir, sizeof(tmp_pgd_table));
+	set_ttbr0((u64)__pa(tmp_pgd_table));
+#endif
+	flush_cache_all();
+	local_flush_bp_all();
+	local_flush_tlb_all();
+
+	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+
+	kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START),
+				    kasan_mem_to_shadow((void *)-1UL) + 1);
+
+	for_each_memblock(memory, reg) {
+		void *start = __va(reg->base);
+		void *end = __va(reg->base + reg->size);
+
+		if (reg->base + reg->size > arm_lowmem_limit)
+			end = __va(arm_lowmem_limit);
+		if (start >= end)
+			break;
+
+		create_mapping((unsigned long)kasan_mem_to_shadow(start),
+			(unsigned long)kasan_mem_to_shadow(end),
+			NUMA_NO_NODE);
+	}
+
+	/*
+	 * 1. The module global variables are in MODULES_VADDR ~ MODULES_END,
+	 *    so we need to map this area.
+	 * 2. PKMAP_BASE ~ PKMAP_BASE+PMD_SIZE's shadow and MODULES_VADDR
+	 *    ~ MODULES_END's shadow is in the same PMD_SIZE, so we can't
+	 *    use kasan_populate_zero_shadow.
+	 */
+	create_mapping(
+		(unsigned long)kasan_mem_to_shadow((void *)MODULES_VADDR),
+
+		(unsigned long)kasan_mem_to_shadow((void *)(PKMAP_BASE +
+							PMD_SIZE)),
+		NUMA_NO_NODE);
+
+	/*
+	 * KAsan may reuse the contents of kasan_early_shadow_pte directly, so
+	 * we should make sure that it maps the zero page read-only.
+	 */
+	for (i = 0; i < PTRS_PER_PTE; i++)
+		set_pte_at(&init_mm, KASAN_SHADOW_START + i*PAGE_SIZE,
+			&kasan_early_shadow_pte[i],
+			pfn_pte(virt_to_pfn(kasan_early_shadow_page),
+				__pgprot(pgprot_val(PAGE_KERNEL)
+					| L_PTE_RDONLY)));
+	memset(kasan_early_shadow_page, 0, PAGE_SIZE);
+	set_ttbr0(orig_ttbr0);
+	flush_cache_all();
+	local_flush_bp_all();
+	local_flush_tlb_all();
+	pr_info("Kernel address sanitizer initialized\n");
+	init_task.kasan_depth = 0;
+}
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 478bd2c6aa50..92a408262df2 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -61,6 +61,20 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 	new_pmd = pmd_alloc(mm, new_pud, 0);
 	if (!new_pmd)
 		goto no_pmd;
+#ifdef CONFIG_KASAN
+	/*
+	 *Copy PMD table for KASAN shadow mappings.
+	 */
+	init_pgd = pgd_offset_k(TASK_SIZE);
+	init_pud = pud_offset(init_pgd, TASK_SIZE);
+	init_pmd = pmd_offset(init_pud, TASK_SIZE);
+	new_pmd = pmd_offset(new_pud, TASK_SIZE);
+	memcpy(new_pmd, init_pmd,
+		(pmd_index(MODULES_VADDR)-pmd_index(TASK_SIZE))
+		* sizeof(pmd_t));
+	clean_dcache_area(new_pmd, PTRS_PER_PMD*sizeof(pmd_t));
+#endif
+
 #endif
 
 	if (!vectors_high()) {
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 5/5 v2] ARM: Enable KASan for ARM
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
                   ` (3 preceding siblings ...)
  2020-04-12  0:24 ` [PATCH 4/5 v2] ARM: Initialize the mapping of KASan shadow memory Linus Walleij
@ 2020-04-12  0:24 ` Linus Walleij
  2020-06-01  4:00 ` [PATCH 0/5 v2] " Florian Fainelli
  5 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2020-04-12  0:24 UTC (permalink / raw)
  To: Florian Fainelli, Abbott Liu, Russell King, Ard Biesheuvel,
	Andrey Ryabinin
  Cc: Dmitry Vyukov, Linus Walleij, Andrey Ryabinin, linux-arm-kernel

From: Andrey Ryabinin <ryabinin@virtuozzo.com>

This patch enables the kernel address sanitizer for ARM. XIP_KERNEL
has not been tested and is therefore not allowed for now.

Acked-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Abbott Liu <liuwenliang@huawei.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Moved the hacks to __ADDRESS_SANITIZE__ to the patch
  replacing the memory access functions.
- Moved the definition of KASAN_OFFSET out of this patch
  and to the patch that defines the virtual memory used by
  KASan.
---
 Documentation/dev-tools/kasan.rst | 4 ++--
 arch/arm/Kconfig                  | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
index c652d740735d..0962365e1405 100644
--- a/Documentation/dev-tools/kasan.rst
+++ b/Documentation/dev-tools/kasan.rst
@@ -21,8 +21,8 @@ global variables yet.
 
 Tag-based KASAN is only supported in Clang and requires version 7.0.0 or later.
 
-Currently generic KASAN is supported for the x86_64, arm64, xtensa, s390 and
-riscv architectures, and tag-based KASAN is supported only for arm64.
+Currently generic KASAN is supported for the x86_64, arm, arm64, xtensa, s390
+and riscv architectures, and tag-based KASAN is supported only for arm64.
 
 Usage
 -----
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f6f2d3b202f5..f5d26cbe2f42 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -64,6 +64,7 @@ config ARM
 	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
 	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
+	select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
 	select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT
 	select HAVE_ARCH_THREAD_STRUCT_WHITELIST
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
                   ` (4 preceding siblings ...)
  2020-04-12  0:24 ` [PATCH 5/5 v2] ARM: Enable KASan for ARM Linus Walleij
@ 2020-06-01  4:00 ` Florian Fainelli
  2020-06-01  8:55   ` Linus Walleij
  5 siblings, 1 reply; 16+ messages in thread
From: Florian Fainelli @ 2020-06-01  4:00 UTC (permalink / raw)
  To: Linus Walleij, Abbott Liu, Russell King, Ard Biesheuvel, Andrey Ryabinin
  Cc: linux-arm-kernel

Hi Linus,

On 4/11/2020 5:24 PM, Linus Walleij wrote:
> I am trying to pick up this series.
> 
> I rebased it on what is soon v5.7-rc1 and fixed some bug
> or two (see individual ChangeLog on the patches).
> 
> The main thing I need to fix here is the usage of TTBR0
> in patch 4. This isn't working for machines without
> TTBR0 obviously. I need help with the right approach
> here.
> 
> I want to support all ARM CPUs that we support with the
> kernel and it is not far off: I tried it in Faraday's
> FA526 and it mostly works until we reach userspace
> and my guess is that that is because of the TTBR0
> shortcut it is taking.
> 
> What is interesting is that if I compile in the KASan
> test module into the kernel, it performs most of the
> tests correctly even on this old platform, so we only
> have a few things to fix.

Since this patch series has had many people trying to push it forward,
how about we try to get it merged as-is (minus bugs, see below) with the
caveat that TTRB0-less CPUs are not going to be supported for now and
later on, this gets lifted if we find a champion who can get that working?

I tested this on an ARMv8 system (Brahma-B53 CPU) and an ARMv7-A system
(Brahma-B15 CPU) with and without ARM_LPAE enabled and neither were able
to boot unless KASAN was turned off (outline instrumentation), I don't
even get to the point where earlyprintk is giving me anything which is
odd. Have not looked at the differences between this version and the one
I had sent before and have not hooked a debugger to find out where we
are hung.

If you have a Raspberry Pi 4 you could use it as a test system for ARM_LPAE.

Thanks!
-- 
Florian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-01  4:00 ` [PATCH 0/5 v2] " Florian Fainelli
@ 2020-06-01  8:55   ` Linus Walleij
  2020-06-01 16:36     ` Florian Fainelli
  0 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2020-06-01  8:55 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Abbott Liu, Andrey Ryabinin, Russell King, Linux ARM, Ard Biesheuvel

On Mon, Jun 1, 2020 at 6:00 AM Florian Fainelli <f.fainelli@gmail.com> wrote:

> Since this patch series has had many people trying to push it forward,
> how about we try to get it merged as-is (minus bugs, see below) with the
> caveat that TTRB0-less CPUs are not going to be supported for now and
> later on, this gets lifted if we find a champion who can get that working?

Oh I fixed most issues in the v9 patch set, we ironed out the actual problem
with ARMv4 and ARMv5 with some help from Ard, Catalin and then Russell
suggested how to also improve the way we get taskinfo from sp in the
assembly.

> I tested this on an ARMv8 system (Brahma-B53 CPU) and an ARMv7-A system
> (Brahma-B15 CPU) with and without ARM_LPAE enabled and neither were able
> to boot unless KASAN was turned off (outline instrumentation), I don't
> even get to the point where earlyprintk is giving me anything which is
> odd. Have not looked at the differences between this version and the one
> I had sent before and have not hooked a debugger to find out where we
> are hung.
>
> If you have a Raspberry Pi 4 you could use it as a test system for ARM_LPAE.

Did you try to use the v9 patch set on top of v5.7:
https://lore.kernel.org/linux-arm-kernel/20200515114028.135674-1-linus.walleij@linaro.org/

I need to rebase this on v5.8-rc1 once it is out but it is working on all my
targets now, there is also this git branch:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=kasan

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-01  8:55   ` Linus Walleij
@ 2020-06-01 16:36     ` Florian Fainelli
  2020-06-01 16:40       ` Ard Biesheuvel
  2020-06-03  8:45       ` Linus Walleij
  0 siblings, 2 replies; 16+ messages in thread
From: Florian Fainelli @ 2020-06-01 16:36 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Abbott Liu, Andrey Ryabinin, Russell King, Linux ARM, Ard Biesheuvel

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]



On 6/1/2020 1:55 AM, Linus Walleij wrote:
> On Mon, Jun 1, 2020 at 6:00 AM Florian Fainelli <f.fainelli@gmail.com> wrote:
> 
>> Since this patch series has had many people trying to push it forward,
>> how about we try to get it merged as-is (minus bugs, see below) with the
>> caveat that TTRB0-less CPUs are not going to be supported for now and
>> later on, this gets lifted if we find a champion who can get that working?
> 
> Oh I fixed most issues in the v9 patch set, we ironed out the actual problem
> with ARMv4 and ARMv5 with some help from Ard, Catalin and then Russell
> suggested how to also improve the way we get taskinfo from sp in the
> assembly.
> 
>> I tested this on an ARMv8 system (Brahma-B53 CPU) and an ARMv7-A system
>> (Brahma-B15 CPU) with and without ARM_LPAE enabled and neither were able
>> to boot unless KASAN was turned off (outline instrumentation), I don't
>> even get to the point where earlyprintk is giving me anything which is
>> odd. Have not looked at the differences between this version and the one
>> I had sent before and have not hooked a debugger to find out where we
>> are hung.
>>
>> If you have a Raspberry Pi 4 you could use it as a test system for ARM_LPAE.
> 
> Did you try to use the v9 patch set on top of v5.7:
> https://lore.kernel.org/linux-arm-kernel/20200515114028.135674-1-linus.walleij@linaro.org/
> 
> I need to rebase this on v5.8-rc1 once it is out but it is working on all my
> targets now, there is also this git branch:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=kasan

This branch got me a bit further, but still failed to fully initialize
(see attached kasan.log), on another platform with a slightly different
memory map, I ended up getting a different error (kasan2.log).
-- 
Florian

[-- Attachment #2: kasan.log --]
[-- Type: text/plain, Size: 6769 bytes --]

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.7.0-rc1-g17b3e5f7b19c (fainelli@fainelli-desktop) (gcc version 6.3.0 (crosstool-NG ), GNU ld (crosstool-NG )
2.26.20160125) #10 SMP Mon Jun 1 09:26:43 PDT 2020
[    0.000000] CPU: ARMv7 Processor [420f00f3] revision 3 (ARMv7), cr=30c5387d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[    0.000000] OF: fdt: Machine model: BCM97445VMS
[    0.000000] printk: bootconsole [earlycon0] enabled
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] cma: Reserved 16 MiB at 0x00000000bec00000
[    0.000000] kasan: populating shadow for b7000000, bd000000
[    0.000000] 8<--- cut here ---
[    0.000000] Unable to handle kernel paging request at virtual address bcbffe00
[    0.000000] pgd = (ptrval)
[    0.000000] [bcbffe00] *pgd=80000000006003, *pmd=00000000
[    0.000000] Internal error: Oops: 206 [#1] SMP ARM
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-rc1-g17b3e5f7b19c #10
[    0.000000] Hardware name: Broadcom STB (Flattened Device Tree)
[    0.000000] PC is at check_memory_region+0xb0/0x1bc
[    0.000000] LR is at 0x40
[    0.000000] pc : [<c044b060>]    lr : [<00000040>]    psr: 000000d3
[    0.000000] sp : c2803c58  ip : bcbffe00  fp : c2803c84
[    0.000000] r10: c16b5000  r9 : 00000000  r8 : bcc00000
[    0.000000] r7 : 00000000  r6 : 00000200  r5 : bcbfffff  r4 : edffffff
[    0.000000] r3 : c181cf10  r2 : 00000001  r1 : 00001000  r0 : edfff000
[    0.000000] Flags: nzcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment user
[    0.000000] Control: 30c5387d  Table: 018731e0  DAC: fffffffd
[    0.000000] Process swapper (pid: 0, stack limit = 0x(ptrval))
[    0.000000] Stack: (0xc2803c58 to 0xc2804000)
[    0.000000] 3c40:                                                       c181cf10 00001000
[    0.000000] 3c60: edfff000 00000000 00000000 00000001 00000000 c16b5000 c2803ca4 c2803c88
[    0.000000] 3c80: c0448ca8 c044afbc 00001000 00000000 edfff000 00000000 c2803ce4 c2803ca8
[    0.000000] 3ca0: c181cf10 c0448c8c 3fffffff 00000000 00000001 00000000 ffffffff 00000000
[    0.000000] 3cc0: 00000001 00000000 ffffffff ffffffff b71f6000 00000018 c2803d1c c2803ce8
[    0.000000] 3ce0: c180d578 c181ce68 3fffffff 00000000 00000001 00000000 ffffffff c180d7c0
[    0.000000] 3d00: ee1f6fb0 00000000 fffff000 00000000 c2803d4c c2803d20 c180d768 c180d508
[    0.000000] 3d20: 2e00071f c180d924 b71f6000 c2899de0 bd000000 00000000 c18730d8 00000018
[    0.000000] 3d40: c2803d6c c2803d50 c180d94c c180d724 c289a040 c2b51460 30000000 00000000
[    0.000000] 3d60: c2803dc4 c2803d70 c180db60 c180d8cc 02800000 00000000 c2b284c0 00000000
[    0.000000] 3d80: 0000001c ffff1000 0002ffff 00001000 30000000 00000000 30000000 c2f8c740
[    0.000000] 3da0: c0008000 c1870a44 c2899de0 e12fff1e c2803f40 c185e7a8 c2803ee4 c2803dc8
[    0.000000] 3dc0: c1805b48 c180d99c 0000006c 30c5387d 00000000 00000000 c1200740 c2803edc
[    0.000000] 3de0: c0226508 30c5387d 00000024 c2803df8 185007c0 c2803ea0 c1200740 c2803edc
[    0.000000] 3e00: 41b58ab3 c1641aa4 c1805368 c02b2060 c02b2c50 c02b3508 00000000 b75007cc
[    0.000000] 3e20: c2800000 30c0387d c2800000 c2806d40 c2803ed4 c2803e40 c02b2c50 c02b3508
[    0.000000] 3e40: c2803eb4 00000000 c2803e74 c2803e58 c2803e74 c2803e60 c0297cc0 c044ab08
[    0.000000] 3e60: 41b58ab3 c1643fe0 c02b2bbc c2803e78 c031c8ec c044ab08 00000000 c285fad8
[    0.000000] 3e80: c2803edc c0449634 c2803eb4 c2803e98 c0449634 c044a3c8 c2b4bf80 c2b4d680
[    0.000000] 3ea0: 00000000 c2800000 c2803ec4 c2803eb8 c044ab68 00000000 c2803ee4 b75007e4
[    0.000000] 3ec0: c2803fc0 30c0387d c2800000 c2806d40 420f00f3 30c5387d c2803ff4 c2803ee8
[    0.000000] 3ee0: c1800d3c c1805374 00000000 00000000 00000000 00000000 00000000 00000000
[    0.000000] 3f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.000000] 3f20: 41b58ab3 c1640b9c c1800c64 00000000 00000000 00000000 00000000 00000000
[    0.000000] 3f40: c1870a44 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.000000] 3f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c180d618
[    0.000000] 3f80: 00001000 00002b24 02b24403 00c00000 c2803fe4 c2803fa0 c180d684 c02281a8
[    0.000000] 3fa0: 02b24403 00c00000 00000000 00000000 c280a284 c2899de0 00000000 c1800334
[    0.000000] 3fc0: 00000000 00000000 ffffffff c1800334 00000000 30c0387d ffffffff 07723000
[    0.000000] 3fe0: 420f00f3 30c5387d 00000000 c2803ff8 00000000 c1800c70 00000000 00000000
[    0.000000] Backtrace:
[    0.000000] [<c044afb0>] (check_memory_region) from [<c0448ca8>] (memset+0x28/0x44)
[    0.000000]  r10:c16b5000 r9:00000000 r8:00000001 r7:00000000 r6:00000000 r5:edfff000
[    0.000000]  r4:00001000 r3:c181cf10
[    0.000000] [<c0448c80>] (memset) from [<c181cf10>] (memblock_alloc_try_nid+0xb4/0xc4)
[    0.000000]  r7:00000000 r6:edfff000 r5:00000000 r4:00001000
[    0.000000] [<c181ce5c>] (memblock_alloc_try_nid) from [<c180d578>] (kasan_alloc_block.constprop.7+0x7c/0x84)
[    0.000000]  r9:00000018 r8:b71f6000 r7:ffffffff r6:ffffffff r5:00000000 r4:00000001
[    0.000000] [<c180d4fc>] (kasan_alloc_block.constprop.7) from [<c180d768>] (kasan_pte_populate+0x50/0xb4)
[    0.000000]  r7:00000000 r6:fffff000 r5:00000000 r4:ee1f6fb0
[    0.000000] [<c180d718>] (kasan_pte_populate) from [<c180d94c>] (create_mapping.constprop.1+0x8c/0xa4)
[    0.000000]  r9:00000018 r8:c18730d8 r7:00000000 r6:bd000000 r5:c2899de0 r4:b71f6000
[    0.000000] [<c180d8c0>] (create_mapping.constprop.1) from [<c180db60>] (kasan_init+0x1d0/0x2f0)
[    0.000000]  r7:00000000 r6:30000000 r5:c2b51460 r4:c289a040
[    0.000000] [<c180d990>] (kasan_init) from [<c1805b48>] (setup_arch+0x7e0/0xfb0)
[    0.000000]  r10:c185e7a8 r9:c2803f40 r8:e12fff1e r7:c2899de0 r6:c1870a44 r5:c0008000
[    0.000000]  r4:c2f8c740
[    0.000000] [<c1805368>] (setup_arch) from [<c1800d3c>] (start_kernel+0xd8/0x5d8)
[    0.000000]  r10:30c5387d r9:420f00f3 r8:c2806d40 r7:c2800000 r6:30c0387d r5:c2803fc0
[    0.000000]  r4:b75007e4
[    0.000000] [<c1800c64>] (start_kernel) from [<00000000>] (0x0)
[    0.000000]  r10:30c5387d r9:420f00f3 r8:07723000 r7:ffffffff r6:30c0387d r5:00000000
[    0.000000]  r4:c1800334
[    0.000000] Code: e286e007 a1a0e006 e1b0e1ce 0a00002d (e1cc60d0)
[    0.000000] random: get_random_bytes called from print_oops_end_marker+0x48/0x58 with crng_init=0
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

[-- Attachment #3: kasan2.log --]
[-- Type: text/plain, Size: 5162 bytes --]

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.7.0-rc1-g17b3e5f7b19c (fainelli@fainelli-desktop) (gcc version 6.3.0 (crosstool-NG ), GNU ld (crosstool-NG )
2.26.20160125) #10 SMP Mon Jun 1 09:26:43 PDT 2020
[    0.000000] CPU: ARMv7 Processor [420f1000] revision 0 (ARMv7), cr=30c5383d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: BCX972160DV
[    0.000000] printk: bootconsole [earlycon0] enabled
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] cma: Reserved 16 MiB at 0x00000000fcc00000
[    0.000000] kasan: populating shadow for b7000000, bd000000
[    0.000000] kasan: populating shadow for af000000, bd000000
[    0.000000] kasan: populating shadow for b6e00000, b7000000
[    0.000000] kasan: Kernel address sanitizer initialized
[    0.000000] ==================================================================
[    0.000000] BUG: KASAN: stack-out-of-bounds in unflatten_dt_nodes+0x5f8/0x75c
[    0.000000] Write of size 6 at addr df783afc by task swapper/0
[    0.000000]
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-rc1-g17b3e5f7b19c #10
[    0.000000] Hardware name: Broadcom STB (Flattened Device Tree)
[    0.000000] Backtrace:
[    0.000000] [<c0210d68>] (dump_backtrace) from [<c0211130>] (show_stack+0x20/0x24)
[    0.000000]  r7:c2977560 r6:00000000 r5:400000d3 r4:c2977560
[    0.000000] [<c0211110>] (show_stack) from [<c086ec70>] (dump_stack+0xc0/0xf0)
[    0.000000] [<c086ebb0>] (dump_stack) from [<c0449efc>] (print_address_description.constprop.2+0x78/0x4d4)
[    0.000000]  r10:c2803d40 r9:df7839b8 r8:00000001 r7:c0d58280 r6:edce2c78 r5:c2800000
[    0.000000]  r4:df783afc r3:edce2c80
[    0.000000] [<c0449e84>] (print_address_description.constprop.2) from [<c044a5fc>] (__kasan_report+0x124/0x158)
[    0.000000]  r8:00000001 r7:c0d58280 r6:00000000 r5:c2800000 r4:df783afc
[    0.000000] [<c044a4d8>] (__kasan_report) from [<c0449650>] (kasan_report+0x3c/0x44)
[    0.000000]  r8:baef0761 r7:c0d58280 r6:00000001 r5:00000006 r4:df783afc
[    0.000000] [<c0449614>] (kasan_report) from [<c044b0cc>] (check_memory_region+0x11c/0x1bc)
[    0.000000]  r7:df783afc r6:baef075f r5:baef0760 r4:df783b01
[    0.000000] [<c044afb0>] (check_memory_region) from [<c0448d80>] (memcpy+0x4c/0x70)
[    0.000000]  r10:c2803d40 r9:df7839b8 r8:c761e000 r7:df783afc r6:c7622030 r5:c0d58280
[    0.000000]  r4:00000006 r3:c0d58280
[    0.000000] [<c0448d34>] (memcpy) from [<c0d58280>] (unflatten_dt_nodes+0x5f8/0x75c)
[    0.000000]  r7:df783ab0 r6:df783ad0 r5:00000006 r4:c7622030
[    0.000000] [<c0d57c88>] (unflatten_dt_nodes) from [<c0d5851c>] (__unflatten_device_tree+0x118/0x398)
[    0.000000]  r10:00000000 r9:c2f81cc0 r8:df786ffc r7:df77976c r6:c761e000 r5:0000d890
[    0.000000]  r4:c2b1af70
[    0.000000] [<c0d58404>] (__unflatten_device_tree) from [<c1836a0c>] (unflatten_device_tree+0x44/0x54)
[    0.000000]  r10:c185e7a8 r9:00000000 r8:42800000 r7:c2b51490 r6:efffcd00 r5:00000000
[    0.000000]  r4:c1834efc
[    0.000000] [<c18369c8>] (unflatten_device_tree) from [<c1805fa8>] (setup_arch+0xc40/0xfb0)
[    0.000000]  r4:c185e7d0
[    0.000000] [<c1805368>] (setup_arch) from [<c1800d3c>] (start_kernel+0xd8/0x5d8)
[    0.000000]  r10:30c5387d r9:420f1000 r8:c2806d40 r7:c2800000 r6:30c0387d r5:c2803fc0
[    0.000000]  r4:b75007e4
[    0.000000] [<c1800c64>] (start_kernel) from [<00000000>] (0x0)
[    0.000000]  r10:30c5387d r9:420f1000 r8:4761e000 r7:ffffffff r6:30c0387d r5:00000000
[    0.000000]  r4:c1800334
[    0.000000]
[    0.000000] The buggy address belongs to the page:
[    0.000000] page:edce2c78 refcount:1 mapcount:0 mapping:(ptrval) index:0x0
[    0.000000] flags: 0x0()
[    0.000000] raw: 00000000 00000000 edce2c80 edce2c80 00000000 00000000 00000000 00000000
[    0.000000] raw: ffffffff 00000001
[    0.000000] page dumped because: kasan: bad access detected
[    0.000000]
[    0.000000] Memory state around the buggy address:
[    0.000000]  df783980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]  df783a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000] >df783a80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
[    0.000000]                                                         ^
[    0.000000]  df783b00: 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2
[    0.000000]  df783b80: 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2
[    0.000000] ==================================================================
[    0.000000] Disabling lock debugging due to kernel taint
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS migration not required
[    0.000000] psci: SMC Calling Convention v1.1
[    0.000000] percpu: Embedded 20 pages/cpu s49292 r8192 d24436 u81920
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 1038463
[    0.000000] Kernel command line: earlyprintk


[-- Attachment #4: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-01 16:36     ` Florian Fainelli
@ 2020-06-01 16:40       ` Ard Biesheuvel
  2020-06-01 16:51         ` Florian Fainelli
  2020-06-03  8:45       ` Linus Walleij
  1 sibling, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2020-06-01 16:40 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Abbott Liu, Linus Walleij, Russell King, Linux ARM, Andrey Ryabinin

On Mon, 1 Jun 2020 at 18:37, Florian Fainelli <f.fainelli@gmail.com> wrote:
>
>
>
> On 6/1/2020 1:55 AM, Linus Walleij wrote:
> > On Mon, Jun 1, 2020 at 6:00 AM Florian Fainelli <f.fainelli@gmail.com> wrote:
> >
> >> Since this patch series has had many people trying to push it forward,
> >> how about we try to get it merged as-is (minus bugs, see below) with the
> >> caveat that TTRB0-less CPUs are not going to be supported for now and
> >> later on, this gets lifted if we find a champion who can get that working?
> >
> > Oh I fixed most issues in the v9 patch set, we ironed out the actual problem
> > with ARMv4 and ARMv5 with some help from Ard, Catalin and then Russell
> > suggested how to also improve the way we get taskinfo from sp in the
> > assembly.
> >
> >> I tested this on an ARMv8 system (Brahma-B53 CPU) and an ARMv7-A system
> >> (Brahma-B15 CPU) with and without ARM_LPAE enabled and neither were able
> >> to boot unless KASAN was turned off (outline instrumentation), I don't
> >> even get to the point where earlyprintk is giving me anything which is
> >> odd. Have not looked at the differences between this version and the one
> >> I had sent before and have not hooked a debugger to find out where we
> >> are hung.
> >>
> >> If you have a Raspberry Pi 4 you could use it as a test system for ARM_LPAE.
> >
> > Did you try to use the v9 patch set on top of v5.7:
> > https://lore.kernel.org/linux-arm-kernel/20200515114028.135674-1-linus.walleij@linaro.org/
> >
> > I need to rebase this on v5.8-rc1 once it is out but it is working on all my
> > targets now, there is also this git branch:
> > https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=kasan
>
> This branch got me a bit further, but still failed to fully initialize
> (see attached kasan.log), on another platform with a slightly different
> memory map, I ended up getting a different error (kasan2.log).

How can you be sure kasan2.log did not detect an actual bug?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-01 16:40       ` Ard Biesheuvel
@ 2020-06-01 16:51         ` Florian Fainelli
  0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2020-06-01 16:51 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Abbott Liu, Linus Walleij, Russell King, Linux ARM, Andrey Ryabinin



On 6/1/2020 9:40 AM, Ard Biesheuvel wrote:
> On Mon, 1 Jun 2020 at 18:37, Florian Fainelli <f.fainelli@gmail.com> wrote:
>>
>>
>>
>> On 6/1/2020 1:55 AM, Linus Walleij wrote:
>>> On Mon, Jun 1, 2020 at 6:00 AM Florian Fainelli <f.fainelli@gmail.com> wrote:
>>>
>>>> Since this patch series has had many people trying to push it forward,
>>>> how about we try to get it merged as-is (minus bugs, see below) with the
>>>> caveat that TTRB0-less CPUs are not going to be supported for now and
>>>> later on, this gets lifted if we find a champion who can get that working?
>>>
>>> Oh I fixed most issues in the v9 patch set, we ironed out the actual problem
>>> with ARMv4 and ARMv5 with some help from Ard, Catalin and then Russell
>>> suggested how to also improve the way we get taskinfo from sp in the
>>> assembly.
>>>
>>>> I tested this on an ARMv8 system (Brahma-B53 CPU) and an ARMv7-A system
>>>> (Brahma-B15 CPU) with and without ARM_LPAE enabled and neither were able
>>>> to boot unless KASAN was turned off (outline instrumentation), I don't
>>>> even get to the point where earlyprintk is giving me anything which is
>>>> odd. Have not looked at the differences between this version and the one
>>>> I had sent before and have not hooked a debugger to find out where we
>>>> are hung.
>>>>
>>>> If you have a Raspberry Pi 4 you could use it as a test system for ARM_LPAE.
>>>
>>> Did you try to use the v9 patch set on top of v5.7:
>>> https://lore.kernel.org/linux-arm-kernel/20200515114028.135674-1-linus.walleij@linaro.org/
>>>
>>> I need to rebase this on v5.8-rc1 once it is out but it is working on all my
>>> targets now, there is also this git branch:
>>> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=kasan
>>
>> This branch got me a bit further, but still failed to fully initialize
>> (see attached kasan.log), on another platform with a slightly different
>> memory map, I ended up getting a different error (kasan2.log).
> 
> How can you be sure kasan2.log did not detect an actual bug?

I should have been clearer, my email was just sent out unfiltered to
report the status on Linus' branch, kasan2.log may be showing up a
genuine bug indeed.
-- 
Florian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-01 16:36     ` Florian Fainelli
  2020-06-01 16:40       ` Ard Biesheuvel
@ 2020-06-03  8:45       ` Linus Walleij
  2020-06-04  9:24         ` Linus Walleij
  1 sibling, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2020-06-03  8:45 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Abbott Liu, Andrey Ryabinin, Russell King, Linux ARM, Ard Biesheuvel

On Mon, Jun 1, 2020 at 6:37 PM Florian Fainelli <f.fainelli@gmail.com> wrote:

> This branch got me a bit further,

Thanks, at least we get improvements. :)

> but still failed to fully initialize
> (see attached kasan.log), on another platform with a slightly different
> memory map, I ended up getting a different error (kasan2.log).

I have this error too on a Qualcomm board, it is what I report
in the cover letter, that if I load the kernel into 0x40200000
this happens but when I load it into 0x50000000 it does not
happen.

I think it is because the device tree unflatter reads from
non-kernel memory. The device tree can be placed pretty
much anywhere in physical memory, and if that physical
memory happens to end up to be inside kernel virtual
memory we are fine, and if not this happens. (This is
just my working hypothesis.)

I think the issue is a kind of bug since the kernel is
indeed accessing non-kernel memory, but on the
other hand it has to. So it has to be done under
controlled forms.

I tried to de-instrument the DT parser but that did not
help me, but possibly it is one part of the solution:

From f02ac4adf784cff9fa7b4780d5e7ff5f1c830165 Mon Sep 17 00:00:00 2001
From: Linus Walleij <linus.walleij@linaro.org>
Date: Tue, 12 May 2020 00:19:04 +0200
Subject: [PATCH] lib: fdt: De-instrumentize core FDT parser for KASan

When the architecture initialize and want to inspect the FDT
using this call sequence:

setup_arch()
  unflatten_device_tree()
    early_init_dt_alloc_memory_arch()
      fdt_check_header()

The KASan shadow memory is set up at this point, but
fdt_check_header() will reach out into non-kernel memory
not shadowed by KASan by just casting a pointer into virtual
memory into a ((const struct fdt_header *) by way of
fdt_get_header(). KASan will attempt to shadow these memory
accesses leading to a crash like this:

Unable to handle kernel paging request at virtual address b7600619
pgd = (ptrval)
[b7600619] *pgd=00000000c
Internal error: Oops: 5 [#1] PREEMPT SMP ARM
Modules linked in:c
CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-rc1-00009-g667a8ab4ee5e-dirty #29
Hardware name: Generic DT based system
PC is at __asan_load1+0x1c/0x48
LR is at fdt_check_header+0xc/0x2f4

Fix this by de-instrumenting fdt.c from libfdt.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 lib/Makefile | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/Makefile b/lib/Makefile
index 685aee60de1d..13ea92191788 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -236,6 +236,10 @@ libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o
fdt_sw.o fdt_strerror.o \
 $(foreach file, $(libfdt_files), \
  $(eval CFLAGS_$(file) = -I $(srctree)/scripts/dtc/libfdt))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
+# The early kernel setup will attempt to read properties from the FDT which
+# may very well be in some memory area that is not kernel memory, leading
+# to problems when KASan tries to shadow these memory accesses.
+KASAN_SANITIZE_fdt.o := n

 lib-$(CONFIG_BOOT_CONFIG) += bootconfig.o

-- 
2.25.4

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-03  8:45       ` Linus Walleij
@ 2020-06-04  9:24         ` Linus Walleij
  2020-06-04 11:26           ` Ard Biesheuvel
  0 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2020-06-04  9:24 UTC (permalink / raw)
  To: Florian Fainelli, Rob Herring
  Cc: Abbott Liu, Andrey Ryabinin, Russell King, Linux ARM, Ard Biesheuvel

On Wed, Jun 3, 2020 at 10:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Jun 1, 2020 at 6:37 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
>
> > This branch got me a bit further,
>
> Thanks, at least we get improvements. :)
>
> > but still failed to fully initialize
> > (see attached kasan.log), on another platform with a slightly different
> > memory map, I ended up getting a different error (kasan2.log).
>
> I have this error too on a Qualcomm board, it is what I report
> in the cover letter, that if I load the kernel into 0x40200000
> this happens but when I load it into 0x50000000 it does not
> happen.

So this is what happens to me, even after I try to de-instrument
the DT parsing code (maybe I do it all wrong...)
This is done with that patch:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/commit/?h=kasan-apq8060-test&id=1cd83357f3c35b037400f6ec2547eeff074c578c

If I boot from physical memory at 0x40200000
fastboot --base 40200000 --cmdline "console=ttyMSM0,115200,n8" boot zImage

kasan: populating shadow for b7040000, b75c0000
kasan: populating shadow for b8000000, bb000000
kasan: populating shadow for b6e00000, b7000000
kasan: Kernel address sanitizer initialized
8<--- cut here ---
Unable to handle kernel paging request at virtual address c30050b0
pgd = (ptrval)
[c30050b0] *pgd=00000000c
Internal error: Oops: 5 [#1] PREEMPT SMP ARM
Modules linked in:c
CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-00011-g1cd83357f3c3 #34
Hardware name: Generic DT based system
PC is at fdt_check_header+0x0/0x168
LR is at __unflatten_device_tree+0x6c/0x338
pc : [<c08e6968>]    lr : [<c0d698a8>]    psr: 60000093
sp : c1e03db8  ip : cffffee0  fp : fffff000
r10: 00000000  r9 : c2646000  r8 : 00000000
r7 : c30050b0  r6 : c192e9e4  r5 : c19492e8  r4 : c21d7448
r3 : 00000000  r2 : c2646000  r1 : 00000000  r0 : c30050b0
(...)
[<c08e6968>] (fdt_check_header) from [<c192e9e4>]
(early_init_dt_alloc_memory_arch+0x0/0x64)
[<c192e9e4>] (early_init_dt_alloc_memory_arch) from [<c1930264>]
(unflatten_device_tree+0x34/0x44)
[<c1930264>] (unflatten_device_tree) from [<c1905794>] (setup_arch+0xac4/0xde8)
[<c1905794>] (setup_arch) from [<c1900b98>] (start_kernel+0xd8/0x634)
[<c1900b98>] (start_kernel) from [<00000000>] (0x0)
Code: e3a00020 e12fff1e e3a0001c e12fff1e (e5901000)
random: get_random_bytes called from print_oops_end_marker+0x38/0x50
with crng_init=0
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Attempted to kill the idle task!
---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

But if I instead boot from 0x50000000 I just get this lesser error and
the platform actually comes up:
fastboot --base 50000000 --cmdline "console=ttyMSM0,115200,n8" boot zImage

[    0.000000] kasan: populating shadow for b7000000, b9000000
[    0.000000] kasan: populating shadow for b6e00000, b7000000
[    0.000000] kasan: Kernel address sanitizer initialized
[    0.000000] ==================================================================
[    0.000000] BUG: KASAN: stack-out-of-bounds in
memblock_alloc_try_nid+0x9c/0xac
[    0.000000] Write of size 61920 at addr cdbd6e20 by task swapper/0
[    0.000000]
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted
5.7.0-00011-g1cd83357f3c3 #34
[    0.000000] Hardware name: Generic DT based system
[    0.000000] [<c0317844>] (unwind_backtrace) from [<c0310544>]
(show_stack+0x10/0x14)
[    0.000000] [<c0310544>] (show_stack) from [<c08e6374>]
(dump_stack+0x80/0x98)
[    0.000000] [<c08e6374>] (dump_stack) from [<c050eed0>]
(print_address_description.constprop.3+0x50/0x478)
[    0.000000] [<c050eed0>] (print_address_description.constprop.3)
from [<c050f508>] (__kasan_report+0xf0/0x12c)
[    0.000000] [<c050f508>] (__kasan_report) from [<c050e95c>]
(kasan_report+0x34/0x3c)
[    0.000000] [<c050e95c>] (kasan_report) from [<c050fed0>]
(check_memory_region+0x14c/0x1b0)
[    0.000000] [<c050fed0>] (check_memory_region) from [<c050e100>]
(memset+0x20/0x3c)
[    0.000000] [<c050e100>] (memset) from [<c1918898>]
(memblock_alloc_try_nid+0x9c/0xac)
[    0.000000] [<c1918898>] (memblock_alloc_try_nid) from [<c192ea14>]
(early_init_dt_alloc_memory_arch+0x30/0x64)
[    0.000000] [<c192ea14>] (early_init_dt_alloc_memory_arch) from
[<c0d698f0>] (__unflatten_device_tree+0xb4/0x338)
[    0.000000] [<c0d698f0>] (__unflatten_device_tree) from
[<c1930264>] (unflatten_device_tree+0x34/0x44)
[    0.000000] [<c1930264>] (unflatten_device_tree) from [<c1905794>]
(setup_arch+0xac4/0xde8)
[    0.000000] [<c1905794>] (setup_arch) from [<c1900b98>]
(start_kernel+0xd8/0x634)
[    0.000000] [<c1900b98>] (start_kernel) from [<00000000>] (0x0)
[    0.000000]
[    0.000000] The buggy address belongs to the page:
[    0.000000] page:cffafac0 refcount:1 mapcount:0 mapping:00000000 index:0x0
[    0.000000] flags: 0x0()
[    0.000000] raw: 00000000 cffafac4 cffafac4 00000000 00000000
00000000 ffffffff 00000001
[    0.000000] page dumped because: kasan: bad access detected
[    0.000000]
[    0.000000] Memory state around the buggy address:
[    0.000000]  cdbe3d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]  cdbe3d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000] >cdbe3e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]                        ^
[    0.000000]  cdbe3e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]  cdbe3f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000] ==================================================================

There is something really funky going on with how devicetree is unflattened
in this platform I think, I just need to figure it out.

I do not think it is a KASan bug per se, more of a DT parser issue, like it is
doing stuff that need to be properly de-instrumented.

Any hints welcome!

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-04  9:24         ` Linus Walleij
@ 2020-06-04 11:26           ` Ard Biesheuvel
  2020-06-04 12:10             ` Ard Biesheuvel
  0 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2020-06-04 11:26 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Florian Fainelli, Abbott Liu, Russell King,
	Andrey Ryabinin, Linux ARM

On Thu, 4 Jun 2020 at 11:24, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Wed, Jun 3, 2020 at 10:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Mon, Jun 1, 2020 at 6:37 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
> >
> > > This branch got me a bit further,
> >
> > Thanks, at least we get improvements. :)
> >
> > > but still failed to fully initialize
> > > (see attached kasan.log), on another platform with a slightly different
> > > memory map, I ended up getting a different error (kasan2.log).
> >
> > I have this error too on a Qualcomm board, it is what I report
> > in the cover letter, that if I load the kernel into 0x40200000
> > this happens but when I load it into 0x50000000 it does not
> > happen.
>
> So this is what happens to me, even after I try to de-instrument
> the DT parsing code (maybe I do it all wrong...)
> This is done with that patch:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/commit/?h=kasan-apq8060-test&id=1cd83357f3c35b037400f6ec2547eeff074c578c
>
> If I boot from physical memory at 0x40200000
> fastboot --base 40200000 --cmdline "console=ttyMSM0,115200,n8" boot zImage
>
> kasan: populating shadow for b7040000, b75c0000
> kasan: populating shadow for b8000000, bb000000
> kasan: populating shadow for b6e00000, b7000000
> kasan: Kernel address sanitizer initialized
> 8<--- cut here ---
> Unable to handle kernel paging request at virtual address c30050b0
> pgd = (ptrval)
> [c30050b0] *pgd=00000000c
> Internal error: Oops: 5 [#1] PREEMPT SMP ARM
> Modules linked in:c
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-00011-g1cd83357f3c3 #34
> Hardware name: Generic DT based system
> PC is at fdt_check_header+0x0/0x168
> LR is at __unflatten_device_tree+0x6c/0x338
> pc : [<c08e6968>]    lr : [<c0d698a8>]    psr: 60000093
> sp : c1e03db8  ip : cffffee0  fp : fffff000
> r10: 00000000  r9 : c2646000  r8 : 00000000
> r7 : c30050b0  r6 : c192e9e4  r5 : c19492e8  r4 : c21d7448
> r3 : 00000000  r2 : c2646000  r1 : 00000000  r0 : c30050b0
> (...)
> [<c08e6968>] (fdt_check_header) from [<c192e9e4>]
> (early_init_dt_alloc_memory_arch+0x0/0x64)
> [<c192e9e4>] (early_init_dt_alloc_memory_arch) from [<c1930264>]
> (unflatten_device_tree+0x34/0x44)
> [<c1930264>] (unflatten_device_tree) from [<c1905794>] (setup_arch+0xac4/0xde8)
> [<c1905794>] (setup_arch) from [<c1900b98>] (start_kernel+0xd8/0x634)
> [<c1900b98>] (start_kernel) from [<00000000>] (0x0)
> Code: e3a00020 e12fff1e e3a0001c e12fff1e (e5901000)
> random: get_random_bytes called from print_oops_end_marker+0x38/0x50
> with crng_init=0
> ---[ end trace 0000000000000000 ]---
> Kernel panic - not syncing: Attempted to kill the idle task!
> ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
>

I don't think we ever check whether the ATAGS/DTB pointer points into
memory that is described to the kernel as unreserved lowmem. We simply
call phys_to_virt() on it [in setup_machine_fdt()], and assume that by
the time we call unflatten_device_tree(), the same virtual address
still points to the DT contents.

On arm64, we have a special fixmap slot for the DT, so there this
doesn't happen.

Could you try whether the following makes the issues go away?

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d8e18cdd96d3..b00867a026ed 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1076,6 +1076,7 @@ void __init hyp_mode_check(void)
 void __init setup_arch(char **cmdline_p)
 {
        const struct machine_desc *mdesc;
+       void *fdt;

        setup_processor();
        mdesc = setup_machine_fdt(__atags_pointer);
@@ -1135,6 +1136,8 @@ void __init setup_arch(char **cmdline_p)
        if (mdesc->restart)
                arm_pm_restart = mdesc->restart;

+       fdt = memremap(__atags_pointer, SZ_1M, MEMREMAP_WB);
+       early_init_dt_verify(fdt);
        unflatten_device_tree();

        arm_dt_init_cpu_maps();


(Not saying this is the right fix, just testing a hypothesis)





> But if I instead boot from 0x50000000 I just get this lesser error and
> the platform actually comes up:
> fastboot --base 50000000 --cmdline "console=ttyMSM0,115200,n8" boot zImage
>
> [    0.000000] kasan: populating shadow for b7000000, b9000000
> [    0.000000] kasan: populating shadow for b6e00000, b7000000
> [    0.000000] kasan: Kernel address sanitizer initialized
> [    0.000000] ==================================================================
> [    0.000000] BUG: KASAN: stack-out-of-bounds in
> memblock_alloc_try_nid+0x9c/0xac
> [    0.000000] Write of size 61920 at addr cdbd6e20 by task swapper/0
> [    0.000000]
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted
> 5.7.0-00011-g1cd83357f3c3 #34
> [    0.000000] Hardware name: Generic DT based system
> [    0.000000] [<c0317844>] (unwind_backtrace) from [<c0310544>]
> (show_stack+0x10/0x14)
> [    0.000000] [<c0310544>] (show_stack) from [<c08e6374>]
> (dump_stack+0x80/0x98)
> [    0.000000] [<c08e6374>] (dump_stack) from [<c050eed0>]
> (print_address_description.constprop.3+0x50/0x478)
> [    0.000000] [<c050eed0>] (print_address_description.constprop.3)
> from [<c050f508>] (__kasan_report+0xf0/0x12c)
> [    0.000000] [<c050f508>] (__kasan_report) from [<c050e95c>]
> (kasan_report+0x34/0x3c)
> [    0.000000] [<c050e95c>] (kasan_report) from [<c050fed0>]
> (check_memory_region+0x14c/0x1b0)
> [    0.000000] [<c050fed0>] (check_memory_region) from [<c050e100>]
> (memset+0x20/0x3c)
> [    0.000000] [<c050e100>] (memset) from [<c1918898>]
> (memblock_alloc_try_nid+0x9c/0xac)
> [    0.000000] [<c1918898>] (memblock_alloc_try_nid) from [<c192ea14>]
> (early_init_dt_alloc_memory_arch+0x30/0x64)
> [    0.000000] [<c192ea14>] (early_init_dt_alloc_memory_arch) from
> [<c0d698f0>] (__unflatten_device_tree+0xb4/0x338)
> [    0.000000] [<c0d698f0>] (__unflatten_device_tree) from
> [<c1930264>] (unflatten_device_tree+0x34/0x44)
> [    0.000000] [<c1930264>] (unflatten_device_tree) from [<c1905794>]
> (setup_arch+0xac4/0xde8)
> [    0.000000] [<c1905794>] (setup_arch) from [<c1900b98>]
> (start_kernel+0xd8/0x634)
> [    0.000000] [<c1900b98>] (start_kernel) from [<00000000>] (0x0)
> [    0.000000]
> [    0.000000] The buggy address belongs to the page:
> [    0.000000] page:cffafac0 refcount:1 mapcount:0 mapping:00000000 index:0x0
> [    0.000000] flags: 0x0()
> [    0.000000] raw: 00000000 cffafac4 cffafac4 00000000 00000000
> 00000000 ffffffff 00000001
> [    0.000000] page dumped because: kasan: bad access detected
> [    0.000000]
> [    0.000000] Memory state around the buggy address:
> [    0.000000]  cdbe3d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    0.000000]  cdbe3d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    0.000000] >cdbe3e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    0.000000]                        ^
> [    0.000000]  cdbe3e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    0.000000]  cdbe3f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [    0.000000] ==================================================================
>
> There is something really funky going on with how devicetree is unflattened
> in this platform I think, I just need to figure it out.
>
> I do not think it is a KASan bug per se, more of a DT parser issue, like it is
> doing stuff that need to be properly de-instrumented.
>
> Any hints welcome!
>
> Yours,
> Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-04 11:26           ` Ard Biesheuvel
@ 2020-06-04 12:10             ` Ard Biesheuvel
  2020-06-04 17:01               ` Ard Biesheuvel
  0 siblings, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2020-06-04 12:10 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Florian Fainelli, Abbott Liu, Russell King,
	Andrey Ryabinin, Linux ARM

On Thu, 4 Jun 2020 at 13:26, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 4 Jun 2020 at 11:24, Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > On Wed, Jun 3, 2020 at 10:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > > On Mon, Jun 1, 2020 at 6:37 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
> > >
> > > > This branch got me a bit further,
> > >
> > > Thanks, at least we get improvements. :)
> > >
> > > > but still failed to fully initialize
> > > > (see attached kasan.log), on another platform with a slightly different
> > > > memory map, I ended up getting a different error (kasan2.log).
> > >
> > > I have this error too on a Qualcomm board, it is what I report
> > > in the cover letter, that if I load the kernel into 0x40200000
> > > this happens but when I load it into 0x50000000 it does not
> > > happen.
> >
> > So this is what happens to me, even after I try to de-instrument
> > the DT parsing code (maybe I do it all wrong...)
> > This is done with that patch:
> > https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/commit/?h=kasan-apq8060-test&id=1cd83357f3c35b037400f6ec2547eeff074c578c
> >
> > If I boot from physical memory at 0x40200000
> > fastboot --base 40200000 --cmdline "console=ttyMSM0,115200,n8" boot zImage
> >
> > kasan: populating shadow for b7040000, b75c0000
> > kasan: populating shadow for b8000000, bb000000
> > kasan: populating shadow for b6e00000, b7000000
> > kasan: Kernel address sanitizer initialized
> > 8<--- cut here ---
> > Unable to handle kernel paging request at virtual address c30050b0
> > pgd = (ptrval)
> > [c30050b0] *pgd=00000000c
> > Internal error: Oops: 5 [#1] PREEMPT SMP ARM
> > Modules linked in:c
> > CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-00011-g1cd83357f3c3 #34
> > Hardware name: Generic DT based system
> > PC is at fdt_check_header+0x0/0x168
> > LR is at __unflatten_device_tree+0x6c/0x338
> > pc : [<c08e6968>]    lr : [<c0d698a8>]    psr: 60000093
> > sp : c1e03db8  ip : cffffee0  fp : fffff000
> > r10: 00000000  r9 : c2646000  r8 : 00000000
> > r7 : c30050b0  r6 : c192e9e4  r5 : c19492e8  r4 : c21d7448
> > r3 : 00000000  r2 : c2646000  r1 : 00000000  r0 : c30050b0
> > (...)
> > [<c08e6968>] (fdt_check_header) from [<c192e9e4>]
> > (early_init_dt_alloc_memory_arch+0x0/0x64)
> > [<c192e9e4>] (early_init_dt_alloc_memory_arch) from [<c1930264>]
> > (unflatten_device_tree+0x34/0x44)
> > [<c1930264>] (unflatten_device_tree) from [<c1905794>] (setup_arch+0xac4/0xde8)
> > [<c1905794>] (setup_arch) from [<c1900b98>] (start_kernel+0xd8/0x634)
> > [<c1900b98>] (start_kernel) from [<00000000>] (0x0)
> > Code: e3a00020 e12fff1e e3a0001c e12fff1e (e5901000)
> > random: get_random_bytes called from print_oops_end_marker+0x38/0x50
> > with crng_init=0
> > ---[ end trace 0000000000000000 ]---
> > Kernel panic - not syncing: Attempted to kill the idle task!
> > ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
> >
>
> I don't think we ever check whether the ATAGS/DTB pointer points into
> memory that is described to the kernel as unreserved lowmem. We simply
> call phys_to_virt() on it [in setup_machine_fdt()], and assume that by
> the time we call unflatten_device_tree(), the same virtual address
> still points to the DT contents.
>
> On arm64, we have a special fixmap slot for the DT, so there this
> doesn't happen.
>
> Could you try whether the following makes the issues go away?
>
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index d8e18cdd96d3..b00867a026ed 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1076,6 +1076,7 @@ void __init hyp_mode_check(void)
>  void __init setup_arch(char **cmdline_p)
>  {
>         const struct machine_desc *mdesc;
> +       void *fdt;
>
>         setup_processor();
>         mdesc = setup_machine_fdt(__atags_pointer);
> @@ -1135,6 +1136,8 @@ void __init setup_arch(char **cmdline_p)
>         if (mdesc->restart)
>                 arm_pm_restart = mdesc->restart;
>
> +       fdt = memremap(__atags_pointer, SZ_1M, MEMREMAP_WB);
> +       early_init_dt_verify(fdt);
>         unflatten_device_tree();
>
>         arm_dt_init_cpu_maps();
>
>
> (Not saying this is the right fix, just testing a hypothesis)
>

OK, so the bad news is that this doesn't help, but the good news is
that that means I have a reproducer :-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 0/5 v2] KASan for ARM
  2020-06-04 12:10             ` Ard Biesheuvel
@ 2020-06-04 17:01               ` Ard Biesheuvel
  0 siblings, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2020-06-04 17:01 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rob Herring, Florian Fainelli, Abbott Liu, Russell King,
	Andrey Ryabinin, Linux ARM

On Thu, 4 Jun 2020 at 14:10, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Thu, 4 Jun 2020 at 13:26, Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Thu, 4 Jun 2020 at 11:24, Linus Walleij <linus.walleij@linaro.org> wrote:
> > >
> > > On Wed, Jun 3, 2020 at 10:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > > > On Mon, Jun 1, 2020 at 6:37 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
> > > >
> > > > > This branch got me a bit further,
> > > >
> > > > Thanks, at least we get improvements. :)
> > > >
> > > > > but still failed to fully initialize
> > > > > (see attached kasan.log), on another platform with a slightly different
> > > > > memory map, I ended up getting a different error (kasan2.log).
> > > >
> > > > I have this error too on a Qualcomm board, it is what I report
> > > > in the cover letter, that if I load the kernel into 0x40200000
> > > > this happens but when I load it into 0x50000000 it does not
> > > > happen.
> > >
> > > So this is what happens to me, even after I try to de-instrument
> > > the DT parsing code (maybe I do it all wrong...)
> > > This is done with that patch:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/commit/?h=kasan-apq8060-test&id=1cd83357f3c35b037400f6ec2547eeff074c578c
> > >
> > > If I boot from physical memory at 0x40200000
> > > fastboot --base 40200000 --cmdline "console=ttyMSM0,115200,n8" boot zImage
> > >
> > > kasan: populating shadow for b7040000, b75c0000
> > > kasan: populating shadow for b8000000, bb000000
> > > kasan: populating shadow for b6e00000, b7000000
> > > kasan: Kernel address sanitizer initialized
> > > 8<--- cut here ---
> > > Unable to handle kernel paging request at virtual address c30050b0
> > > pgd = (ptrval)
> > > [c30050b0] *pgd=00000000c
> > > Internal error: Oops: 5 [#1] PREEMPT SMP ARM
> > > Modules linked in:c
> > > CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0-00011-g1cd83357f3c3 #34
> > > Hardware name: Generic DT based system
> > > PC is at fdt_check_header+0x0/0x168
> > > LR is at __unflatten_device_tree+0x6c/0x338
> > > pc : [<c08e6968>]    lr : [<c0d698a8>]    psr: 60000093
> > > sp : c1e03db8  ip : cffffee0  fp : fffff000
> > > r10: 00000000  r9 : c2646000  r8 : 00000000
> > > r7 : c30050b0  r6 : c192e9e4  r5 : c19492e8  r4 : c21d7448
> > > r3 : 00000000  r2 : c2646000  r1 : 00000000  r0 : c30050b0
> > > (...)
> > > [<c08e6968>] (fdt_check_header) from [<c192e9e4>]
> > > (early_init_dt_alloc_memory_arch+0x0/0x64)
> > > [<c192e9e4>] (early_init_dt_alloc_memory_arch) from [<c1930264>]
> > > (unflatten_device_tree+0x34/0x44)
> > > [<c1930264>] (unflatten_device_tree) from [<c1905794>] (setup_arch+0xac4/0xde8)
> > > [<c1905794>] (setup_arch) from [<c1900b98>] (start_kernel+0xd8/0x634)
> > > [<c1900b98>] (start_kernel) from [<00000000>] (0x0)
> > > Code: e3a00020 e12fff1e e3a0001c e12fff1e (e5901000)
> > > random: get_random_bytes called from print_oops_end_marker+0x38/0x50
> > > with crng_init=0
> > > ---[ end trace 0000000000000000 ]---
> > > Kernel panic - not syncing: Attempted to kill the idle task!
> > > ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
> > >
> >
> > I don't think we ever check whether the ATAGS/DTB pointer points into
> > memory that is described to the kernel as unreserved lowmem. We simply
> > call phys_to_virt() on it [in setup_machine_fdt()], and assume that by
> > the time we call unflatten_device_tree(), the same virtual address
> > still points to the DT contents.
> >

OK, so this is definitely not the issue. I am seeing very similar
issues, but in different places (two examples below)

What is notable here is that in both cases, a sizable chunk of memory
has one stack frame's worth of shadow bytes right in the middle. I
spent some time trying to figure out what is going on here, but I am
not a KASAN expert, so I am struggling a bit. Are we sure that all the
shadow is mapped correctly without physical pages being mapped more
than once?




[    0.000000] ==================================================================
[    0.000000] BUG: KASAN: stack-out-of-bounds in
memblock_alloc_try_nid+0x108/0x144
[    0.000000] Write of size 19104 at addr e95c2560 by task swapper/0
[    0.000000]
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.7.0+ #60
[    0.000000] Hardware name: Generic DT based system
[    0.000000] [<c0317634>] (unwind_backtrace) from [<c030f338>]
(show_stack+0x10/0x14)
[    0.000000] [<c030f338>] (show_stack) from [<c0905130>]
(dump_stack+0xc4/0xdc)
[    0.000000] [<c0905130>] (dump_stack) from [<c053b238>]
(print_address_description.constprop.0+0x34/0x444)
[    0.000000] [<c053b238>] (print_address_description.constprop.0)
from [<c053b844>] (kasan_report+0x158/0x174)
[    0.000000] [<c053b844>] (kasan_report) from [<c053c24c>]
(check_memory_region+0x94/0x1a4)
[    0.000000] [<c053c24c>] (check_memory_region) from [<c053a640>]
(memset+0x20/0x3c)
[    0.000000] [<c053a640>] (memset) from [<c242fa78>]
(memblock_alloc_try_nid+0x108/0x144)
[    0.000000] [<c242fa78>] (memblock_alloc_try_nid) from [<c24c857c>]
(early_init_dt_alloc_memory_arch+0x30/0x60)
[    0.000000] [<c24c857c>] (early_init_dt_alloc_memory_arch) from
[<c128cd3c>] (__unflatten_device_tree+0x5c/0x11c)
[    0.000000] [<c128cd3c>] (__unflatten_device_tree) from
[<c24c9c88>] (unflatten_device_tree+0x34/0x44)
[    0.000000] [<c24c9c88>] (unflatten_device_tree) from [<c2405a4c>]
(setup_arch+0xc00/0x10f4)
[    0.000000] [<c2405a4c>] (setup_arch) from [<c2400c2c>]
(start_kernel+0xd4/0x610)
[    0.000000] [<c2400c2c>] (start_kernel) from [<00000000>] (0x0)
[    0.000000]
[    0.000000] The buggy address belongs to the page:
[    0.000000] page:efd24840 refcount:1 mapcount:0 mapping:00000000 index:0x0
[    0.000000] flags: 0x0()
[    0.000000] raw: 00000000 efd24844 efd24844 00000000 00000000
00000000 ffffffff 00000001
[    0.000000] page dumped because: kasan: bad access detected
[    0.000000]
[    0.000000] Memory state around the buggy address:
[    0.000000]  e95c3c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]  e95c3c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000] >e95c3d00: f1 f1 f1 f1 f1 f1 04 f2 04 f3 f3 f3 00 00 00 00
[    0.000000]            ^
[    0.000000]  e95c3d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000]  e95c3e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[    0.000000] ==================================================================

[   50.235136] ==================================================================
[   50.238107] BUG: KASAN: stack-out-of-bounds in blk_add_partitions+0x1e8/0x6f8
[   50.239318] Write of size 32768 at addr f08c6000 by task swapper/0/1
[   50.240226]
[   50.241432] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.7.0+ #60
[   50.242402] Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015
[   50.244206] [<c0317634>] (unwind_backtrace) from [<c030f338>]
(show_stack+0x10/0x14)
[   50.245566] [<c030f338>] (show_stack) from [<c0905130>]
(dump_stack+0xc4/0xdc)
[   50.246823] [<c0905130>] (dump_stack) from [<c053b384>]
(print_address_description.constprop.0+0x180/0x444)
[   50.248429] [<c053b384>] (print_address_description.constprop.0)
from [<c053b844>] (kasan_report+0x158/0x174)
[   50.250113] [<c053b844>] (kasan_report) from [<c053c24c>]
(check_memory_region+0x94/0x1a4)
[   50.251495] [<c053c24c>] (check_memory_region) from [<c053a640>]
(memset+0x20/0x3c)
[   50.252787] [<c053a640>] (memset) from [<c0868954>]
(blk_add_partitions+0x1e8/0x6f8)
[   50.254172] [<c0868954>] (blk_add_partitions) from [<c05aa56c>]
(bdev_disk_changed+0x94/0x118)
[   50.255630] [<c05aa56c>] (bdev_disk_changed) from [<c05ab140>]
(__blkdev_get+0x460/0x748)
[   50.257091] [<c05ab140>] (__blkdev_get) from [<c08649b4>]
(__device_add_disk+0x718/0x808)
[   50.258649] [<c08649b4>] (__device_add_disk) from [<c24b12ac>]
(brd_init+0x158/0x234)
[   50.259989] [<c24b12ac>] (brd_init) from [<c0302630>]
(do_one_initcall+0xb4/0x30c)
[   50.261275] [<c0302630>] (do_one_initcall) from [<c2401360>]
(kernel_init_freeable+0x1f8/0x26c)
[   50.262629] [<c2401360>] (kernel_init_freeable) from [<c1545040>]
(kernel_init+0x8/0x120)
[   50.263953] [<c1545040>] (kernel_init) from [<c03001b0>]
(ret_from_fork+0x14/0x24)
[   50.265225] Exception stack(0xe88c3fb0 to 0xe88c3ff8)
[   50.266569] 3fa0:                                     00000000
00000000 00000000 00000000
[   50.268334] 3fc0: 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000
[   50.269970] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[   50.271241]
[   50.271821]
[   50.272268] Memory state around the buggy address:
[   50.274111]  f08cbd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   50.275302]  f08cbd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   50.276296] >f08cbe00: 00 00 00 00 f1 f1 f1 f1 04 f2 04 f2 00 f3 f3 f3
[   50.277548]                        ^
[   50.278206]  f08cbe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   50.279194]  f08cbf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   50.280193] ==================================================================

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2020-06-04 17:02 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-12  0:24 [PATCH 0/5 v2] KASan for ARM Linus Walleij
2020-04-12  0:24 ` [PATCH 1/5 v2] ARM: Disable KASan instrumentation for some code Linus Walleij
2020-04-12  0:24 ` [PATCH 2/5 v2] ARM: Replace memory functions for KASan Linus Walleij
2020-04-12  0:24 ` [PATCH 3/5 v2] ARM: Define the virtual space of KASan's shadow region Linus Walleij
2020-04-12  0:24 ` [PATCH 4/5 v2] ARM: Initialize the mapping of KASan shadow memory Linus Walleij
2020-04-12  0:24 ` [PATCH 5/5 v2] ARM: Enable KASan for ARM Linus Walleij
2020-06-01  4:00 ` [PATCH 0/5 v2] " Florian Fainelli
2020-06-01  8:55   ` Linus Walleij
2020-06-01 16:36     ` Florian Fainelli
2020-06-01 16:40       ` Ard Biesheuvel
2020-06-01 16:51         ` Florian Fainelli
2020-06-03  8:45       ` Linus Walleij
2020-06-04  9:24         ` Linus Walleij
2020-06-04 11:26           ` Ard Biesheuvel
2020-06-04 12:10             ` Ard Biesheuvel
2020-06-04 17:01               ` Ard Biesheuvel

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).