Author: jhb
Date: Wed Aug 12 20:33:29 2020
New Revision: 364181
URL: https://svnweb.freebsd.org/changeset/base/364181

Log:
  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

Modified:
  head/sys/riscv/riscv/stack_machdep.c

Modified: head/sys/riscv/riscv/stack_machdep.c
==============================================================================
--- head/sys/riscv/riscv/stack_machdep.c        Wed Aug 12 20:29:49 2020        
(r364180)
+++ head/sys/riscv/riscv/stack_machdep.c        Wed Aug 12 20:33:29 2020        
(r364181)
@@ -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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to