提交 4291e9ee 编写于 作者: A Andrey Konovalov 提交者: Linus Torvalds

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.

Link: https://lkml.kernel.org/r/b559c82b6a969afedf53b4694b475f0234067a1a.1606161801.git.andreyknvl@google.comSigned-off-by: NAndrey Konovalov <andreyknvl@google.com>
Co-developed-by: NVincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: NVincenzo Frascino <vincenzo.frascino@arm.com>
Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: NAlexander Potapenko <glider@google.com>
Tested-by: NVincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Branislav Rankov <Branislav.Rankov@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgenii Stepanov <eugenis@google.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Marco Elver <elver@google.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 2e903b91
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kasan.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/page-flags.h> #include <linux/page-flags.h>
...@@ -297,10 +298,23 @@ static void die_kernel_fault(const char *msg, unsigned long addr, ...@@ -297,10 +298,23 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
do_exit(SIGKILL); do_exit(SIGKILL);
} }
#ifdef CONFIG_KASAN_HW_TAGS
static void report_tag_fault(unsigned long addr, unsigned int esr, static void report_tag_fault(unsigned long addr, unsigned int esr,
struct pt_regs *regs) 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, static void do_tag_recovery(unsigned long addr, unsigned int esr,
struct pt_regs *regs) struct pt_regs *regs)
......
...@@ -62,9 +62,14 @@ static void print_error_description(struct kasan_access_info *info) ...@@ -62,9 +62,14 @@ static void print_error_description(struct kasan_access_info *info)
{ {
pr_err("BUG: KASAN: %s in %pS\n", pr_err("BUG: KASAN: %s in %pS\n",
get_bug_type(info), (void *)info->ip); get_bug_type(info), (void *)info->ip);
pr_err("%s of size %zu at addr %px by task %s/%d\n", if (info->access_size)
info->is_write ? "Write" : "Read", info->access_size, pr_err("%s of size %zu at addr %px by task %s/%d\n",
info->access_addr, current->comm, task_pid_nr(current)); 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); static DEFINE_SPINLOCK(report_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册