From 888e282ab47d29808648940d9cfdaf64f2fd5431 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 16 Jul 2015 19:40:18 +0000 Subject: [PATCH] When checking for the valid value of the frame pointer, verify that it belongs to the kernel stack address range for the thread. Right now, code checks that new frame is not farther then KSTACK_PAGES pages from the current frame, which allows the address to point past the top of the stack. Reviewed by: andrew, emaste, markj Differential revision: https://reviews.freebsd.org/D3108 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/amd64/amd64/stack_machdep.c | 10 +++++----- sys/cddl/dev/dtrace/amd64/dtrace_isa.c | 8 ++++---- sys/cddl/dev/dtrace/i386/dtrace_isa.c | 8 ++++---- sys/i386/i386/stack_machdep.c | 10 +++++----- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sys/amd64/amd64/stack_machdep.c b/sys/amd64/amd64/stack_machdep.c index 57908e202a0..2412c93e069 100644 --- a/sys/amd64/amd64/stack_machdep.c +++ b/sys/amd64/amd64/stack_machdep.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include static void -stack_capture(struct stack *st, register_t rbp) +stack_capture(struct thread *td, struct stack *st, register_t rbp) { struct amd64_frame *frame; vm_offset_t callpc; @@ -56,8 +56,8 @@ stack_capture(struct stack *st, register_t rbp) if (stack_put(st, callpc) == -1) break; if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= td->td_kstack + + td->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } @@ -74,7 +74,7 @@ stack_save_td(struct stack *st, struct thread *td) panic("stack_save_td: running"); rbp = td->td_pcb->pcb_rbp; - stack_capture(st, rbp); + stack_capture(td, st, rbp); } void @@ -83,5 +83,5 @@ stack_save(struct stack *st) register_t rbp; __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); - stack_capture(st, rbp); + stack_capture(curthread, st, rbp); } diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c index 336befca218..07a1b0a7ae8 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -89,8 +89,8 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, } if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= curthread->td_kstack + + curthread->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } @@ -469,8 +469,8 @@ dtrace_getstackdepth(int aframes) break; depth++; if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= curthread->td_kstack + + curthread->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } diff --git a/sys/cddl/dev/dtrace/i386/dtrace_isa.c b/sys/cddl/dev/dtrace/i386/dtrace_isa.c index 04f205c5551..63a7c085d26 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_isa.c @@ -92,8 +92,8 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, } if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= curthread->td_kstack + + curthread->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } @@ -485,8 +485,8 @@ dtrace_getstackdepth(int aframes) break; depth++; if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= curthread->td_kstack + + curthread->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } diff --git a/sys/i386/i386/stack_machdep.c b/sys/i386/i386/stack_machdep.c index 2a5dfdac88a..8dbb9ab8460 100644 --- a/sys/i386/i386/stack_machdep.c +++ b/sys/i386/i386/stack_machdep.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include static void -stack_capture(struct stack *st, register_t ebp) +stack_capture(struct thread *td, struct stack *st, register_t ebp) { struct i386_frame *frame; vm_offset_t callpc; @@ -56,8 +56,8 @@ stack_capture(struct stack *st, register_t ebp) if (stack_put(st, callpc) == -1) break; if (frame->f_frame <= frame || - (vm_offset_t)frame->f_frame >= - (vm_offset_t)ebp + KSTACK_PAGES * PAGE_SIZE) + (vm_offset_t)frame->f_frame >= td->td_kstack + + td->td_kstack_pages * PAGE_SIZE) break; frame = frame->f_frame; } @@ -74,7 +74,7 @@ stack_save_td(struct stack *st, struct thread *td) panic("stack_save_td: running"); ebp = td->td_pcb->pcb_ebp; - stack_capture(st, ebp); + stack_capture(td, st, ebp); } void @@ -83,5 +83,5 @@ stack_save(struct stack *st) register_t ebp; __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); - stack_capture(st, ebp); + stack_capture(curthread, st, ebp); }