From: Sami Tolvanen <samitolvanen@google.com> To: linux-kernel@vger.kernel.org Cc: Kees Cook <keescook@chromium.org>, Josh Poimboeuf <jpoimboe@redhat.com>, Peter Zijlstra <peterz@infradead.org>, x86@kernel.org, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Nathan Chancellor <nathan@kernel.org>, Nick Desaulniers <ndesaulniers@google.com>, Joao Moreira <joao@overdrivepizza.com>, Sedat Dilek <sedat.dilek@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, linux-hardening@vger.kernel.org, linux-arm-kernel@lists.infradead.org, llvm@lists.linux.dev, Sami Tolvanen <samitolvanen@google.com> Subject: [RFC PATCH 09/21] arm64: Add CFI error handling Date: Fri, 29 Apr 2022 13:36:32 -0700 [thread overview] Message-ID: <20220429203644.2868448-10-samitolvanen@google.com> (raw) In-Reply-To: <20220429203644.2868448-1-samitolvanen@google.com> With -fsanitize=kcfi, CFI always traps. Add arm64 support for handling CFI failures and determining the target address. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> --- arch/arm64/include/asm/brk-imm.h | 2 ++ arch/arm64/include/asm/insn.h | 1 + arch/arm64/kernel/traps.c | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h index ec7720dbe2c8..3a50b70b4404 100644 --- a/arch/arm64/include/asm/brk-imm.h +++ b/arch/arm64/include/asm/brk-imm.h @@ -16,6 +16,7 @@ * 0x400: for dynamic BRK instruction * 0x401: for compile time BRK instruction * 0x800: kernel-mode BUG() and WARN() traps + * 0x801: Control-Flow Integrity traps * 0x9xx: tag-based KASAN trap (allowed values 0x900 - 0x9ff) */ #define KPROBES_BRK_IMM 0x004 @@ -25,6 +26,7 @@ #define KGDB_DYN_DBG_BRK_IMM 0x400 #define KGDB_COMPILED_DBG_BRK_IMM 0x401 #define BUG_BRK_IMM 0x800 +#define CFI_BRK_IMM 0x801 #define KASAN_BRK_IMM 0x900 #define KASAN_BRK_MASK 0x0ff diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 1e5760d567ae..12225bdfa776 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -334,6 +334,7 @@ __AARCH64_INSN_FUNCS(store_pre, 0x3FE00C00, 0x38000C00) __AARCH64_INSN_FUNCS(load_pre, 0x3FE00C00, 0x38400C00) __AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400) __AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400) +__AARCH64_INSN_FUNCS(ldur, 0x3FE00C00, 0x38400000) __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000) __AARCH64_INSN_FUNCS(ldclr, 0x3F20FC00, 0x38201000) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 0529fd57567e..b524411ba663 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -26,6 +26,7 @@ #include <linux/syscalls.h> #include <linux/mm_types.h> #include <linux/kasan.h> +#include <linux/cfi.h> #include <asm/atomic.h> #include <asm/bug.h> @@ -990,6 +991,55 @@ static struct break_hook bug_break_hook = { .imm = BUG_BRK_IMM, }; +#ifdef CONFIG_CFI_CLANG +void *arch_get_cfi_target(unsigned long addr, struct pt_regs *regs) +{ + /* The expected CFI check instruction sequence: + * ldur wA, [xN, #-4] + * movk wB, #nnnnn + * movk wB, #nnnnn, lsl #16 + * cmp wA, wB + * b.eq .Ltmp1 + * brk #0x801 ; <- addr + * .Ltmp1: + * + * Therefore, the target address is in the xN register, which we can + * decode from the ldur instruction. + */ + u32 insn, rn; + void *p = (void *)(addr - 5 * AARCH64_INSN_SIZE); + + if (aarch64_insn_read(p, &insn) || !aarch64_insn_is_ldur(insn)) + return NULL; + + rn = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn); + return (void *)regs->regs[rn]; +} + +static int cfi_handler(struct pt_regs *regs, unsigned int esr) +{ + switch (report_cfi(regs->pc, regs)) { + case BUG_TRAP_TYPE_BUG: + die("Oops - CFI", regs, 0); + break; + + case BUG_TRAP_TYPE_WARN: + break; + + default: + return DBG_HOOK_ERROR; + } + + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); + return DBG_HOOK_HANDLED; +} + +static struct break_hook cfi_break_hook = { + .fn = cfi_handler, + .imm = CFI_BRK_IMM, +}; +#endif /* CONFIG_CFI_CLANG */ + static int reserved_fault_handler(struct pt_regs *regs, unsigned int esr) { pr_err("%s generated an invalid instruction at %pS!\n", @@ -1063,6 +1113,10 @@ int __init early_brk64(unsigned long addr, unsigned int esr, if ((comment & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) return kasan_handler(regs, esr) != DBG_HOOK_HANDLED; +#endif +#ifdef CONFIG_CFI_CLANG + if ((esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == CFI_BRK_IMM) + return cfi_handler(regs, esr) != DBG_HOOK_HANDLED; #endif return bug_handler(regs, esr) != DBG_HOOK_HANDLED; } @@ -1070,6 +1124,9 @@ int __init early_brk64(unsigned long addr, unsigned int esr, void __init trap_init(void) { register_kernel_break_hook(&bug_break_hook); +#ifdef CONFIG_CFI_CLANG + register_kernel_break_hook(&cfi_break_hook); +#endif register_kernel_break_hook(&fault_break_hook); #ifdef CONFIG_KASAN_SW_TAGS register_kernel_break_hook(&kasan_break_hook); -- 2.36.0.464.gb9c8b46e94-goog
WARNING: multiple messages have this Message-ID (diff)
From: Sami Tolvanen <samitolvanen@google.com> To: linux-kernel@vger.kernel.org Cc: Kees Cook <keescook@chromium.org>, Josh Poimboeuf <jpoimboe@redhat.com>, Peter Zijlstra <peterz@infradead.org>, x86@kernel.org, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Nathan Chancellor <nathan@kernel.org>, Nick Desaulniers <ndesaulniers@google.com>, Joao Moreira <joao@overdrivepizza.com>, Sedat Dilek <sedat.dilek@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, linux-hardening@vger.kernel.org, linux-arm-kernel@lists.infradead.org, llvm@lists.linux.dev, Sami Tolvanen <samitolvanen@google.com> Subject: [RFC PATCH 09/21] arm64: Add CFI error handling Date: Fri, 29 Apr 2022 13:36:32 -0700 [thread overview] Message-ID: <20220429203644.2868448-10-samitolvanen@google.com> (raw) In-Reply-To: <20220429203644.2868448-1-samitolvanen@google.com> With -fsanitize=kcfi, CFI always traps. Add arm64 support for handling CFI failures and determining the target address. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> --- arch/arm64/include/asm/brk-imm.h | 2 ++ arch/arm64/include/asm/insn.h | 1 + arch/arm64/kernel/traps.c | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h index ec7720dbe2c8..3a50b70b4404 100644 --- a/arch/arm64/include/asm/brk-imm.h +++ b/arch/arm64/include/asm/brk-imm.h @@ -16,6 +16,7 @@ * 0x400: for dynamic BRK instruction * 0x401: for compile time BRK instruction * 0x800: kernel-mode BUG() and WARN() traps + * 0x801: Control-Flow Integrity traps * 0x9xx: tag-based KASAN trap (allowed values 0x900 - 0x9ff) */ #define KPROBES_BRK_IMM 0x004 @@ -25,6 +26,7 @@ #define KGDB_DYN_DBG_BRK_IMM 0x400 #define KGDB_COMPILED_DBG_BRK_IMM 0x401 #define BUG_BRK_IMM 0x800 +#define CFI_BRK_IMM 0x801 #define KASAN_BRK_IMM 0x900 #define KASAN_BRK_MASK 0x0ff diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 1e5760d567ae..12225bdfa776 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -334,6 +334,7 @@ __AARCH64_INSN_FUNCS(store_pre, 0x3FE00C00, 0x38000C00) __AARCH64_INSN_FUNCS(load_pre, 0x3FE00C00, 0x38400C00) __AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400) __AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400) +__AARCH64_INSN_FUNCS(ldur, 0x3FE00C00, 0x38400000) __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000) __AARCH64_INSN_FUNCS(ldclr, 0x3F20FC00, 0x38201000) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 0529fd57567e..b524411ba663 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -26,6 +26,7 @@ #include <linux/syscalls.h> #include <linux/mm_types.h> #include <linux/kasan.h> +#include <linux/cfi.h> #include <asm/atomic.h> #include <asm/bug.h> @@ -990,6 +991,55 @@ static struct break_hook bug_break_hook = { .imm = BUG_BRK_IMM, }; +#ifdef CONFIG_CFI_CLANG +void *arch_get_cfi_target(unsigned long addr, struct pt_regs *regs) +{ + /* The expected CFI check instruction sequence: + * ldur wA, [xN, #-4] + * movk wB, #nnnnn + * movk wB, #nnnnn, lsl #16 + * cmp wA, wB + * b.eq .Ltmp1 + * brk #0x801 ; <- addr + * .Ltmp1: + * + * Therefore, the target address is in the xN register, which we can + * decode from the ldur instruction. + */ + u32 insn, rn; + void *p = (void *)(addr - 5 * AARCH64_INSN_SIZE); + + if (aarch64_insn_read(p, &insn) || !aarch64_insn_is_ldur(insn)) + return NULL; + + rn = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn); + return (void *)regs->regs[rn]; +} + +static int cfi_handler(struct pt_regs *regs, unsigned int esr) +{ + switch (report_cfi(regs->pc, regs)) { + case BUG_TRAP_TYPE_BUG: + die("Oops - CFI", regs, 0); + break; + + case BUG_TRAP_TYPE_WARN: + break; + + default: + return DBG_HOOK_ERROR; + } + + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); + return DBG_HOOK_HANDLED; +} + +static struct break_hook cfi_break_hook = { + .fn = cfi_handler, + .imm = CFI_BRK_IMM, +}; +#endif /* CONFIG_CFI_CLANG */ + static int reserved_fault_handler(struct pt_regs *regs, unsigned int esr) { pr_err("%s generated an invalid instruction at %pS!\n", @@ -1063,6 +1113,10 @@ int __init early_brk64(unsigned long addr, unsigned int esr, if ((comment & ~KASAN_BRK_MASK) == KASAN_BRK_IMM) return kasan_handler(regs, esr) != DBG_HOOK_HANDLED; +#endif +#ifdef CONFIG_CFI_CLANG + if ((esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == CFI_BRK_IMM) + return cfi_handler(regs, esr) != DBG_HOOK_HANDLED; #endif return bug_handler(regs, esr) != DBG_HOOK_HANDLED; } @@ -1070,6 +1124,9 @@ int __init early_brk64(unsigned long addr, unsigned int esr, void __init trap_init(void) { register_kernel_break_hook(&bug_break_hook); +#ifdef CONFIG_CFI_CLANG + register_kernel_break_hook(&cfi_break_hook); +#endif register_kernel_break_hook(&fault_break_hook); #ifdef CONFIG_KASAN_SW_TAGS register_kernel_break_hook(&kasan_break_hook); -- 2.36.0.464.gb9c8b46e94-goog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-04-29 20:37 UTC|newest] Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-04-29 20:36 [RFC PATCH 00/21] KCFI support Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 01/21] efi/libstub: Filter out CC_FLAGS_CFI Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 02/21] arm64/vdso: " Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 03/21] kallsyms: Ignore __kcfi_typeid_ Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 04/21] cfi: Remove CONFIG_CFI_CLANG_SHADOW Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 05/21] cfi: Drop __CFI_ADDRESSABLE Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 06/21] cfi: Switch to -fsanitize=kcfi Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-30 9:09 ` Peter Zijlstra 2022-04-30 9:09 ` Peter Zijlstra 2022-04-29 20:36 ` [RFC PATCH 07/21] cfi: Add type helper macros Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 08/21] arm64/crypto: Add types to indirect called assembly functions Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen [this message] 2022-04-29 20:36 ` [RFC PATCH 09/21] arm64: Add CFI error handling Sami Tolvanen 2022-05-05 15:44 ` Mark Rutland 2022-05-05 15:44 ` Mark Rutland 2022-05-05 16:23 ` Sami Tolvanen 2022-05-05 16:23 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 10/21] treewide: Drop function_nocfi Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-05-05 16:30 ` Mark Rutland 2022-05-05 16:30 ` Mark Rutland 2022-05-05 16:51 ` Sami Tolvanen 2022-05-05 16:51 ` Sami Tolvanen 2022-05-05 18:03 ` Mark Rutland 2022-05-05 18:03 ` Mark Rutland 2022-04-29 20:36 ` [RFC PATCH 11/21] treewide: Drop WARN_ON_FUNCTION_MISMATCH Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 12/21] treewide: Drop __cficanonical Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 13/21] cfi: Add the cfi_unchecked macro Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 14/21] treewide: static_call: Pass call arguments to the macro Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 23:21 ` Peter Zijlstra 2022-04-29 23:21 ` Peter Zijlstra 2022-04-30 0:49 ` Sami Tolvanen 2022-04-30 0:49 ` Sami Tolvanen 2022-05-02 7:46 ` Peter Zijlstra 2022-05-02 7:46 ` Peter Zijlstra 2022-04-29 20:36 ` [RFC PATCH 15/21] static_call: Use cfi_unchecked Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 23:23 ` Peter Zijlstra 2022-04-29 23:23 ` Peter Zijlstra 2022-04-29 20:36 ` [RFC PATCH 16/21] objtool: Add support for CONFIG_CFI_CLANG Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 23:30 ` Peter Zijlstra 2022-04-29 23:30 ` Peter Zijlstra 2022-04-30 1:00 ` Sami Tolvanen 2022-04-30 1:00 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 17/21] x86/tools/relocs: Ignore __kcfi_typeid_ relocations Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 18/21] x86: Add types to indirect called assembly functions Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 19/21] x86/purgatory: Disable CFI Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 20/21] x86/vdso: " Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-29 20:36 ` [RFC PATCH 21/21] x86: Add support for CONFIG_CFI_CLANG Sami Tolvanen 2022-04-29 20:36 ` Sami Tolvanen 2022-04-30 9:24 ` Peter Zijlstra 2022-04-30 9:24 ` Peter Zijlstra 2022-05-02 15:20 ` Sami Tolvanen 2022-05-02 15:20 ` Sami Tolvanen 2022-04-29 22:53 ` [RFC PATCH 00/21] KCFI support Kees Cook 2022-04-29 22:53 ` Kees Cook 2022-04-30 9:02 ` Peter Zijlstra 2022-04-30 9:02 ` Peter Zijlstra 2022-05-02 15:22 ` Sami Tolvanen 2022-05-02 15:22 ` Sami Tolvanen 2022-05-02 19:55 ` Peter Zijlstra 2022-05-02 19:55 ` Peter Zijlstra 2022-05-03 22:35 ` Peter Collingbourne 2022-05-03 22:35 ` Peter Collingbourne 2022-05-04 7:34 ` Peter Zijlstra 2022-05-04 7:34 ` Peter Zijlstra 2022-04-30 16:07 ` Kenton Groombridge 2022-04-30 16:07 ` Kenton Groombridge 2022-05-02 15:31 ` Sami Tolvanen 2022-05-02 15:31 ` Sami Tolvanen 2022-05-04 16:17 ` Mark Rutland 2022-05-04 16:17 ` Mark Rutland 2022-05-04 16:41 ` Sami Tolvanen 2022-05-04 16:41 ` Sami Tolvanen 2022-05-04 20:17 ` Sami Tolvanen 2022-05-04 20:17 ` Sami Tolvanen 2022-05-05 12:36 ` Mark Rutland 2022-05-05 12:36 ` Mark Rutland 2022-05-05 16:00 ` Sami Tolvanen 2022-05-05 16:00 ` Sami Tolvanen 2022-05-05 17:14 ` Mark Rutland 2022-05-05 17:14 ` Mark Rutland
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220429203644.2868448-10-samitolvanen@google.com \ --to=samitolvanen@google.com \ --cc=catalin.marinas@arm.com \ --cc=joao@overdrivepizza.com \ --cc=jpoimboe@redhat.com \ --cc=keescook@chromium.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-hardening@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=llvm@lists.linux.dev \ --cc=mark.rutland@arm.com \ --cc=nathan@kernel.org \ --cc=ndesaulniers@google.com \ --cc=peterz@infradead.org \ --cc=rostedt@goodmis.org \ --cc=sedat.dilek@gmail.com \ --cc=will@kernel.org \ --cc=x86@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.