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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F5C4C433EF for ; Mon, 15 Nov 2021 08:49:43 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 20ED160273 for ; Mon, 15 Nov 2021 08:49:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 20ED160273 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org 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:References:In-Reply-To: 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: List-Owner; bh=By6uoqQ9oPlGu9eD6CCI2M7gMhHbSXKicZ7ZfUZXgEQ=; b=18Lt0X3vOWiPwk BYxj74L0gGjRIrS6oawcwp1hEwouq8Ac+tUiN1rrpsbxEV6VCVhiGSBUy0R8xKDbdCj4MK4rROSMT gvXJyeDEX62KRIKTF92IMNGIRTy+W4QWI6sXfHsuH3WsGYt0tY0wxjzJ+UKtdCAJY3aV/VmQ2pLjM UuTARe6ygq6fKRDl//on1aXgxMsSb+8owlVzjAO7u9+RhAOxYtY72SB3Of1gi4Kj5XU9SBS2mC5Bk V3e52eKCt9k0y6K11rvpz+hKpOzQPq+lrvThS7xtAXIDJxQq757vbX8jqbEOFW8rn6KfuEZng6QPE 1Pzvv7IARsh7PvxcQ4Bw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mmXf1-00EjFb-Of; Mon, 15 Nov 2021 08:48:19 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mmXeV-00Ej65-CM for linux-arm-kernel@lists.infradead.org; Mon, 15 Nov 2021 08:47:48 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 262E560273; Mon, 15 Nov 2021 08:47:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1636966067; bh=UNhsqFF6lWxejQQEY2CUNtek34KtXIXbhy6vPpJObyg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=neUkZVKGbbpH6UeeR1t6SNT7uPm+K/y2ZIcka/r8vleR20z2irT1J+YnqXf3A6GBr HxCGvfJXSKlHanf9nejSke3DFaW1rT+fQc1L1L9Nqaq8leI/cW6u8u/D/+WIOETDaf rnvyF8BCiNDEuekj3q7pRi/l0WlaKoGS29qWr6Swls5wQCmRQouZcz66Uk+2O7KMDN MrNPgCJEIuCCgnJeylbp/odYE5e+i1dV6fVW61AhKRDT068MPvZMOOe5GbxBGrS1af bRc6zrxJG/wgTD0nZ06PhEZ7cNqmhMWvexdAARMeggkwWNIMguHtySEUbySLupp0yM oWmWdaBWU+L8A== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Russell King , Arnd Bergmann , Kees Cook , Keith Packard , Linus Walleij , Nick Desaulniers , Nicolas Pitre Subject: [PATCH v4 3/9] ARM: unwind: support unwinding across multiple stacks Date: Mon, 15 Nov 2021 09:47:26 +0100 Message-Id: <20211115084732.3704393-4-ardb@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211115084732.3704393-1-ardb@kernel.org> References: <20211115084732.3704393-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3497; h=from:subject; bh=UNhsqFF6lWxejQQEY2CUNtek34KtXIXbhy6vPpJObyg=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBhkh6YTRKtkpo7eMVQFzOjsKyA+STe3jLh999ziPTo 7ayb8YqJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYZIemAAKCRDDTyI5ktmPJHFRC/ 4zkIp6s0xEiV/CqqGR3zvqGrfDR6BkRzujsgaRSaioTlocraOPTVSI2KQAFRcuFwe8KUzkWFWWXV0y RrIsCN9C3myWQ7SEMBPHf76fNIhRPHl6gDppNlgzBgPsedcT3woPAnKlQ9/88CUsWIFjbOFHD4ltLH NzKmcx8ERw3JrjE7l4SA399S2jTJlyVAolMkMkepOSX1Bxw0jpFPLHobyeqQKhA2hRtls0WDKEDI+K clyMp5xyCFDKERe9cwXjI1zL9XBDlG9ZnFwNdhD3MPQIHBKJATefJYYbcpyO7No6EIVtUbdZAwf0V2 Gwt4NfydcTZP4SSmTuWx3o/zxfdPf4fp3n7/6OjFCynXidZ2u7XN2ElLwjPuSMWuBxXSgj2nPXmjjG oqkpHBtc/KoXctNSmHS3bZQXtrpufd5OE0TJZzhuqGf30e+JSPxgKZ2xg8Lb4CwqxfnPoKg5eEW++f Ae8vFXOQqJGOEa83neAo4a1XFVE8b6l8dy/8i14EI3rLI= 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-20211115_004747_476105_2E8B4D03 X-CRM114-Status: GOOD ( 19.99 ) 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: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Implement support in the unwinder for dealing with multiple stacks. This will be needed once we add support for IRQ stacks, or for the overflow stack used by the vmap'ed stacks code. This involves tracking the unwind opcodes that either update the virtual stack pointer from another virtual register, or perform an explicit subtract on the virtual stack pointer, and updating the low and high bounds that we use to sanitize the stack pointer accordingly. Signed-off-by: Ard Biesheuvel Reviewed-by: Arnd Bergmann Acked-by: Linus Walleij Tested-by: Keith Packard --- arch/arm/kernel/unwind.c | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index 59fdf257bf8b..9cb9af3fc433 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -52,6 +52,7 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2); struct unwind_ctrl_block { unsigned long vrs[16]; /* virtual register set */ const unsigned long *insn; /* pointer to the current instructions word */ + unsigned long sp_low; /* lowest value of sp allowed */ unsigned long sp_high; /* highest value of sp allowed */ /* * 1 : check for stack overflow for each register pop. @@ -256,8 +257,12 @@ static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl, mask >>= 1; reg++; } - if (!load_sp) + if (!load_sp) { ctrl->vrs[SP] = (unsigned long)vsp; + } else { + ctrl->sp_low = ctrl->vrs[SP]; + ctrl->sp_high = ALIGN(ctrl->sp_low, THREAD_SIZE); + } return URC_OK; } @@ -313,9 +318,10 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) if ((insn & 0xc0) == 0x00) ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4; - else if ((insn & 0xc0) == 0x40) + else if ((insn & 0xc0) == 0x40) { ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4; - else if ((insn & 0xf0) == 0x80) { + ctrl->sp_low = ctrl->vrs[SP]; + } else if ((insn & 0xf0) == 0x80) { unsigned long mask; insn = (insn << 8) | unwind_get_byte(ctrl); @@ -330,9 +336,11 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) if (ret) goto error; } else if ((insn & 0xf0) == 0x90 && - (insn & 0x0d) != 0x0d) + (insn & 0x0d) != 0x0d) { ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f]; - else if ((insn & 0xf0) == 0xa0) { + ctrl->sp_low = ctrl->vrs[SP]; + ctrl->sp_high = ALIGN(ctrl->sp_low, THREAD_SIZE); + } else if ((insn & 0xf0) == 0xa0) { ret = unwind_exec_pop_r4_to_rN(ctrl, insn); if (ret) goto error; @@ -375,13 +383,12 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl) */ int unwind_frame(struct stackframe *frame) { - unsigned long low; const struct unwind_idx *idx; struct unwind_ctrl_block ctrl; /* store the highest address on the stack to avoid crossing it*/ - low = frame->sp; - ctrl.sp_high = ALIGN(low, THREAD_SIZE); + ctrl.sp_low = frame->sp; + ctrl.sp_high = ALIGN(ctrl.sp_low, THREAD_SIZE); pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, frame->pc, frame->lr, frame->sp); @@ -437,7 +444,7 @@ int unwind_frame(struct stackframe *frame) urc = unwind_exec_insn(&ctrl); if (urc < 0) return urc; - if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high) + if (ctrl.vrs[SP] < ctrl.sp_low || ctrl.vrs[SP] > ctrl.sp_high) return -URC_FAILURE; } -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel