From nobody Fri Jun 12 14:33:26 2026 Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC0A23A6B68 for ; Thu, 14 May 2026 10:07:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778753256; cv=none; b=uofI/F0JZPQ443CYvj2oLeQ74OnKB92efXPDX1J9UjOV4zrsKn07g8Z0OEwCU/Ekc56lSj8UGIA5p1C8dYEnWQRYT+OMwoLiWlEeNiOsZgFl2MW94j8L3thFnw253htPfmFV06reSK037P/KT2CqiKkoSwOdO26GbDu1YuCcFFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778753256; c=relaxed/simple; bh=ogp149ju9lFVsb+MBnSXY8OnhcH0qSOjYu21pK89kYY=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=Ae88AzdBQrI0UIWN2CicM8K1eDXWBPbnzdH1SqydCd+OIbmmVZHpZsxFY6Qq+Le+cuzLtJmYUbrQy5GTOYwdtvQwPlaqYEivEQTtIiimmsnsMlNOLl9zJc/L9ykKmbA6JV3R5MVQIgntUgNnnMvdlj16uiCTTBw51Xz3kMR4m00= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from fric.. (unknown [36.110.52.2]) by APP-01 (Coremail) with SMTP id qwCowACXQm7XngVqRHA0EA--.11494S2; Thu, 14 May 2026 18:07:20 +0800 (CST) From: Jiakai Xu To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Cc: Albert Ou , Alexandre Ghiti , Chunyan Zhang , Jiakai Xu , Matthew Bystrin , Palmer Dabbelt , Paul Walmsley , Samuel Holland Subject: [PATCH] riscv: stacktrace: fix stack-out-of-bounds in walk_stackframe Date: Thu, 14 May 2026 10:07:11 +0000 Message-Id: <20260514100711.838895-1-xujiakai2025@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qwCowACXQm7XngVqRHA0EA--.11494S2 X-Coremail-Antispam: 1UD129KBjvJXoW7ZF47Gr4UKw1kuryUAw47Jwb_yoW5JF4rpF Zak3Zrtr47G3y293sxAr18ury5Jrs3W3yUKFZxtw15J3W7GFyYvryqqa45Zr1Yyryvqa42 kFyjyw4DCan0vaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBY14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s 0DM2vYz4IE04k24VAvwVAKI4IrM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI 64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVW8JVWxJw Am72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAG YxC7M4IIrI8v6xkF7I0E8cxan2IY04v7MxkF7I0En4kS14v26r1q6r43MxAIw28IcxkI7V AKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCj r7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6x IIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x 0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VUjEoGDUUUUU== X-CM-SenderInfo: 50xmxthndljiysv6x2xfdvhtffof0/1tbiBg0HCWoFh+JXSAAAsQ Content-Type: text/plain; charset="utf-8" The fp_is_valid() function uses ALIGN(sp, THREAD_SIZE) as the upper bound for the frame pointer check. This bound is calculated relative to the current sp and shifts upward when sp itself exceeds the valid stack region, allowing the unwinder to read past the end of the allocated task stack and triggering KASAN stack-out-of-bounds. Fix this by using the absolute task stack boundary (task_stack_page(task) + THREAD_SIZE) instead. This ensures that once the frame pointer walks past the actual end of the stack, the check consistently fails and the unwinding terminates. Note that the frame pointer unwinder has no mechanism to detect when the unwind has crossed from the task stack onto a different kernel stack (e.g., IRQ stack). Using the absolute task stack boundary provides correct protection against out-of-bounds reads at the end of the task stack. Fixes: a2a4d4a6a0bf ("riscv: stacktrace: fixed walk_stackframe()") Signed-off-by: Jiakai Xu Assisted-by: OpenClaw:DeepSeek-V3.2 --- arch/riscv/kernel/stacktrace.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index b41b6255751c..d23681873b5a 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -35,12 +35,16 @@ extern asmlinkage void handle_exception(void); extern unsigned long ret_from_exception_end; =20 -static inline int fp_is_valid(unsigned long fp, unsigned long sp) +static inline int fp_is_valid(unsigned long fp, unsigned long sp, + struct task_struct *task) { unsigned long low, high; =20 + if (!task) + task =3D current; + low =3D sp + sizeof(struct stackframe); - high =3D ALIGN(sp, THREAD_SIZE); + high =3D (unsigned long)task_stack_page(task) + THREAD_SIZE; =20 return !(fp < low || fp > high || fp & 0x07); } @@ -74,13 +78,13 @@ void notrace walk_stackframe(struct task_struct *task, = struct pt_regs *regs, if (unlikely(!__kernel_text_address(pc) || (level++ >=3D 0 && !fn(arg, p= c)))) break; =20 - if (unlikely(!fp_is_valid(fp, sp))) + if (unlikely(!fp_is_valid(fp, sp, task))) break; =20 /* Unwind stack frame */ frame =3D (struct stackframe *)fp - 1; sp =3D fp; - if (regs && (regs->epc =3D=3D pc) && fp_is_valid(frame->ra, sp)) { + if (regs && (regs->epc =3D=3D pc) && fp_is_valid(frame->ra, sp, task)) { /* We hit function where ra is not saved on the stack */ fp =3D frame->ra; pc =3D regs->ra; --=20 2.34.1