diff options
author | marius <marius@FreeBSD.org> | 2009-12-08 20:18:54 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2009-12-08 20:18:54 +0000 |
commit | e888c6f864ef40440287949376c4e869a07f8b68 (patch) | |
tree | 598d460ae5567e2657fc4ad335e6271026ae2b7c /sys/sun4v | |
parent | 942205b726b9102e8300a9b563b69ea22755f629 (diff) | |
download | FreeBSD-src-e888c6f864ef40440287949376c4e869a07f8b68.zip FreeBSD-src-e888c6f864ef40440287949376c4e869a07f8b68.tar.gz |
Add additional checks of the kernel stack addresses in order to
ensure we don't overrun the end of the call chain.
MFC after: 1 week
Diffstat (limited to 'sys/sun4v')
-rw-r--r-- | sys/sun4v/sun4v/stack_machdep.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/sun4v/sun4v/stack_machdep.c b/sys/sun4v/sun4v/stack_machdep.c index e29ce88..6b91dc1 100644 --- a/sys/sun4v/sun4v/stack_machdep.c +++ b/sys/sun4v/sun4v/stack_machdep.c @@ -36,20 +36,28 @@ __FBSDID("$FreeBSD$"); #include <machine/stack.h> #include <machine/vmparam.h> -static void stack_capture(struct stack *st, struct frame *fp); +static void stack_capture(struct stack *st, struct frame *frame); static void -stack_capture(struct stack *st, struct frame *fp) +stack_capture(struct stack *st, struct frame *frame) { + struct frame *fp; vm_offset_t callpc; stack_zero(st); - while (1) { + fp = frame; + for (;;) { + if (!INKERNEL((vm_offset_t)fp) || + !ALIGNED_POINTER(fp, uint64_t)) + break; callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; if (stack_put(st, callpc) == -1) break; + if (v9next_frame(fp) <= fp || + v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) + break; fp = v9next_frame(fp); } } |