From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from aserp1040.oracle.com ([141.146.126.69]:50286 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161167AbcFCVi3 (ORCPT ); Fri, 3 Jun 2016 17:38:29 -0400 From: Sasha Levin To: stable@vger.kernel.org, stable-commits@vger.kernel.org Cc: James Hogan , linux-mips@linux-mips.org, Ralf Baechle , Sasha Levin Subject: [added to the 4.1 stable tree] MIPS: Don't unwind to user mode with EVA Date: Fri, 3 Jun 2016 17:35:57 -0400 Message-Id: <1464989831-16666-62-git-send-email-sasha.levin@oracle.com> In-Reply-To: <1464989831-16666-1-git-send-email-sasha.levin@oracle.com> References: <1464989831-16666-1-git-send-email-sasha.levin@oracle.com> Sender: stable-owner@vger.kernel.org List-ID: From: James Hogan This patch has been added to the 4.1 stable tree. If you have any objections, please let us know. =============== [ Upstream commit a816b306c62195b7c43c92cb13330821a96bdc27 ] When unwinding through IRQs and exceptions, the unwinding only continues if the PC is a kernel text address, however since EVA it is possible for user and kernel address ranges to overlap, potentially allowing unwinding to continue to user mode if the user PC happens to be in the kernel text address range. Adjust the check to also ensure that the register state from before the exception is actually running in kernel mode, i.e. !user_mode(regs). I don't believe any harm can come of this problem, since the PC is only output, the stack pointer is checked to ensure it resides within the task's stack page before it is dereferenced in search of the return address, and the return address register is similarly only output (if the PC is in a leaf function or the beginning of a non-leaf function). However unwind_stack() is only meant for unwinding kernel code, so to be correct the unwind should stop there. Signed-off-by: James Hogan Reviewed-by: Leonid Yegoshin Cc: linux-mips@linux-mips.org Cc: # 3.15+ Patchwork: https://patchwork.linux-mips.org/patch/11700/ Signed-off-by: Ralf Baechle Signed-off-by: Sasha Levin --- arch/mips/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f2975d4..6b3ae73 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -457,7 +457,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page, *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { regs = (struct pt_regs *)*sp; pc = regs->cp0_epc; - if (__kernel_text_address(pc)) { + if (!user_mode(regs) && __kernel_text_address(pc)) { *sp = regs->regs[29]; *ra = regs->regs[31]; return pc; -- 2.5.0