aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/dev/dtrace
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2020-12-08 18:00:58 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2020-12-08 18:00:58 +0000
commitae953968171234bb77658c8b1072706a9b7ff2d1 (patch)
treef2ce36e9317e3d574531b4a7961bc5e00571ca01 /sys/cddl/dev/dtrace
parent9b9e7f4c51abea7a0776a283d3d4f583139bea08 (diff)
downloadsrc-ae953968171234bb77658c8b1072706a9b7ff2d1.tar.gz
src-ae953968171234bb77658c8b1072706a9b7ff2d1.zip
Check that the frame pointer is within the current stack.
This same check is used on other architectures. Previously this would permit a stack frame to unwind into any arbitrary kernel address (including unmapped addresses). Reviewed by: andrew, markj Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D27362
Notes
Notes: svn path=/head/; revision=368455
Diffstat (limited to 'sys/cddl/dev/dtrace')
-rw-r--r--sys/cddl/dev/dtrace/aarch64/dtrace_isa.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c b/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
index d235ab6dab39..db47423e9d33 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c
@@ -70,7 +70,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
{
struct unwind_state state;
int scp_offset;
- register_t sp, fp;
+ register_t sp;
int depth;
depth = 0;
@@ -88,15 +88,10 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
state.pc = (uintptr_t)dtrace_getpcstack;
while (depth < pcstack_limit) {
- if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+ if (!unwind_frame(curthread, &state))
+ break;
+ if (!INKERNEL(state.pc))
break;
-
- fp = state.fp;
- state.sp = fp + 0x10;
- /* FP to previous frame (X29) */
- state.fp = *(register_t *)(fp);
- /* LR (X30) */
- state.pc = *(register_t *)(fp + 8) - 4;
/*
* NB: Unlike some other architectures, we don't need to
@@ -274,10 +269,10 @@ dtrace_getstackdepth(int aframes)
int scp_offset;
register_t sp;
int depth;
- int done;
+ bool done;
depth = 1;
- done = 0;
+ done = false;
__asm __volatile("mov %0, sp" : "=&r" (sp));
@@ -286,7 +281,7 @@ dtrace_getstackdepth(int aframes)
state.pc = (uintptr_t)dtrace_getstackdepth;
do {
- done = unwind_frame(&state);
+ done = !unwind_frame(curthread, &state);
if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
break;
depth++;