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
This commit is contained in:
Tijl Coosemans 2017-10-31 11:51:34 +00:00
parent 26cb32ad01
commit f236378b54
2 changed files with 9 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);