From patchwork Fri Apr 29 20:36:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 12832771 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8424DC433F5 for ; Fri, 29 Apr 2022 20:44:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=QHpu8pgRLTUAFH+op7iY9sk1cA1GKbC7tstONonPjZ8=; b=SdMgNqgYTm7ZMldTLbUZNAUAjL PRT3l237RGa157uiVYdZIgdpQPjjPtwtm4+XRu3OFYin9SFyTHLQ4SXZ8c0cz88oKf/RQHTvcDLGd 88XpjRJPRxgKaEIffrU5dJczXO5h3qx7JcsYvOBeBZi5SA5MNrUhJ5El5+l3yMfg04Gh5t6z8wqCY tYgi5PHcEI1HeCdM+UGcZa7JhSDaMNlJkFozJE5G+EOMC3PWmleqP2YWoLWaR3MP6ofDeW17KS+fd 3gRkn8TeZFpqF6upNLHnlsMXh4I6E05gw5huBevvYdlskGO0IyTbfcJLb2fQaxLXDYP4d3gv7oyUw MlQPtoFw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nkXS1-00CZNz-0I; Fri, 29 Apr 2022 20:42:53 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nkXMV-00CXCT-3B for linux-arm-kernel@lists.infradead.org; Fri, 29 Apr 2022 20:37:14 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id z15-20020a25bb0f000000b00613388c7d99so8398783ybg.8 for ; Fri, 29 Apr 2022 13:37:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=5hCa0Th+W5/EJvbV2Mxb+ItoW5xxwAS7kF6LUvID5mc=; b=S0N+CrTDZPvcK92q2enU+oVhR8rVjO0uZ5+G+H/+XSr0HLDhtVQlnf3XdP2RpmbQTB qxib2RNe+lgYyVAC/K4UeXT5QGc0R00zizFDHp3tWHZqzalRZrtj6xsSrA36fRYOAmHY RnJyYZqHEruYZOOBGjwd/Go7AWOCMlZ5QMLRILy3Ev8qGB/6Y0qYjhU14rV+0nU/g/sH M3hWk+95HJeec8dFyf5hxRyv7r+cCx02MHG30C9DdAWXmaBjn4GAy2+GpXeVpkmkD2hV Yi/dbME+Gg3iSIXmapnP/Ol0jDRfngnUdvKw1FSR5l6MFtv3fNCo0nEc7aXEBh0Hu06o 3vtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=5hCa0Th+W5/EJvbV2Mxb+ItoW5xxwAS7kF6LUvID5mc=; b=PtdmD2NG3/02hzr2rGTiJT9sXsi54HpRitwWbD4tk0sgyXP6jq1HT4DHvt1MdghvSa 0hdYJkjklWMXatK6Q3KTfOVJ0IFtf2A441/9BxW0VnFUCo2Tt6dii8Dem0Yy7qnYRVzX ooTg697L7d922BPxxBfkB+XZuHm/0lUSoMpIT7V1qAAeHPXW+o6bGHhn1DmK+Be8w0D1 +n4En1SLVqqtMi2uHqbhsptTsydW2xTe6yewWH02uC6dyOJ1rj/ePzcyVkxFeh5eMFQR AaApsGlTio8J1rw6bUlSFQArtOy0TA3gHYrJTrk/dM1thUa4+ga1uHiFrvBhQaylzlyV Dqqg== X-Gm-Message-State: AOAM532Nc2tXxBMd88ywp74ya54LIFVxuAK1tOdDBeJGOwnCSk5Xg74k 2pSLKCS/IQcgS80uWeSgrhmEOsepRvaKov+zpxs= X-Google-Smtp-Source: ABdhPJz+eDKnS2W33vUCyhR6WhYeLBeYAFhDRUfMiHJY50CUszLf61iMmFxt93d2j2RTvlyfCCPtlhqeWBFFGoC3YyE= X-Received: from samitolvanen1.mtv.corp.google.com ([2620:15c:201:2:351:bea9:f158:1021]) (user=samitolvanen job=sendgmr) by 2002:a25:9d12:0:b0:63e:5463:9161 with SMTP id i18-20020a259d12000000b0063e54639161mr1245278ybp.520.1651264629191; Fri, 29 Apr 2022 13:37:09 -0700 (PDT) Date: Fri, 29 Apr 2022 13:36:32 -0700 In-Reply-To: <20220429203644.2868448-1-samitolvanen@google.com> Message-Id: <20220429203644.2868448-10-samitolvanen@google.com> Mime-Version: 1.0 References: <20220429203644.2868448-1-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4436; h=from:subject; bh=NE+VmE0GV2F5TAg2wjWn2y0FVE5ul0MCwcRd3JvOCxM=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBibExWtMuY47WbpGwUnz3/EYOP7dO1dD9ixSIlsYG3 x8Cd/pyJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCYmxMVgAKCRBMtfaEi7xW7rmmC/ 9YbnECwIsbp/HZ5mIfeFER1Ea+SidGBDwevjph92DWZRHHBk+vWKzcN4tx2RqzfmU/WvZ50K3w9BCw qwWWAs9udhv1ocs1hOPeO12RlgvSuSTw8kYQIJIrepC1qXFD3lUUl8yDxipO/T4mSTysgs5AReakBS Yt32fnxwnduGRpVjea7S6gSqDnZtoVDV7jrcJgyIG1SlDlZPKsIpn9+nE4fpaDVKsDQq5NGKa8UJKk 3qfqREIt7aV262NXiQxLF1qGmNffIZgOSyxdY6tQWT9vrXbBCub2HgKUx+u2DEQHrveMTyg8Y8YT7+ 8Pms4AMGpH2I11QDsLNutbwe5QI70n3ytnK5J+apZiYU0Cv3lKxDt2Odxl623Ly+CVShBd2zIsafj2 j14rVS/5d6DaDtTs5ckt62TAIZzmhvcZkyF+MULQnjhDQGhteaK9K5BCp74kSh0K92dYKMf4D44gK9 4J75YA3echFB0WWw7aq3WXfsP+NT7W6VM6M20yqGC2sIA= X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [RFC PATCH 09/21] arm64: Add CFI error handling From: Sami Tolvanen To: linux-kernel@vger.kernel.org Cc: Kees Cook , Josh Poimboeuf , Peter Zijlstra , x86@kernel.org, Catalin Marinas , Will Deacon , Mark Rutland , Nathan Chancellor , Nick Desaulniers , Joao Moreira , Sedat Dilek , Steven Rostedt , linux-hardening@vger.kernel.org, linux-arm-kernel@lists.infradead.org, llvm@lists.linux.dev, Sami Tolvanen X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220429_133711_211599_911486DC X-CRM114-Status: GOOD ( 16.70 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org With -fsanitize=kcfi, CFI always traps. Add arm64 support for handling CFI failures and determining the target address. Signed-off-by: Sami Tolvanen --- 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 #include #include +#include #include #include @@ -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);