[lkml]   [2016]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 4.8 28/37] x86/dumpstack: Fix x86_32 kernel_stack_pointer() previous stack access
4.8-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 '&regs->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
'&regs->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")
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;

 \ /
  Last update: 2016-10-14 14:34    [W:1.919 / U:0.088 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site