From patchwork Sun Oct 17 13:17:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 12564311 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 E63E0C433EF for ; Sun, 17 Oct 2021 13:19:34 +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 AF00361260 for ; Sun, 17 Oct 2021 13:19:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org AF00361260 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=JWsCHU84BiyrQt g+yWn3U6gzGbybpcfToJVHyQSCAtfGs2AAzwnmnhWIUsOXmT6fPbefRwqyiJjg6lcsW06PTfTsCV+ PsMtWoJNwKDDBe5eX5bx6U8Ic1KEinVg1MmznKv+/dvo1rLm9CuUkMKJj3ZuDnh6evMSsrLbfEgPM 09ne+vF5jtJzB4S6DdR9O0xAKlUpwOv6hiiOJWwCpgyd3ppVFgCVCiICszwYEWRPKIZ7bMACKf+Uh /w2AhymxMxJ5x2bc5t2PO0JtCOQMM9YpgDulq1M5vrDYnYIreoMEx02goxfoIEWFRg5ppGNuUxmRs ajBjjfOl9GmOqoogpuDA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mc63S-00Calx-EN; Sun, 17 Oct 2021 13:18:22 +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 1mc62p-00CabS-EF for linux-arm-kernel@lists.infradead.org; Sun, 17 Oct 2021 13:17:44 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id F1FCC61260; Sun, 17 Oct 2021 13:17:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634476662; bh=UNhsqFF6lWxejQQEY2CUNtek34KtXIXbhy6vPpJObyg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fT/LE4XZrcqadEgenzJ4ggtWviRh0/zyFluRaffGDPgYfXsdigkmiGPG7bw43b+Cp 2S2Wt7LAmn67ghXOOCLQa7o5mRbRy/q6+Ou0ZkKJO3asc/0R4+8fqZ/mQ7SLd/0DgE OnBZwaDAy1z9sUG7JUNnhRg0Qk5RL1mW881zOrVN/GzcisOZTpTYc2cuCV+oOtYDx4 V+8so7JOeTma44BBiwsqm58qLwS/viPpxGs//3/twy0tcPh/G9iAnMR+VGTluFWZkI rA3rpdBXNP6Tpm7ScKGeX3bQCKP40hK12BqOIBrm5gTczuwnU/4nlnTCz6oqFjR8a6 gPI3PYjGBrt6A== 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 v3 04/10] ARM: unwind: support unwinding across multiple stacks Date: Sun, 17 Oct 2021 15:17:17 +0200 Message-Id: <20211017131723.4034662-5-ardb@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211017131723.4034662-1-ardb@kernel.org> References: <20211017131723.4034662-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/pANAwAKAcNPIjmS2Y8kAcsmYgBhbCJWTRKtkpo7eMVQFzOjsKyA+STe3jLh999ziPTo 7ayb8YqJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYWwiVgAKCRDDTyI5ktmPJM4RC/ 0dA0ryKZREjyXsg1alQHsfFLbdSis+/gYonnDVQd1WkUS4BQbFe9D6SgPE8cUcZwhnIgbCNl6bcJgs n/2jfQ18H2/yTKuQSd+FlJ0H9RHPsLsmk7xJyPlEyKiH6wHx+oTk7Ouw5xaToXOrkxe0Zro2vgshVW +0JtvTtFWAeYf+2htvqVUBIHUic8HK7RcIDMpI1dfb5A0Ae4ILa0zPtOURUIF5SIoBIiBpAupHaqO6 x5+YgIRtCJSy5FIm/oesAIT1Yi1+GQnyIOmS6xghDk1EsjTp+ZOwkapvBLvnT61jV1jq8FSe9mxw8R UOI4pJUAoqmPxgl9qY2g28yblx2RBWNY6XD6TiTq9XMj0K3dbwHK36Zn/G++vYbKgz/0E2jGVH/Dtr 1OgttNdLnni2r2lVfKx5WubcQJMWlangP9+9z0pLdEU9GOEYtjkuM2/JgBOZb3A5ZVqt0uiUEMqZL9 84Q2JgUdhu30YzomVthrBal3RRaPmZsaRFXqTfJlkqDQY= 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-20211017_061743_548859_E5F9D927 X-CRM114-Status: GOOD ( 19.29 ) 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 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; }