diff options
author | Jan Beulich <jbeulich@novell.com> | 2006-12-06 20:14:13 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:13 -0500 |
commit | 359ad0d4015a9ab39243f2ebc4eb07915bd618b2 (patch) | |
tree | 90f05d8d9ab048029bfe1e451a012b4d5896aafe /arch/i386/kernel/traps.c | |
parent | eef5e0d185fc049bda11fa14ba286fbd357da896 (diff) |
[PATCH] unwinder: more sanity checks in Dwarf2 unwinder
Tighten the requirements on both input to and output from the Dwarf2
unwinder.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 86d8476be4fe..c447807e2a45 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -161,12 +161,19 @@ dump_trace_unwind(struct unwind_frame_info *info, void *data) | |||
161 | { | 161 | { |
162 | struct ops_and_data *oad = (struct ops_and_data *)data; | 162 | struct ops_and_data *oad = (struct ops_and_data *)data; |
163 | int n = 0; | 163 | int n = 0; |
164 | unsigned long sp = UNW_SP(info); | ||
164 | 165 | ||
166 | if (arch_unw_user_mode(info)) | ||
167 | return -1; | ||
165 | while (unwind(info) == 0 && UNW_PC(info)) { | 168 | while (unwind(info) == 0 && UNW_PC(info)) { |
166 | n++; | 169 | n++; |
167 | oad->ops->address(oad->data, UNW_PC(info)); | 170 | oad->ops->address(oad->data, UNW_PC(info)); |
168 | if (arch_unw_user_mode(info)) | 171 | if (arch_unw_user_mode(info)) |
169 | break; | 172 | break; |
173 | if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) | ||
174 | && sp > UNW_SP(info)) | ||
175 | break; | ||
176 | sp = UNW_SP(info); | ||
170 | } | 177 | } |
171 | return n; | 178 | return n; |
172 | } | 179 | } |