aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-11-28 14:12:59 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-11-28 14:12:59 -0500
commitc547c77ee4d0408907847f64c403df1bf2f9c7a0 (patch)
treeffbc35f7dcbf7b1b57f220c1e1a555bed24a6089
parent38b5b036b91248be8033d42dd0778b1c75c5af58 (diff)
[PATCH] x86-64: Use stricter in process stack check for unwinder
Previously it would check for alignment only, which could break if the stack pointer was unaligned. Now explicitely check if the stack pointer is in the stack page of the current process. Ported from i386. Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/x86_64/kernel/traps.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index a153d0a01b7..0d65b22f229 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -242,12 +242,19 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context)
242 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack 242 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
243 */ 243 */
244 244
245static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
246{
247 void *t = (void *)tinfo;
248 return p > t && p < t + THREAD_SIZE - 3;
249}
250
245void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, 251void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack,
246 struct stacktrace_ops *ops, void *data) 252 struct stacktrace_ops *ops, void *data)
247{ 253{
248 const unsigned cpu = smp_processor_id(); 254 const unsigned cpu = smp_processor_id();
249 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; 255 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
250 unsigned used = 0; 256 unsigned used = 0;
257 struct thread_info *tinfo;
251 258
252 if (!tsk) 259 if (!tsk)
253 tsk = current; 260 tsk = current;
@@ -370,7 +377,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
370 /* 377 /*
371 * This handles the process stack: 378 * This handles the process stack:
372 */ 379 */
373 HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); 380 tinfo = current_thread_info();
381 HANDLE_STACK (valid_stack_ptr(tinfo, stack));
374#undef HANDLE_STACK 382#undef HANDLE_STACK
375} 383}
376EXPORT_SYMBOL(dump_trace); 384EXPORT_SYMBOL(dump_trace);