From b7fc89b74b7213ab8b669c6bf8205938540690e8 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 15 Dec 2009 20:00:34 +0000 Subject: [PATCH] MFC: r200272 Add additional checks of the kernel stack addresses in order to ensure we don't overrun the beginning of the call chain. --- sys/sparc64/sparc64/stack_machdep.c | 14 +++++++++++--- sys/sun4v/sun4v/stack_machdep.c | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/sys/sparc64/sparc64/stack_machdep.c b/sys/sparc64/sparc64/stack_machdep.c index f05ad6b7f49..a4309ef45c4 100644 --- a/sys/sparc64/sparc64/stack_machdep.c +++ b/sys/sparc64/sparc64/stack_machdep.c @@ -36,15 +36,20 @@ __FBSDID("$FreeBSD$"); #include #include -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; @@ -56,6 +61,9 @@ stack_capture(struct stack *st, struct frame *fp) 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); } } diff --git a/sys/sun4v/sun4v/stack_machdep.c b/sys/sun4v/sun4v/stack_machdep.c index e29ce88ef73..6b91dc1d52f 100644 --- a/sys/sun4v/sun4v/stack_machdep.c +++ b/sys/sun4v/sun4v/stack_machdep.c @@ -36,20 +36,28 @@ __FBSDID("$FreeBSD$"); #include #include -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); } }