Commit eb33c190 authored by Heiko Carstens's avatar Heiko Carstens Committed by Linus Torvalds

[PATCH] s390: show_task oops

The show_task function walks the kernel stack backchain of processes assuming
that the processes are not running.  Since this assumption is not correct
walking the backchain can lead to an addressing exception and therefore to a
kernel hang.  So prevent the kernel hang (you still get incorrect results)
verity that all read accesses are within the bounds of the kernel stack before
performing them.
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7ffbc9da
...@@ -58,10 +58,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); ...@@ -58,10 +58,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
*/ */
unsigned long thread_saved_pc(struct task_struct *tsk) unsigned long thread_saved_pc(struct task_struct *tsk)
{ {
struct stack_frame *sf; struct stack_frame *sf, *low, *high;
sf = (struct stack_frame *) tsk->thread.ksp; if (!tsk || !task_stack_page(tsk))
sf = (struct stack_frame *) sf->back_chain; return 0;
low = task_stack_page(tsk);
high = (struct stack_frame *) task_pt_regs(tsk);
sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN);
if (sf <= low || sf > high)
return 0;
sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
if (sf <= low || sf > high)
return 0;
return sf->gprs[8]; return sf->gprs[8];
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment