Module Name: src
Committed By: maxv
Date: Wed Aug 22 17:25:02 UTC 2018
Modified Files:
src/sys/arch/amd64/amd64: asan.c
Log Message:
Unwind the stack on error, to get the full path that led to the illegal
access. Example of output:
kASan: Unauthorized Access In 0xffffffff80e6219c: Addr 0xffffbb007a39fd03 [1
byte, read]
#0 0xffffffff80e6219c in ras_purgeall <netbsd>
#1 0xffffffff80e62330 in sys_rasctl <netbsd>
#2 0xffffffff80265008 in syscall <netbsd>
(I manually added a one-byte stack read overflow in rasctl to demonstrate.)
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/amd64/amd64/asan.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/asan.c
diff -u src/sys/arch/amd64/amd64/asan.c:1.4 src/sys/arch/amd64/amd64/asan.c:1.5
--- src/sys/arch/amd64/amd64/asan.c:1.4 Wed Aug 22 17:04:36 2018
+++ src/sys/arch/amd64/amd64/asan.c Wed Aug 22 17:25:02 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: asan.c,v 1.4 2018/08/22 17:04:36 maxv Exp $ */
+/* $NetBSD: asan.c,v 1.5 2018/08/22 17:25:02 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: asan.c,v 1.4 2018/08/22 17:04:36 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: asan.c,v 1.5 2018/08/22 17:25:02 maxv Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: asan.c,v 1.4
#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/types.h>
+#include <sys/ksyms.h>
#include <sys/asan.h>
#include <uvm/uvm.h>
@@ -248,12 +249,69 @@ kasan_init(void)
/* -------------------------------------------------------------------------- */
+static inline bool
+kasan_unwind_end(const char *name)
+{
+ if (!strcmp(name, "syscall") ||
+ !strcmp(name, "handle_syscall") ||
+ !strncmp(name, "Xintr", 5) ||
+ !strncmp(name, "Xhandle", 7) ||
+ !strncmp(name, "Xresume", 7) ||
+ !strncmp(name, "Xstray", 6) ||
+ !strncmp(name, "Xhold", 5) ||
+ !strncmp(name, "Xrecurse", 8) ||
+ !strcmp(name, "Xdoreti") ||
+ !strncmp(name, "Xsoft", 5)) {
+ return true;
+ }
+
+ return false;
+}
+
+static void
+kasan_unwind(void)
+{
+ uint64_t *rbp, rip;
+ const char *mod;
+ const char *sym;
+ size_t nsym;
+ int error;
+
+ rbp = (uint64_t *)__builtin_frame_address(0);
+ nsym = 0;
+
+ while (1) {
+ /* 8(%rbp) contains the saved %rip. */
+ rip = *(rbp + 1);
+
+ if (rip < KERNBASE) {
+ break;
+ }
+ error = ksyms_getname(&mod, &sym, (vaddr_t)rip, KSYMS_PROC);
+ if (error) {
+ break;
+ }
+ printf("#%zu %p in %s <%s>\n", nsym, (void *)rip, sym, mod);
+ if (kasan_unwind_end(sym)) {
+ break;
+ }
+
+ rbp = (uint64_t *)*(rbp);
+ nsym++;
+
+ if (nsym >= 15) {
+ break;
+ }
+ }
+}
+
static void
kasan_report(unsigned long addr, size_t size, bool write, unsigned long rip)
{
printf("kASan: Unauthorized Access In %p: Addr %p [%zu byte%s, %s]\n",
(void *)rip, (void *)addr, size, (size > 1 ? "s" : ""),
(write ? "write" : "read"));
+ kasan_unwind();
}
/* -------------------------------------------------------------------------- */