From f236378b54c04bb62a1cc528f4d8daa6e68252b9 Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Tue, 31 Oct 2017 11:51:34 +0000 Subject: [PATCH] Set the return address for stack entry points to zero. Stack unwinders treat zero as a stop condition. The value on the stack can be non-zero because thread stacks may be arbitrary memory provided via pthread_attr_setstack(3) or may be recycled from previous threads. Reference: https://lists.freebsd.org/pipermail/freebsd-current/2017-August/066855.html https://lists.freebsd.org/pipermail/freebsd-current/2017-October/067254.html Discussed with: kib MFC after: 1 week --- sys/amd64/amd64/vm_machdep.c | 6 ++++++ sys/i386/i386/vm_machdep.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 5f4f43c2352..fae37d731b0 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -508,6 +508,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, (((uintptr_t)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4; td->td_frame->tf_rip = (uintptr_t)entry; + /* Return address sentinel value to stop stack unwinding. */ + suword32((void *)td->td_frame->tf_rsp, 0); + /* Pass the argument to the entry point. */ suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)), (uint32_t)(uintptr_t)arg); @@ -531,6 +534,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, td->td_frame->tf_gs = _ugssel; td->td_frame->tf_flags = TF_HASSEGS; + /* Return address sentinel value to stop stack unwinding. */ + suword((void *)td->td_frame->tf_rsp, 0); + /* Pass the argument to the entry point. */ td->td_frame->tf_rdi = (register_t)arg; } diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index a0a9473b3bd..562cdfdd756 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -524,6 +524,9 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, (((int)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4; td->td_frame->tf_eip = (int)entry; + /* Return address sentinel value to stop stack unwinding. */ + suword((void *)td->td_frame->tf_esp, 0); + /* Pass the argument to the entry point. */ suword((void *)(td->td_frame->tf_esp + sizeof(void *)), (int)arg);