All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] arm64: kasan: log potential KASAN shadow aliases
@ 2021-12-02 11:27 ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

When using KASAN_GENERIC or KASAN_SW_TAGS, many representable pointer
values (e.g. NULL) don't have a legitimate shadow address. If KASAN
instrumentation attempts to access the shadow for such pointers, it will
fault on an unusual-looking address, e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001

To make this easier to debug, this series makes the arm64 fault handling
code log the corresponding memory range for potential shadow acceses,
e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001
| Possible KASAN shadow access for range [0000000000000008..000000000000000f]

Thanks,
Mark.

Mark Rutland (3):
  kasan: move kasan_shadow_to_mem() to shared header
  arm64: mm: use die_kernel_fault() in do_mem_abort()
  arm64: mm: log potential KASAN shadow alias

 arch/arm64/mm/fault.c | 13 ++++++++-----
 include/linux/kasan.h |  6 ++++++
 mm/kasan/kasan.h      |  6 ------
 3 files changed, 14 insertions(+), 11 deletions(-)

-- 
2.30.2


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

* [PATCH 0/3] arm64: kasan: log potential KASAN shadow aliases
@ 2021-12-02 11:27 ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

When using KASAN_GENERIC or KASAN_SW_TAGS, many representable pointer
values (e.g. NULL) don't have a legitimate shadow address. If KASAN
instrumentation attempts to access the shadow for such pointers, it will
fault on an unusual-looking address, e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001

To make this easier to debug, this series makes the arm64 fault handling
code log the corresponding memory range for potential shadow acceses,
e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001
| Possible KASAN shadow access for range [0000000000000008..000000000000000f]

Thanks,
Mark.

Mark Rutland (3):
  kasan: move kasan_shadow_to_mem() to shared header
  arm64: mm: use die_kernel_fault() in do_mem_abort()
  arm64: mm: log potential KASAN shadow alias

 arch/arm64/mm/fault.c | 13 ++++++++-----
 include/linux/kasan.h |  6 ++++++
 mm/kasan/kasan.h      |  6 ------
 3 files changed, 14 insertions(+), 11 deletions(-)

-- 
2.30.2


_______________________________________________
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] 12+ messages in thread

* [PATCH 1/3] kasan: move kasan_shadow_to_mem() to shared header
  2021-12-02 11:27 ` Mark Rutland
@ 2021-12-02 11:27   ` Mark Rutland
  -1 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

Some arch code would like to convert a shadow address to a corresponding
memory address, e.g. for better reporting when a fault is taken on a
shadow access.

We already provide architectures with kasan_mem_to_shadow() and all the
underlying constants, so we may as well allow them to use
kasan_shadow_to_mem() rather than having to open-code this.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
---
 include/linux/kasan.h | 6 ++++++
 mm/kasan/kasan.h      | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index d8783b682669..9059533e19c3 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -56,6 +56,12 @@ static inline void *kasan_mem_to_shadow(const void *addr)
 		+ KASAN_SHADOW_OFFSET;
 }
 
+static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
+{
+	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
+		<< KASAN_SHADOW_SCALE_SHIFT);
+}
+
 int kasan_add_zero_shadow(void *start, unsigned long size);
 void kasan_remove_zero_shadow(void *start, unsigned long size);
 
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index aebd8df86a1f..9ec09154ceb1 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -213,12 +213,6 @@ struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
-static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
-{
-	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
-		<< KASAN_SHADOW_SCALE_SHIFT);
-}
-
 static inline bool addr_has_metadata(const void *addr)
 {
 	return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
-- 
2.30.2


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

* [PATCH 1/3] kasan: move kasan_shadow_to_mem() to shared header
@ 2021-12-02 11:27   ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

Some arch code would like to convert a shadow address to a corresponding
memory address, e.g. for better reporting when a fault is taken on a
shadow access.

We already provide architectures with kasan_mem_to_shadow() and all the
underlying constants, so we may as well allow them to use
kasan_shadow_to_mem() rather than having to open-code this.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
---
 include/linux/kasan.h | 6 ++++++
 mm/kasan/kasan.h      | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index d8783b682669..9059533e19c3 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -56,6 +56,12 @@ static inline void *kasan_mem_to_shadow(const void *addr)
 		+ KASAN_SHADOW_OFFSET;
 }
 
+static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
+{
+	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
+		<< KASAN_SHADOW_SCALE_SHIFT);
+}
+
 int kasan_add_zero_shadow(void *start, unsigned long size);
 void kasan_remove_zero_shadow(void *start, unsigned long size);
 
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index aebd8df86a1f..9ec09154ceb1 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -213,12 +213,6 @@ struct kasan_free_meta *kasan_get_free_meta(struct kmem_cache *cache,
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
-static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
-{
-	return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET)
-		<< KASAN_SHADOW_SCALE_SHIFT);
-}
-
 static inline bool addr_has_metadata(const void *addr)
 {
 	return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
-- 
2.30.2


_______________________________________________
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] 12+ messages in thread

* [PATCH 2/3] arm64: mm: use die_kernel_fault() in do_mem_abort()
  2021-12-02 11:27 ` Mark Rutland
@ 2021-12-02 11:27   ` Mark Rutland
  -1 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

If we take an unhandled fault from EL1, either:

a) The xFSC handler calls die_kernel_fault() directly. In this case,
   die_kernel_fault() calls:

   pr_alert(..., msg, addr);
   mem_abort_decode(esr);
   show_pte(addr);
   die();
   bust_spinlocks(0);
   do_exit(SIGKILL);

b) The xFSC handler returns to do_mem_abort(), indicating failure. In
   this case, do_mem_abort() calls:

   pr_alert(..., addr);
   mem_abort_decode(esr);
   show_pte(addr);
   arm64_notify_die() {
     die();
   }

This inconstency is unfortunatem, and in theory in case (b) registered
notifiers can prevent us from terminating the faulting thread by
returning NOTIFY_STOP, whereupon we'll end up returning from the fault,
replaying, and almost certainly get stuck in a livelock spewing errors
into dmesg. We don't expect notifers to fix things up, since we dump
state to dmesg before invoking them, so it would be more sensible to
consistently terminate the thread in this case.

This patch has do_mem_abort() call die_kernel_fault() for unhandled
faults taken from EL1. Where we would previously have logged a messafe
of the form:

| Unhandled fault at ${ADDR}

... we will now log a message of the form:

| Unable to handle kernel ${FAULT_NAME} at virtual address ${ADDR}

... and we will consistently terminate the thread from which the fault
was taken.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/mm/fault.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 9ae24e3b72be..b7b9caa41bc7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -813,11 +813,8 @@ void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs)
 	if (!inf->fn(far, esr, regs))
 		return;
 
-	if (!user_mode(regs)) {
-		pr_alert("Unhandled fault at 0x%016lx\n", addr);
-		mem_abort_decode(esr);
-		show_pte(addr);
-	}
+	if (!user_mode(regs))
+		die_kernel_fault(inf->name, addr, esr, regs);
 
 	/*
 	 * At this point we have an unrecognized fault type whose tag bits may
-- 
2.30.2


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

* [PATCH 2/3] arm64: mm: use die_kernel_fault() in do_mem_abort()
@ 2021-12-02 11:27   ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

If we take an unhandled fault from EL1, either:

a) The xFSC handler calls die_kernel_fault() directly. In this case,
   die_kernel_fault() calls:

   pr_alert(..., msg, addr);
   mem_abort_decode(esr);
   show_pte(addr);
   die();
   bust_spinlocks(0);
   do_exit(SIGKILL);

b) The xFSC handler returns to do_mem_abort(), indicating failure. In
   this case, do_mem_abort() calls:

   pr_alert(..., addr);
   mem_abort_decode(esr);
   show_pte(addr);
   arm64_notify_die() {
     die();
   }

This inconstency is unfortunatem, and in theory in case (b) registered
notifiers can prevent us from terminating the faulting thread by
returning NOTIFY_STOP, whereupon we'll end up returning from the fault,
replaying, and almost certainly get stuck in a livelock spewing errors
into dmesg. We don't expect notifers to fix things up, since we dump
state to dmesg before invoking them, so it would be more sensible to
consistently terminate the thread in this case.

This patch has do_mem_abort() call die_kernel_fault() for unhandled
faults taken from EL1. Where we would previously have logged a messafe
of the form:

| Unhandled fault at ${ADDR}

... we will now log a message of the form:

| Unable to handle kernel ${FAULT_NAME} at virtual address ${ADDR}

... and we will consistently terminate the thread from which the fault
was taken.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/mm/fault.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 9ae24e3b72be..b7b9caa41bc7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -813,11 +813,8 @@ void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs)
 	if (!inf->fn(far, esr, regs))
 		return;
 
-	if (!user_mode(regs)) {
-		pr_alert("Unhandled fault at 0x%016lx\n", addr);
-		mem_abort_decode(esr);
-		show_pte(addr);
-	}
+	if (!user_mode(regs))
+		die_kernel_fault(inf->name, addr, esr, regs);
 
 	/*
 	 * At this point we have an unrecognized fault type whose tag bits may
-- 
2.30.2


_______________________________________________
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] 12+ messages in thread

* [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
  2021-12-02 11:27 ` Mark Rutland
@ 2021-12-02 11:27   ` Mark Rutland
  -1 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
memory is allocated and mapped for all legitimate kernel addresses, and
prior to a regular memory access instrumentation will read from the
corresponding shadow address.

Due to the way memory addresses are converted to shadow addresses,
bogus pointers (e.g. NULL) can generate shadow addresses out of the
bounds of allocated shadow memory. For example, with KASAN_GENERIC and
48-bit VAs, NULL would have a shadow address of dfff800000000000, which
falls between the TTBR ranges.

To make such cases easier to debug, this patch makes die_kernel_fault()
recover dump the real memory address range for any potential KASAN
shadow access. Since we can't reliably distinguish shadow accesses from
regular accesses, we always dump this information when shadow memory is
in use.

This makes it much easier to identify such cases, e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001
| Possible KASAN shadow access for range [0000000000000008..000000000000000f]
| Mem abort info:
|   ESR = 0x96000004
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x04: level 0 translation fault
| Data abort info:
|   ISV = 0, ISS = 0x00000004
|   CM = 0, WnR = 0
| [dfff800000000001] address between user and kernel address ranges
| Internal error: Oops: 96000004 [#1] PREEMPT SMP
| CPU: 1 PID: 285 Comm: kworker/1:3 Not tainted 5.16.0-rc3-00005-g24a22db61d64 #3
| Hardware name: linux,dummy-virt (DT)
| Workqueue: events netlink_sock_destruct_work
| pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
| pc : klist_iter_exit+0x2c/0x90
| lr : klist_iter_exit+0x20/0x90
| sp : ffff800011fd7a00
| x29: ffff800011fd7a00 x28: 1fffe8d1812f1e03 x27: ffff468c0a124d40
| x26: ffffa4783a9a4000 x25: ffff468c17666620 x24: 1fffe8d182ecccc4
| x23: ffff468c17666608 x22: 0000000000000008 x21: ffffa4783f9754a0
| x20: 0000000000000001 x19: 0000000000000000 x18: 0000000000000000
| x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
| x14: 1ffff000023faeea x13: ffff7000023faf33 x12: 1ffff000023faf32
| x11: 1ffff000023faf32 x10: ffff7000023faf32 x9 : ffffa47838735d5c
| x8 : ffff800011fd7997 x7 : 0000000000000001 x6 : ffff7000023faf33
| x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff468c0a124d40
| x2 : 0000000000000000 x1 : 0000000000000000 x0 : dfff800000000000
| Call trace:
|  klist_iter_exit+0x2c/0x90
|  class_dev_iter_exit+0x28/0x38
|  nfc_genl_dump_devices_done+0x44/0x68
|  genl_lock_done+0xa4/0x128
|  netlink_sock_destruct+0x1d4/0x280
|  __sk_destruct+0x58/0x6a8
|  sk_destruct+0xc0/0xe8
|  __sk_free+0xd4/0x350
|  sk_free+0x78/0x120
|  netlink_sock_destruct_work+0x28/0x38
|  process_one_work+0x8ac/0x1bd8
|  worker_thread+0x3f0/0xc48
|  kthread+0x3b4/0x460
|  ret_from_fork+0x10/0x20
| Code: 969c54cb d2d00000 d343fed4 f2fbffe0 (38e06a80)
| ---[ end trace 78cc63aab52d9b7b ]---

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/mm/fault.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b7b9caa41bc7..3ae84ab9f0fa 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
 	pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
 		 addr);
 
+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+	pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
+		 (unsigned long)kasan_shadow_to_mem((void *)addr),
+		 (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
+#endif
+
 	mem_abort_decode(esr);
 
 	show_pte(addr);
-- 
2.30.2


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

* [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
@ 2021-12-02 11:27   ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: andreyknvl, catalin.marinas, dvyukov, glider, linux-kernel,
	mark.rutland, ryabinin.a.a, will

When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
memory is allocated and mapped for all legitimate kernel addresses, and
prior to a regular memory access instrumentation will read from the
corresponding shadow address.

Due to the way memory addresses are converted to shadow addresses,
bogus pointers (e.g. NULL) can generate shadow addresses out of the
bounds of allocated shadow memory. For example, with KASAN_GENERIC and
48-bit VAs, NULL would have a shadow address of dfff800000000000, which
falls between the TTBR ranges.

To make such cases easier to debug, this patch makes die_kernel_fault()
recover dump the real memory address range for any potential KASAN
shadow access. Since we can't reliably distinguish shadow accesses from
regular accesses, we always dump this information when shadow memory is
in use.

This makes it much easier to identify such cases, e.g.

| Unable to handle kernel paging request at virtual address dfff800000000001
| Possible KASAN shadow access for range [0000000000000008..000000000000000f]
| Mem abort info:
|   ESR = 0x96000004
|   EC = 0x25: DABT (current EL), IL = 32 bits
|   SET = 0, FnV = 0
|   EA = 0, S1PTW = 0
|   FSC = 0x04: level 0 translation fault
| Data abort info:
|   ISV = 0, ISS = 0x00000004
|   CM = 0, WnR = 0
| [dfff800000000001] address between user and kernel address ranges
| Internal error: Oops: 96000004 [#1] PREEMPT SMP
| CPU: 1 PID: 285 Comm: kworker/1:3 Not tainted 5.16.0-rc3-00005-g24a22db61d64 #3
| Hardware name: linux,dummy-virt (DT)
| Workqueue: events netlink_sock_destruct_work
| pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
| pc : klist_iter_exit+0x2c/0x90
| lr : klist_iter_exit+0x20/0x90
| sp : ffff800011fd7a00
| x29: ffff800011fd7a00 x28: 1fffe8d1812f1e03 x27: ffff468c0a124d40
| x26: ffffa4783a9a4000 x25: ffff468c17666620 x24: 1fffe8d182ecccc4
| x23: ffff468c17666608 x22: 0000000000000008 x21: ffffa4783f9754a0
| x20: 0000000000000001 x19: 0000000000000000 x18: 0000000000000000
| x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
| x14: 1ffff000023faeea x13: ffff7000023faf33 x12: 1ffff000023faf32
| x11: 1ffff000023faf32 x10: ffff7000023faf32 x9 : ffffa47838735d5c
| x8 : ffff800011fd7997 x7 : 0000000000000001 x6 : ffff7000023faf33
| x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff468c0a124d40
| x2 : 0000000000000000 x1 : 0000000000000000 x0 : dfff800000000000
| Call trace:
|  klist_iter_exit+0x2c/0x90
|  class_dev_iter_exit+0x28/0x38
|  nfc_genl_dump_devices_done+0x44/0x68
|  genl_lock_done+0xa4/0x128
|  netlink_sock_destruct+0x1d4/0x280
|  __sk_destruct+0x58/0x6a8
|  sk_destruct+0xc0/0xe8
|  __sk_free+0xd4/0x350
|  sk_free+0x78/0x120
|  netlink_sock_destruct_work+0x28/0x38
|  process_one_work+0x8ac/0x1bd8
|  worker_thread+0x3f0/0xc48
|  kthread+0x3b4/0x460
|  ret_from_fork+0x10/0x20
| Code: 969c54cb d2d00000 d343fed4 f2fbffe0 (38e06a80)
| ---[ end trace 78cc63aab52d9b7b ]---

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/mm/fault.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b7b9caa41bc7..3ae84ab9f0fa 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
 	pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
 		 addr);
 
+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+	pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
+		 (unsigned long)kasan_shadow_to_mem((void *)addr),
+		 (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
+#endif
+
 	mem_abort_decode(esr);
 
 	show_pte(addr);
-- 
2.30.2


_______________________________________________
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] 12+ messages in thread

* Re: [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
  2021-12-02 11:27   ` Mark Rutland
@ 2021-12-02 16:20     ` Andrey Konovalov
  -1 siblings, 0 replies; 12+ messages in thread
From: Andrey Konovalov @ 2021-12-02 16:20 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Linux ARM, Catalin Marinas, Dmitry Vyukov, Alexander Potapenko,
	LKML, Andrey Ryabinin, Will Deacon

On Thu, Dec 2, 2021 at 12:27 PM Mark Rutland <mark.rutland@arm.com> wrote:
>
> When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
> memory is allocated and mapped for all legitimate kernel addresses, and
> prior to a regular memory access instrumentation will read from the
> corresponding shadow address.
>
> Due to the way memory addresses are converted to shadow addresses,
> bogus pointers (e.g. NULL) can generate shadow addresses out of the
> bounds of allocated shadow memory. For example, with KASAN_GENERIC and
> 48-bit VAs, NULL would have a shadow address of dfff800000000000, which
> falls between the TTBR ranges.
>
> To make such cases easier to debug, this patch makes die_kernel_fault()
> recover dump the real memory address range for any potential KASAN
> shadow access. Since we can't reliably distinguish shadow accesses from
> regular accesses, we always dump this information when shadow memory is
> in use.
>
> This makes it much easier to identify such cases, e.g.
>
> | Unable to handle kernel paging request at virtual address dfff800000000001
> | Possible KASAN shadow access for range [0000000000000008..000000000000000f]
> | Mem abort info:
> |   ESR = 0x96000004
> |   EC = 0x25: DABT (current EL), IL = 32 bits
> |   SET = 0, FnV = 0
> |   EA = 0, S1PTW = 0
> |   FSC = 0x04: level 0 translation fault
> | Data abort info:
> |   ISV = 0, ISS = 0x00000004
> |   CM = 0, WnR = 0
> | [dfff800000000001] address between user and kernel address ranges
> | Internal error: Oops: 96000004 [#1] PREEMPT SMP
> | CPU: 1 PID: 285 Comm: kworker/1:3 Not tainted 5.16.0-rc3-00005-g24a22db61d64 #3
> | Hardware name: linux,dummy-virt (DT)
> | Workqueue: events netlink_sock_destruct_work
> | pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> | pc : klist_iter_exit+0x2c/0x90
> | lr : klist_iter_exit+0x20/0x90
> | sp : ffff800011fd7a00
> | x29: ffff800011fd7a00 x28: 1fffe8d1812f1e03 x27: ffff468c0a124d40
> | x26: ffffa4783a9a4000 x25: ffff468c17666620 x24: 1fffe8d182ecccc4
> | x23: ffff468c17666608 x22: 0000000000000008 x21: ffffa4783f9754a0
> | x20: 0000000000000001 x19: 0000000000000000 x18: 0000000000000000
> | x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> | x14: 1ffff000023faeea x13: ffff7000023faf33 x12: 1ffff000023faf32
> | x11: 1ffff000023faf32 x10: ffff7000023faf32 x9 : ffffa47838735d5c
> | x8 : ffff800011fd7997 x7 : 0000000000000001 x6 : ffff7000023faf33
> | x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff468c0a124d40
> | x2 : 0000000000000000 x1 : 0000000000000000 x0 : dfff800000000000
> | Call trace:
> |  klist_iter_exit+0x2c/0x90
> |  class_dev_iter_exit+0x28/0x38
> |  nfc_genl_dump_devices_done+0x44/0x68
> |  genl_lock_done+0xa4/0x128
> |  netlink_sock_destruct+0x1d4/0x280
> |  __sk_destruct+0x58/0x6a8
> |  sk_destruct+0xc0/0xe8
> |  __sk_free+0xd4/0x350
> |  sk_free+0x78/0x120
> |  netlink_sock_destruct_work+0x28/0x38
> |  process_one_work+0x8ac/0x1bd8
> |  worker_thread+0x3f0/0xc48
> |  kthread+0x3b4/0x460
> |  ret_from_fork+0x10/0x20
> | Code: 969c54cb d2d00000 d343fed4 f2fbffe0 (38e06a80)
> | ---[ end trace 78cc63aab52d9b7b ]---
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Potapenko <glider@google.com>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: Will Deacon <will@kernel.org>
> ---
>  arch/arm64/mm/fault.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index b7b9caa41bc7..3ae84ab9f0fa 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
>         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
>                  addr);
>
> +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> +       pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
> +                (unsigned long)kasan_shadow_to_mem((void *)addr),
> +                (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
> +#endif

Hi Mark,

There's the kasan_non_canonical_hook() function that's used on x86 for
the same purpose: adding clarity to GPF faults caused by KASAN shadow
accesses. Would it possible to reuse it for arm64?

Thanks!


> +
>         mem_abort_decode(esr);
>
>         show_pte(addr);
> --
> 2.30.2
>

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

* Re: [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
@ 2021-12-02 16:20     ` Andrey Konovalov
  0 siblings, 0 replies; 12+ messages in thread
From: Andrey Konovalov @ 2021-12-02 16:20 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Linux ARM, Catalin Marinas, Dmitry Vyukov, Alexander Potapenko,
	LKML, Andrey Ryabinin, Will Deacon

On Thu, Dec 2, 2021 at 12:27 PM Mark Rutland <mark.rutland@arm.com> wrote:
>
> When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
> memory is allocated and mapped for all legitimate kernel addresses, and
> prior to a regular memory access instrumentation will read from the
> corresponding shadow address.
>
> Due to the way memory addresses are converted to shadow addresses,
> bogus pointers (e.g. NULL) can generate shadow addresses out of the
> bounds of allocated shadow memory. For example, with KASAN_GENERIC and
> 48-bit VAs, NULL would have a shadow address of dfff800000000000, which
> falls between the TTBR ranges.
>
> To make such cases easier to debug, this patch makes die_kernel_fault()
> recover dump the real memory address range for any potential KASAN
> shadow access. Since we can't reliably distinguish shadow accesses from
> regular accesses, we always dump this information when shadow memory is
> in use.
>
> This makes it much easier to identify such cases, e.g.
>
> | Unable to handle kernel paging request at virtual address dfff800000000001
> | Possible KASAN shadow access for range [0000000000000008..000000000000000f]
> | Mem abort info:
> |   ESR = 0x96000004
> |   EC = 0x25: DABT (current EL), IL = 32 bits
> |   SET = 0, FnV = 0
> |   EA = 0, S1PTW = 0
> |   FSC = 0x04: level 0 translation fault
> | Data abort info:
> |   ISV = 0, ISS = 0x00000004
> |   CM = 0, WnR = 0
> | [dfff800000000001] address between user and kernel address ranges
> | Internal error: Oops: 96000004 [#1] PREEMPT SMP
> | CPU: 1 PID: 285 Comm: kworker/1:3 Not tainted 5.16.0-rc3-00005-g24a22db61d64 #3
> | Hardware name: linux,dummy-virt (DT)
> | Workqueue: events netlink_sock_destruct_work
> | pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> | pc : klist_iter_exit+0x2c/0x90
> | lr : klist_iter_exit+0x20/0x90
> | sp : ffff800011fd7a00
> | x29: ffff800011fd7a00 x28: 1fffe8d1812f1e03 x27: ffff468c0a124d40
> | x26: ffffa4783a9a4000 x25: ffff468c17666620 x24: 1fffe8d182ecccc4
> | x23: ffff468c17666608 x22: 0000000000000008 x21: ffffa4783f9754a0
> | x20: 0000000000000001 x19: 0000000000000000 x18: 0000000000000000
> | x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> | x14: 1ffff000023faeea x13: ffff7000023faf33 x12: 1ffff000023faf32
> | x11: 1ffff000023faf32 x10: ffff7000023faf32 x9 : ffffa47838735d5c
> | x8 : ffff800011fd7997 x7 : 0000000000000001 x6 : ffff7000023faf33
> | x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff468c0a124d40
> | x2 : 0000000000000000 x1 : 0000000000000000 x0 : dfff800000000000
> | Call trace:
> |  klist_iter_exit+0x2c/0x90
> |  class_dev_iter_exit+0x28/0x38
> |  nfc_genl_dump_devices_done+0x44/0x68
> |  genl_lock_done+0xa4/0x128
> |  netlink_sock_destruct+0x1d4/0x280
> |  __sk_destruct+0x58/0x6a8
> |  sk_destruct+0xc0/0xe8
> |  __sk_free+0xd4/0x350
> |  sk_free+0x78/0x120
> |  netlink_sock_destruct_work+0x28/0x38
> |  process_one_work+0x8ac/0x1bd8
> |  worker_thread+0x3f0/0xc48
> |  kthread+0x3b4/0x460
> |  ret_from_fork+0x10/0x20
> | Code: 969c54cb d2d00000 d343fed4 f2fbffe0 (38e06a80)
> | ---[ end trace 78cc63aab52d9b7b ]---
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Potapenko <glider@google.com>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: Will Deacon <will@kernel.org>
> ---
>  arch/arm64/mm/fault.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index b7b9caa41bc7..3ae84ab9f0fa 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
>         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
>                  addr);
>
> +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> +       pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
> +                (unsigned long)kasan_shadow_to_mem((void *)addr),
> +                (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
> +#endif

Hi Mark,

There's the kasan_non_canonical_hook() function that's used on x86 for
the same purpose: adding clarity to GPF faults caused by KASAN shadow
accesses. Would it possible to reuse it for arm64?

Thanks!


> +
>         mem_abort_decode(esr);
>
>         show_pte(addr);
> --
> 2.30.2
>

_______________________________________________
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] 12+ messages in thread

* Re: [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
  2021-12-02 16:20     ` Andrey Konovalov
@ 2021-12-02 16:30       ` Mark Rutland
  -1 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 16:30 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: Linux ARM, Catalin Marinas, Dmitry Vyukov, Alexander Potapenko,
	LKML, Andrey Ryabinin, Will Deacon

On Thu, Dec 02, 2021 at 05:20:56PM +0100, Andrey Konovalov wrote:
> On Thu, Dec 2, 2021 at 12:27 PM Mark Rutland <mark.rutland@arm.com> wrote:
> >
> > When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
> > memory is allocated and mapped for all legitimate kernel addresses, and
> > prior to a regular memory access instrumentation will read from the
> > corresponding shadow address.
> >
> > Due to the way memory addresses are converted to shadow addresses,
> > bogus pointers (e.g. NULL) can generate shadow addresses out of the
> > bounds of allocated shadow memory. For example, with KASAN_GENERIC and
> > 48-bit VAs, NULL would have a shadow address of dfff800000000000, which
> > falls between the TTBR ranges.
> >
> > To make such cases easier to debug, this patch makes die_kernel_fault()
> > recover dump the real memory address range for any potential KASAN
> > shadow access. Since we can't reliably distinguish shadow accesses from
> > regular accesses, we always dump this information when shadow memory is
> > in use.

> > @@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
> >         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
> >                  addr);
> >
> > +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> > +       pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
> > +                (unsigned long)kasan_shadow_to_mem((void *)addr),
> > +                (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
> > +#endif
> 
> Hi Mark,
> 
> There's the kasan_non_canonical_hook() function that's used on x86 for
> the same purpose: adding clarity to GPF faults caused by KASAN shadow
> accesses. Would it possible to reuse it for arm64?

Aha! That looks like exactly what I'm after; I'll go try that for v2.

Thanks for the pointer!

Mark.

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

* Re: [PATCH 3/3] arm64: mm: log potential KASAN shadow alias
@ 2021-12-02 16:30       ` Mark Rutland
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2021-12-02 16:30 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: Linux ARM, Catalin Marinas, Dmitry Vyukov, Alexander Potapenko,
	LKML, Andrey Ryabinin, Will Deacon

On Thu, Dec 02, 2021 at 05:20:56PM +0100, Andrey Konovalov wrote:
> On Thu, Dec 2, 2021 at 12:27 PM Mark Rutland <mark.rutland@arm.com> wrote:
> >
> > When the kernel is built with KASAN_GENERIC or KASAN_SW_TAGS, shadow
> > memory is allocated and mapped for all legitimate kernel addresses, and
> > prior to a regular memory access instrumentation will read from the
> > corresponding shadow address.
> >
> > Due to the way memory addresses are converted to shadow addresses,
> > bogus pointers (e.g. NULL) can generate shadow addresses out of the
> > bounds of allocated shadow memory. For example, with KASAN_GENERIC and
> > 48-bit VAs, NULL would have a shadow address of dfff800000000000, which
> > falls between the TTBR ranges.
> >
> > To make such cases easier to debug, this patch makes die_kernel_fault()
> > recover dump the real memory address range for any potential KASAN
> > shadow access. Since we can't reliably distinguish shadow accesses from
> > regular accesses, we always dump this information when shadow memory is
> > in use.

> > @@ -297,6 +297,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
> >         pr_alert("Unable to handle kernel %s at virtual address %016lx\n", msg,
> >                  addr);
> >
> > +#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> > +       pr_alert("Possible KASAN shadow access for range [%016lx..%016lx]\n",
> > +                (unsigned long)kasan_shadow_to_mem((void *)addr),
> > +                (unsigned long)kasan_shadow_to_mem((void *)addr + 1) - 1);
> > +#endif
> 
> Hi Mark,
> 
> There's the kasan_non_canonical_hook() function that's used on x86 for
> the same purpose: adding clarity to GPF faults caused by KASAN shadow
> accesses. Would it possible to reuse it for arm64?

Aha! That looks like exactly what I'm after; I'll go try that for v2.

Thanks for the pointer!

Mark.

_______________________________________________
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] 12+ messages in thread

end of thread, other threads:[~2021-12-02 16:32 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-02 11:27 [PATCH 0/3] arm64: kasan: log potential KASAN shadow aliases Mark Rutland
2021-12-02 11:27 ` Mark Rutland
2021-12-02 11:27 ` [PATCH 1/3] kasan: move kasan_shadow_to_mem() to shared header Mark Rutland
2021-12-02 11:27   ` Mark Rutland
2021-12-02 11:27 ` [PATCH 2/3] arm64: mm: use die_kernel_fault() in do_mem_abort() Mark Rutland
2021-12-02 11:27   ` Mark Rutland
2021-12-02 11:27 ` [PATCH 3/3] arm64: mm: log potential KASAN shadow alias Mark Rutland
2021-12-02 11:27   ` Mark Rutland
2021-12-02 16:20   ` Andrey Konovalov
2021-12-02 16:20     ` Andrey Konovalov
2021-12-02 16:30     ` Mark Rutland
2021-12-02 16:30       ` Mark Rutland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.