From patchwork Tue Dec 13 14:28:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 13072123 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 5249EC4332F for ; Tue, 13 Dec 2022 14:30:29 +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:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=TA78kdq3TsxWGZkTsQSy1KrqKKh8BUJ1SLGjR8ptgCA=; b=WEnSjUJt/PE7jL E7yFzFWjzcd7EN2t82tcxI4xviy0YIEyXmbJIyyUBPtb5bCiMH2mW9Trf3dkAXD/25Bqrnr8GLvdI 1Nnh8dcoxi68FbTqHVv7u9/8eg32uoC3YA72IAdRNtWYNp5CpFAoq/GL5/kL3hKL1aACTxPebKcHa ZX10oR1CcIen3PO0fZmPJKT7fW+/oFiwe+BWsMNU0DfIXtYIptxW3KXBaL0T2tBs6z1kIERdmEh8i UdQKJSd+B01r0aczrqQs+9N3LmwpMcmSTSowoSazdQM62mCg+7fklz/mU/Vg/pbamErafOuNFK5f3 lAJ94YONAic1i8riA1rg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1p56Ha-001ACY-0q; Tue, 13 Dec 2022 14:29:22 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1p56HQ-001AAn-7J for linux-arm-kernel@lists.infradead.org; Tue, 13 Dec 2022 14:29:13 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 69C9461558; Tue, 13 Dec 2022 14:29:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2550FC433EF; Tue, 13 Dec 2022 14:29:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1670941750; bh=aeDNXWkDZWAT/1qBdkHJXQaD/WN1kfbigN9xWAElqhM=; h=From:To:Cc:Subject:Date:From; b=CYmp9g7GJl7urpSLJBZor2oEjXMqu1pvNLhLfKy2SyRG6jV4/oq7iGxEe7LXJSqzh MPyZWKcJwn6aRODkvpdlP/CTZhppCDd/bjY5dMV1gi51fMnxymzJV4CJXB4cuwnaeN euCUBXOn75B0f/zM+XGMi5LmG0z1XzWHAuFpq4x30D2mgs5GeMXJwthySTLSHIc1N0 V+cPbpnY+y0isI2BR+kICjxuenTYZxzuwCrEZHKeSIjELEr7A/ogT3aaH8Gos/TcfD BbLm4wL8ymqb9BF4Yxhh1JBrvPNTH339n2LXAg8RX8hi98pxrP4OqrGfVJakR355TL a1BVJzGexlCGw== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: will@kernel.org, mark.rutland@arm.com, samitolvanen@google.com, keescook@chromium.org, torvalds@linux-foundation.org, Ard Biesheuvel Subject: [PATCH] arm64: Apply dynamic shadow call stack patching in two passes Date: Tue, 13 Dec 2022 15:28:49 +0100 Message-Id: <20221213142849.1629026-1-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2474; i=ardb@kernel.org; h=from:subject; bh=aeDNXWkDZWAT/1qBdkHJXQaD/WN1kfbigN9xWAElqhM=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjmIwgI+YdvyTyaJ/NmVaKGwfJHaSCwj+5/aMDbV4G GCzSZmKJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY5iMIAAKCRDDTyI5ktmPJPyGC/ 9ySoNQjwO1ayoLHDqP/Hbzrjis+CvsTg7wQcEewY4NRiBHGuAFvdqjqIFYINQaWguJitGYQ/l0mfVE k6NDV7Cfv2grPI4vKo+WmglyY8zdKCor5sOdH2Q31EpArQiCg+bFe4Z6Rp/A96E7pIhf3pdM4W0iGa TYF/O3Dhh8k39CVOCsr661lSe4LXIbUx7KA5KOKYHTjyf1uaODpuZ9hAW+1j8qBmFYlIuHMDLbN8Wo hmIV286fuLBuIvro4JgfUqR5y+iJIQ4N9Xah3Jvr7vaFrdHgu04xuD3rqmLEYD3SJe2tUSeMYTb2g7 B0pAyXujHj0rNCW6wocTzDyTdqOso/NNVkvOlPcm2MvUnVtWLJoI8Iqp6zA8or++pCPJ/QElmL6OmW YZoZY52XyQX/MTiNo9vY15zf90NOdd2lhhYyI9yvpxFoD/u+aOH8wjBCr68wArUoXfxEUVFJv7ZwJO xucHDN/HbOBVBtyAOuxqDW6Ct2bq4k5UcP0LifLUNSoSo= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221213_062912_364085_9E85B5EF X-CRM114-Status: GOOD ( 16.02 ) 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 Code patching for the dynamically enabled shadow call stack comes down to finding PACIASP and AUTIASP instructions -which behave as NOPs on cores that do not implement pointer authentication- and converting them into shadow call stack pushes and pops, respectively. Due to past bad experiences with the highly complex and overengineered DWARF standard that describes the unwind metadata that we are using to locate these instructions, let's make this patching logic a little bit more robust so that any issues with the unwind metadata detected at boot time can de dealt with gracefully. The DWARF annotations that are used for this are emitted at function granularity, and due to the fact that the instructions we are patching will simply behave as NOPs if left unpatched, we can abort on errors as long as we don't leave any functions in a half-patched state. So do a dry run of each FDE frame (covering a single function) before performing the actual patching, and give up if the DWARF metadata cannot be understood. Signed-off-by: Ard Biesheuvel Reviewed-by: Sami Tolvanen Acked-by: Will Deacon --- arch/arm64/kernel/patch-scs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/patch-scs.c b/arch/arm64/kernel/patch-scs.c index 1b3da02d5b741bc3..a1fe4b4ff5917670 100644 --- a/arch/arm64/kernel/patch-scs.c +++ b/arch/arm64/kernel/patch-scs.c @@ -130,7 +130,8 @@ struct eh_frame { static int noinstr scs_handle_fde_frame(const struct eh_frame *frame, bool fde_has_augmentation_data, - int code_alignment_factor) + int code_alignment_factor, + bool dry_run) { int size = frame->size - offsetof(struct eh_frame, opcodes) + 4; u64 loc = (u64)offset_to_ptr(&frame->initial_loc); @@ -184,7 +185,8 @@ static int noinstr scs_handle_fde_frame(const struct eh_frame *frame, break; case DW_CFA_negate_ra_state: - scs_patch_loc(loc - 4); + if (!dry_run) + scs_patch_loc(loc - 4); break; case 0x40 ... 0x7f: @@ -235,9 +237,12 @@ int noinstr scs_patch(const u8 eh_frame[], int size) } else { ret = scs_handle_fde_frame(frame, fde_has_augmentation_data, - code_alignment_factor); + code_alignment_factor, + true); if (ret) return ret; + scs_handle_fde_frame(frame, fde_has_augmentation_data, + code_alignment_factor, false); } p += sizeof(frame->size) + frame->size;