From mboxrd@z Thu Jan 1 00:00:00 1970 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 D4F34C433F5 for ; Mon, 22 Nov 2021 09:54:36 +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: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=8PxJMuzVDh2Db7k+kZ1Yg3ulTHqExrf8MPqljA8uqG8=; b=Ddkgu52Uf4rrXz lM7nkBDA2ke+wNXEBgVNOnk0zMHijb44kbNxTMHytkZn452Gq/y2jSGRKoYUX+OeK+L2veb5mS/6R FFgvni9wrxJKKHcVclOp/WOBXO0PzHQcYeaW9671yWgVadLvxsHfKynkCzF/9Za+eLj43m2PaoENB 2D2mkOqgQaqxSfdl3eixnia92xEoJRRC2P4i6LO/tur4F3Rw2kOqBl40tpAw6XxWHm2tl+1K3Df/g n4B/APoLunm1T5+RoeRK/uXlxfDiAXxKXRWaGx0tbqWCpDrG7IAUJVADBbJZ70Fgwjy5Yjm66amFn 1QXq8YCUN89d33G7wYYA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mp5zv-00FhIz-Es; Mon, 22 Nov 2021 09:52:28 +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 1mp5cr-00FaQk-0i for linux-arm-kernel@lists.infradead.org; Mon, 22 Nov 2021 09:28:42 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4896860E08; Mon, 22 Nov 2021 09:28:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1637573316; bh=G8bl/jS0UF4ofWVfxX1cIJJ06WAI6ETjTnMacIEZcB4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hjD1lCk1EWBlCkIT2hNj6MKQ4ExEBpbntUKgrmyZop9ZOttsXAljBpOqDjDgOdRmR hq64vXusGB/PY54ddmTbReswGW50GJ+mKOoToFs9AYB+knaM+1FBSwCRbR14rgjKJ6 Mi0xVgUZy4rNR12IEnaxgTujodl5aBxYqcoPuMGjcwsddQSsawac/gOrg0Lig4mDJB 6KdkO3iyzuaaCtbEL4J7yIcdEWxZOOlYspgUuMQ19S4aMn0PCnwYcWBrFaFpzrFGQn 3sl5cCB9rEcxNQ4xO+4eRty3xaotWss8VBVPr6A2Ck13hApGOZd3jfyQB0O+A6DPGj ZEt+r6pfNOE9Q== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Russell King , Nicolas Pitre , Arnd Bergmann , Kees Cook , Keith Packard , Linus Walleij , Nick Desaulniers , Tony Lindgren Subject: [PATCH v4 4/7] ARM: unwind: disregard unwind info before stack frame is set up Date: Mon, 22 Nov 2021 10:28:13 +0100 Message-Id: <20211122092816.2865873-5-ardb@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211122092816.2865873-1-ardb@kernel.org> References: <20211122092816.2865873-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2389; h=from:subject; bh=G8bl/jS0UF4ofWVfxX1cIJJ06WAI6ETjTnMacIEZcB4=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBhm2KquEi30aIbAnRchjXXGvZ89mMKIIQd149EMa+6 bmr6GyKJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYZtiqgAKCRDDTyI5ktmPJME+DA C2oVtGODUtUkxDTRnMXBEDMDH4uqGNOJzX4twdcYpfa2vFTUlJZMP7yItMjpERTrpfIvcIgBxhtKcA 5kDpP9CSOVPBn2KqJxsuGuF4fwd0nVwUUZKgPUlvZu0cpWfHsplwQtk7UrWZtA0Flke6FmgVmDJnDk 5j3tWJFJPK3AvtDj1gyMCe+EYbWeNFtdWHnNNDGkzpefNRKn+tLpBdHYJe7Xs6EMYruoBERQrddiwa tNXIWIoY7GnqbzrPIhHejY7EuFUab9UClZ/ipSTxF3D1jiNao1AmpaHBRqwkV4cteJdOI2h3Y6oLAL C8rHGRsEnUG2eeF6+Bts9R6P/Ht+MTVYUD/RgDE+2ENEZOX1FOuKQOYepFG3aMyt4c3ZWCALejYq2p 2lXpcHed2qqKvUiK6+/yWDiDbwR4RjHlhKfq/MxNOB/OdTuSrvKCfP9N2fEIEK5/069loVGCt/0/py 2SUgKpJ5jXzluF/tKnBxJJgQIstn1CgdaqF3jNcXfjS5c= 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-20211122_012837_147724_CAA436F7 X-CRM114-Status: GOOD ( 18.86 ) 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 When unwinding the stack from a stack overflow, we are likely to start from a stack push instruction, given that this is the most common way to grow the stack for compiler emitted code. This push instruction rarely appears anywhere else than at offset 0x0 of the function, and if it doesn't, the compiler tends to split up the unwind annotations, given that the stack frame layout is apparently not the same throughout the function. This means that, in the general case, if the frame's PC points at the first instruction covered by a certain unwind entry, there is no way the stack frame that the unwind entry describes could have been created yet, and so we are still on the stack frame of the caller in that case. So treat this as a special case, and return with the new PC taken from the frame's LR, without applying the unwind transformations to the virtual register set. This permits us to unwind the call stack on stack overflow when the overflow was caused by a stack push on function entry. Signed-off-by: Ard Biesheuvel Tested-by: Keith Packard --- arch/arm/kernel/unwind.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index b7a6141c342f..e8d729975f12 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -411,7 +411,21 @@ int unwind_frame(struct stackframe *frame) if (idx->insn == 1) /* can't unwind */ return -URC_FAILURE; - else if ((idx->insn & 0x80000000) == 0) + else if (frame->pc == prel31_to_addr(&idx->addr_offset)) { + /* + * Unwinding is tricky when we're halfway through the prologue, + * since the stack frame that the unwinder expects may not be + * fully set up yet. However, one thing we do know for sure is + * that if we are unwinding from the very first instruction of + * a function, we are still effectively in the stack frame of + * the caller, and the unwind info has no relevance yet. + */ + if (frame->pc == frame->lr) + return -URC_FAILURE; + frame->sp_low = frame->sp; + frame->pc = frame->lr; + return URC_OK; + } else if ((idx->insn & 0x80000000) == 0) /* prel31 to the unwind table */ ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); else if ((idx->insn & 0xff000000) == 0x80000000) -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel