aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/dumpstack_32.c19
-rw-r--r--arch/x86/kernel/dumpstack_64.c2
2 files changed, 14 insertions, 7 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 4e67a005c7a1..466d55dfeb87 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -28,10 +28,16 @@ void printk_address(unsigned long address, int reliable)
28} 28}
29 29
30static inline int valid_stack_ptr(struct thread_info *tinfo, 30static inline int valid_stack_ptr(struct thread_info *tinfo,
31 void *p, unsigned int size) 31 void *p, unsigned int size, void *end)
32{ 32{
33 void *t = tinfo; 33 void *t = tinfo;
34 return p > t && p <= t + THREAD_SIZE - size; 34 if (end) {
35 if (p < end && p >= (end-THREAD_SIZE))
36 return 1;
37 else
38 return 0;
39 }
40 return p > t && p < t + THREAD_SIZE - size;
35} 41}
36 42
37/* The form of the top of the frame on the stack */ 43/* The form of the top of the frame on the stack */
@@ -43,16 +49,17 @@ struct stack_frame {
43static inline unsigned long 49static inline unsigned long
44print_context_stack(struct thread_info *tinfo, 50print_context_stack(struct thread_info *tinfo,
45 unsigned long *stack, unsigned long bp, 51 unsigned long *stack, unsigned long bp,
46 const struct stacktrace_ops *ops, void *data) 52 const struct stacktrace_ops *ops, void *data,
53 unsigned long *end)
47{ 54{
48 struct stack_frame *frame = (struct stack_frame *)bp; 55 struct stack_frame *frame = (struct stack_frame *)bp;
49 56
50 while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) { 57 while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
51 unsigned long addr; 58 unsigned long addr;
52 59
53 addr = *stack; 60 addr = *stack;
54 if (__kernel_text_address(addr)) { 61 if (__kernel_text_address(addr)) {
55 if ((unsigned long) stack == bp + 4) { 62 if ((unsigned long) stack == bp + sizeof(long)) {
56 ops->address(data, addr, 1); 63 ops->address(data, addr, 1);
57 frame = frame->next_frame; 64 frame = frame->next_frame;
58 bp = (unsigned long) frame; 65 bp = (unsigned long) frame;
@@ -96,7 +103,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
96 103
97 context = (struct thread_info *) 104 context = (struct thread_info *)
98 ((unsigned long)stack & (~(THREAD_SIZE - 1))); 105 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
99 bp = print_context_stack(context, stack, bp, ops, data); 106 bp = print_context_stack(context, stack, bp, ops, data, NULL);
100 /* 107 /*
101 * Should be after the line below, but somewhere 108 * Should be after the line below, but somewhere
102 * in early boot context comes out corrupted and we 109 * in early boot context comes out corrupted and we
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 563554c90686..361afa8864b4 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -141,7 +141,7 @@ print_context_stack(struct thread_info *tinfo,
141 141
142 addr = *stack; 142 addr = *stack;
143 if (__kernel_text_address(addr)) { 143 if (__kernel_text_address(addr)) {
144 if ((unsigned long) stack == bp + 8) { 144 if ((unsigned long) stack == bp + sizeof(long)) {
145 ops->address(data, addr, 1); 145 ops->address(data, addr, 1);
146 frame = frame->next_frame; 146 frame = frame->next_frame;
147 bp = (unsigned long) frame; 147 bp = (unsigned long) frame;