diff options
author | John Baldwin <jhb@FreeBSD.org> | 2020-12-08 18:00:58 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2020-12-08 18:00:58 +0000 |
commit | ae953968171234bb77658c8b1072706a9b7ff2d1 (patch) | |
tree | f2ce36e9317e3d574531b4a7961bc5e00571ca01 /sys/cddl/dev/dtrace | |
parent | 9b9e7f4c51abea7a0776a283d3d4f583139bea08 (diff) | |
download | src-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.c | 19 |
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++; |