diff options
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/locore.S | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 31 | ||||
-rw-r--r-- | sys/arch/amd64/include/signal.h | 3 |
3 files changed, 29 insertions, 9 deletions
diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index f66dc562df8..bad043377b4 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.77 2016/05/10 14:15:57 mikeb Exp $ */ +/* $OpenBSD: locore.S,v 1.78 2016/05/10 18:39:42 deraadt Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -763,6 +763,8 @@ NENTRY(sigcode) pushq %rdi /* fake return address */ movq $SYS_sigreturn,%rax syscall + .globl _C_LABEL(sigcoderet) +_C_LABEL(sigcoderet): movq $SYS_exit,%rax syscall .globl _C_LABEL(esigcode) diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 8d2db71e90d..d0a145ab3ee 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.218 2016/04/03 17:48:33 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.219 2016/05/10 18:39:42 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -571,6 +571,7 @@ sendsig(sig_t catcher, int sig, int mask, u_long code, int type, } scp = sp - sss; + ksc.sc_cookie = (long)scp ^ p->p_p->ps_sigcookie; if (copyout(&ksc, (void *)scp, sizeof(ksc))) sigexit(p, SIGILL); @@ -611,18 +612,34 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval) struct sys_sigreturn_args /* { syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; - struct sigcontext *scp, ksc; + struct sigcontext *scp = SCARG(uap, sigcntxp), ksc; struct trapframe *tf = p->p_md.md_regs; int error; - scp = SCARG(uap, sigcntxp); -#ifdef DEBUG - if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) - printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); -#endif + if (PROC_PC(p) != p->p_p->ps_sigcoderet) { + printf("%s(%d): sigreturn not from tramp [pc 0x%llx %lx]\n", + p->p_comm, p->p_pid, PROC_PC(p), p->p_p->ps_sigcoderet); + sigexit(p, SIGILL); + return (EPERM); + } + if ((error = copyin((caddr_t)scp, &ksc, sizeof ksc))) return (error); + if (ksc.sc_cookie != ((long)scp ^ p->p_p->ps_sigcookie)) { + printf("%s(%d): cookie %lx should have been %lx\n", + p->p_comm, p->p_pid, ksc.sc_cookie, + (long)scp ^ p->p_p->ps_sigcookie); + sigexit(p, SIGILL); + return (EFAULT); + } + + /* Prevent reuse of the sigcontext cookie */ + ksc.sc_cookie = 0; + (void)copyout(&ksc.sc_cookie, (caddr_t)scp + + offsetof(struct sigcontext, sc_cookie), + sizeof (ksc.sc_cookie)); + if (((ksc.sc_rflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || !USERMODE(ksc.sc_cs, ksc.sc_eflags)) return (EINVAL); diff --git a/sys/arch/amd64/include/signal.h b/sys/arch/amd64/include/signal.h index 527a220cf32..e5cffc53b1d 100644 --- a/sys/arch/amd64/include/signal.h +++ b/sys/arch/amd64/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.8 2013/04/01 17:18:19 deraadt Exp $ */ +/* $OpenBSD: signal.h,v 1.9 2016/05/10 18:39:42 deraadt Exp $ */ /* $NetBSD: signal.h,v 1.2 2003/04/28 23:16:17 bjh21 Exp $ */ /* @@ -83,6 +83,7 @@ struct sigcontext { struct fxsave64 *sc_fpstate; int __sc_unused; int sc_mask; + long sc_cookie; }; #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */ #endif /* !_MACHINE_SIGNAL_H_ */ |