Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755786AbcJNM5A (ORCPT ); Fri, 14 Oct 2016 08:57:00 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:42155 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754930AbcJNMz6 (ORCPT ); Fri, 14 Oct 2016 08:55:58 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Josh Poimboeuf , Andy Lutomirski , Andy Lutomirski , Borislav Petkov , Brian Gerst , Byungchul Park , Denys Vlasenko , Frederic Weisbecker , "H. Peter Anvin" , Kees Cook , Linus Torvalds , Nilay Vaish , Peter Zijlstra , Steven Rostedt , Thomas Gleixner , Ingo Molnar Subject: [PATCH 4.7 25/31] x86/dumpstack: Fix x86_32 kernel_stack_pointer() previous stack access Date: Fri, 14 Oct 2016 14:55:09 +0200 Message-Id: <20161014122716.280499841@linuxfoundation.org> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161014122715.235592611@linuxfoundation.org> References: <20161014122715.235592611@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2660 Lines: 67 4.7-stable review patch. If anyone has any objections, please let me know. ------------------ From: Josh Poimboeuf commit 72b4f6a5e903b071f2a7c4eb1418cbe4eefdc344 upstream. On x86_32, when an interrupt happens from kernel space, SS and SP aren't pushed and the existing stack is used. So pt_regs is effectively two words shorter, and the previous stack pointer is normally the memory after the shortened pt_regs, aka '®s->sp'. But in the rare case where the interrupt hits right after the stack pointer has been changed to point to an empty stack, like for example when call_on_stack() is used, the address immediately after the shortened pt_regs is no longer on the stack. In that case, instead of '®s->sp', the previous stack pointer should be retrieved from the beginning of the current stack page. kernel_stack_pointer() wants to do that, but it forgets to dereference the pointer. So instead of returning a pointer to the previous stack, it returns a pointer to the beginning of the current stack. Note that it's probably outside of kernel_stack_pointer()'s scope to be switching stacks at all. The x86_64 version of this function doesn't do it, and it would be better for the caller to do it if necessary. But that's a patch for another day. This just fixes the original intent. Signed-off-by: Josh Poimboeuf Cc: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Byungchul Park Cc: Denys Vlasenko Cc: Frederic Weisbecker Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Nilay Vaish Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Thomas Gleixner Fixes: 0788aa6a23cb ("x86: Prepare removal of previous_esp from i386 thread_info structure") Link: http://lkml.kernel.org/r/472453d6e9f6a2d4ab16aaed4935f43117111566.1471535549.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/ptrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -173,8 +173,8 @@ unsigned long kernel_stack_pointer(struc return sp; prev_esp = (u32 *)(context); - if (prev_esp) - return (unsigned long)prev_esp; + if (*prev_esp) + return (unsigned long)*prev_esp; return (unsigned long)regs; }