On Fri, Mar 02, 2018 at 08:44:30PM +0100, Andrey Konovalov wrote: > KHWASAN inline instrumentation mode (which embeds checks of shadow memory > into the generated code, instead of inserting a callback) generates a brk > instruction when a tag mismatch is detected. The compiler generates the BRK? I'm a little worried about the ABI implications of that. So far we've assumed that for hte kernel-side, the BRK space is completely under our control. How much does this save, compared to having a callback? > This commit add a KHWASAN brk handler, that decodes the immediate value > passed to the brk instructions (to extract information about the memory > access that triggered the mismatch), reads the register values (x0 contains > the guilty address) and reports the bug. > --- > arch/arm64/include/asm/brk-imm.h | 2 ++ > arch/arm64/kernel/traps.c | 40 ++++++++++++++++++++++++++++++++ > 2 files changed, 42 insertions(+) > > diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h > index ed693c5bcec0..e4a7013321dc 100644 > --- a/arch/arm64/include/asm/brk-imm.h > +++ b/arch/arm64/include/asm/brk-imm.h > @@ -16,10 +16,12 @@ > * 0x400: for dynamic BRK instruction > * 0x401: for compile time BRK instruction > * 0x800: kernel-mode BUG() and WARN() traps > + * 0x9xx: KHWASAN trap (allowed values 0x900 - 0x9ff) > */ > #define FAULT_BRK_IMM 0x100 > #define KGDB_DYN_DBG_BRK_IMM 0x400 > #define KGDB_COMPILED_DBG_BRK_IMM 0x401 > #define BUG_BRK_IMM 0x800 > +#define KHWASAN_BRK_IMM 0x900 > > #endif > diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c > index eb2d15147e8d..5df8cdf5af13 100644 > --- a/arch/arm64/kernel/traps.c > +++ b/arch/arm64/kernel/traps.c > @@ -35,6 +35,7 @@ > #include <linux/sizes.h> > #include <linux/syscalls.h> > #include <linux/mm_types.h> > +#include <linux/kasan.h> > > #include <asm/atomic.h> > #include <asm/bug.h> > @@ -771,6 +772,38 @@ static struct break_hook bug_break_hook = { > .fn = bug_handler, > }; > > +#ifdef CONFIG_KASAN_TAGS > +static int khwasan_handler(struct pt_regs *regs, unsigned int esr) > +{ > + bool recover = esr & 0x20; > + bool write = esr & 0x10; Can you please add mnemonics for these, e.g. #define KHWASAN_ESR_RECOVER 0x20 #define KHWASAN_ESR_WRITE 0x10 > + size_t size = 1 << (esr & 0xf); #define KHWASAN_ESR_SIZE_MASK 0x4 #define KHWASAN_ESR_SIZE(esr) (1 << (esr) & KHWASAN_ESR_SIZE_MASK) > + u64 addr = regs->regs[0]; > + u64 pc = regs->pc; > + > + if (user_mode(regs)) > + return DBG_HOOK_ERROR; > + > + khwasan_report(addr, size, write, pc); > + > + if (!recover) > + die("Oops - KHWASAN", regs, 0); Could you elaborate on what "recover" means, and why it's up the the compiler to decide if the kernel should die()? > + > + /* If thread survives, skip over the BUG instruction and continue: */ > + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); This is for fast-forwarding user instruction streams, and isn't correct to call for kernel faults (as it'll mess up the userspace single step logic). Thanks, Mark. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>