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: mhorne Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D25996
This commit is contained in:
parent
367de39efa
commit
40db51b42f
@ -47,15 +47,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/stack.h>
|
||||
|
||||
static void
|
||||
stack_capture(struct stack *st, struct unwind_state *frame)
|
||||
stack_capture(struct thread *td, struct stack *st, struct unwind_state *frame)
|
||||
{
|
||||
|
||||
stack_zero(st);
|
||||
|
||||
while (1) {
|
||||
if ((vm_offset_t)frame->fp < td->td_kstack ||
|
||||
(vm_offset_t)frame->fp >= td->td_kstack +
|
||||
td->td_kstack_pages * PAGE_SIZE)
|
||||
break;
|
||||
unwind_frame(frame);
|
||||
if (!INKERNEL((vm_offset_t)frame->fp) ||
|
||||
!INKERNEL((vm_offset_t)frame->pc))
|
||||
if (!INKERNEL((vm_offset_t)frame->pc))
|
||||
break;
|
||||
if (stack_put(st, frame->pc) == -1)
|
||||
break;
|
||||
@ -78,7 +81,7 @@ stack_save_td(struct stack *st, struct thread *td)
|
||||
frame.fp = td->td_pcb->pcb_s[0];
|
||||
frame.pc = td->td_pcb->pcb_ra;
|
||||
|
||||
stack_capture(st, &frame);
|
||||
stack_capture(td, st, &frame);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -94,5 +97,5 @@ stack_save(struct stack *st)
|
||||
frame.fp = (uintptr_t)__builtin_frame_address(0);
|
||||
frame.pc = (uintptr_t)stack_save;
|
||||
|
||||
stack_capture(st, &frame);
|
||||
stack_capture(curthread, st, &frame);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user