Commit b1e2f063 authored by Konstantin Belousov's avatar Konstantin Belousov
Browse files

amd64 sendsig: fix context corruption

Drop fpstate only after copying out xfpustate from the thread usermode
save area. Otherwise a context switch between get_fpcontext(), which now
returns the pointer directly into user save area, and copyout, would
cause reinit of the save area, loosing user registers.

Reported, reviewed, and tested by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Differential revision:	https://reviews.freebsd.org/D32159
parent 860ee179
......@@ -143,7 +143,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_rdi, sizeof(*regs));
sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
get_fpcontext(td, &sf.sf_uc.uc_mcontext, &xfpusave, &xfpusave_len);
fpstate_drop(td);
update_pcb_bases(pcb);
sf.sf_uc.uc_mcontext.mc_fsbase = pcb->pcb_fsbase;
sf.sf_uc.uc_mcontext.mc_gsbase = pcb->pcb_gsbase;
......@@ -203,6 +202,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sigexit(td, SIGILL);
}
fpstate_drop(td);
regs->tf_rsp = (long)sfp;
regs->tf_rip = p->p_sysent->sv_sigcode_base;
regs->tf_rflags &= ~(PSL_T | PSL_D);
......
......@@ -607,7 +607,6 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs;
sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */
ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext, &xfpusave, &xfpusave_len);
fpstate_drop(td);
sf.sf_uc.uc_mcontext.mc_fsbase = td->td_pcb->pcb_fsbase;
sf.sf_uc.uc_mcontext.mc_gsbase = td->td_pcb->pcb_gsbase;
......@@ -661,6 +660,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sigexit(td, SIGILL);
}
fpstate_drop(td);
regs->tf_rsp = (uintptr_t)sfp;
regs->tf_rip = p->p_sysent->sv_sigcode_base;
regs->tf_rflags &= ~(PSL_T | PSL_D);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment