2020-11-10 22:15:47

by Andrey Konovalov

[permalink] [raw]
Subject: [PATCH v9 40/44] kasan, arm64: print report from tag fault handler

Add error reporting for hardware tag-based KASAN. When CONFIG_KASAN_HW_TAGS
is enabled, print KASAN report from the arm64 tag fault handler.

SAS bits aren't set in ESR for all faults reported in EL1, so it's
impossible to find out the size of the access the caused the fault.
Adapt KASAN reporting code to handle this case.

Signed-off-by: Andrey Konovalov <[email protected]>
Co-developed-by: Vincenzo Frascino <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
---
Change-Id: I3780fe7db6e075dff2937d3d8508f55c9322b095
---
arch/arm64/mm/fault.c | 14 ++++++++++++++
mm/kasan/report.c | 11 ++++++++---
2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index fbceb14d93b1..7370e822e588 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/init.h>
+#include <linux/kasan.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/page-flags.h>
@@ -297,10 +298,23 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
do_exit(SIGKILL);
}

+#ifdef CONFIG_KASAN_HW_TAGS
static void report_tag_fault(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
{
+ bool is_write = ((esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT) != 0;
+
+ /*
+ * SAS bits aren't set for all faults reported in EL1, so we can't
+ * find out access size.
+ */
+ kasan_report(addr, 0, is_write, regs->pc);
}
+#else
+/* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */
+static inline void report_tag_fault(unsigned long addr, unsigned int esr,
+ struct pt_regs *regs) { }
+#endif

static void do_tag_recovery(unsigned long addr, unsigned int esr,
struct pt_regs *regs)
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 8afc1a6ab202..ce06005d4052 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -62,9 +62,14 @@ static void print_error_description(struct kasan_access_info *info)
{
pr_err("BUG: KASAN: %s in %pS\n",
get_bug_type(info), (void *)info->ip);
- pr_err("%s of size %zu at addr %px by task %s/%d\n",
- info->is_write ? "Write" : "Read", info->access_size,
- info->access_addr, current->comm, task_pid_nr(current));
+ if (info->access_size)
+ pr_err("%s of size %zu at addr %px by task %s/%d\n",
+ info->is_write ? "Write" : "Read", info->access_size,
+ info->access_addr, current->comm, task_pid_nr(current));
+ else
+ pr_err("%s at addr %px by task %s/%d\n",
+ info->is_write ? "Write" : "Read",
+ info->access_addr, current->comm, task_pid_nr(current));
}

static DEFINE_SPINLOCK(report_lock);
--
2.29.2.222.g5d2a92d10f8-goog


2020-11-11 16:45:28

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH v9 40/44] kasan, arm64: print report from tag fault handler

On Tue, Nov 10, 2020 at 11:12 PM 'Andrey Konovalov' via kasan-dev
<[email protected]> wrote:
>
> Add error reporting for hardware tag-based KASAN. When CONFIG_KASAN_HW_TAGS
> is enabled, print KASAN report from the arm64 tag fault handler.
>
> SAS bits aren't set in ESR for all faults reported in EL1, so it's
> impossible to find out the size of the access the caused the fault.
> Adapt KASAN reporting code to handle this case.
>
> Signed-off-by: Andrey Konovalov <[email protected]>
> Co-developed-by: Vincenzo Frascino <[email protected]>
> Signed-off-by: Vincenzo Frascino <[email protected]>
> Reviewed-by: Catalin Marinas <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>

> ---
> Change-Id: I3780fe7db6e075dff2937d3d8508f55c9322b095
> ---
> arch/arm64/mm/fault.c | 14 ++++++++++++++
> mm/kasan/report.c | 11 ++++++++---
> 2 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index fbceb14d93b1..7370e822e588 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -14,6 +14,7 @@
> #include <linux/mm.h>
> #include <linux/hardirq.h>
> #include <linux/init.h>
> +#include <linux/kasan.h>
> #include <linux/kprobes.h>
> #include <linux/uaccess.h>
> #include <linux/page-flags.h>
> @@ -297,10 +298,23 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
> do_exit(SIGKILL);
> }
>
> +#ifdef CONFIG_KASAN_HW_TAGS
> static void report_tag_fault(unsigned long addr, unsigned int esr,
> struct pt_regs *regs)
> {
> + bool is_write = ((esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT) != 0;
> +
> + /*
> + * SAS bits aren't set for all faults reported in EL1, so we can't
> + * find out access size.
> + */
> + kasan_report(addr, 0, is_write, regs->pc);
> }
> +#else
> +/* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */
> +static inline void report_tag_fault(unsigned long addr, unsigned int esr,
> + struct pt_regs *regs) { }
> +#endif
>
> static void do_tag_recovery(unsigned long addr, unsigned int esr,
> struct pt_regs *regs)
> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> index 8afc1a6ab202..ce06005d4052 100644
> --- a/mm/kasan/report.c
> +++ b/mm/kasan/report.c
> @@ -62,9 +62,14 @@ static void print_error_description(struct kasan_access_info *info)
> {
> pr_err("BUG: KASAN: %s in %pS\n",
> get_bug_type(info), (void *)info->ip);
> - pr_err("%s of size %zu at addr %px by task %s/%d\n",
> - info->is_write ? "Write" : "Read", info->access_size,
> - info->access_addr, current->comm, task_pid_nr(current));
> + if (info->access_size)
> + pr_err("%s of size %zu at addr %px by task %s/%d\n",
> + info->is_write ? "Write" : "Read", info->access_size,
> + info->access_addr, current->comm, task_pid_nr(current));
> + else
> + pr_err("%s at addr %px by task %s/%d\n",
> + info->is_write ? "Write" : "Read",
> + info->access_addr, current->comm, task_pid_nr(current));
> }
>
> static DEFINE_SPINLOCK(report_lock);
> --
> 2.29.2.222.g5d2a92d10f8-goog
>
> --
> You received this message because you are subscribed to the Google Groups "kasan-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/fe78d723ba64456d68754a944fa93fe4a25c730f.1605046192.git.andreyknvl%40google.com.



--
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg