untrusted comment: signature from openbsd 6.1 base secret key RWQEQa33SgQSEgFdJXBKKtCtqCSWRbNuGiMg8R3y15838QSYV1RoJH0464rW3C50MAjpcKkwYAboSTvq3+Tdd9ENZRmkkRWOLwI= OpenBSD 6.1 errata 030, October 4th, 2017: Correctly handle exceptions when restoring an invalid FPU context. This is the second revision of the patch. Apply by doing: signify -Vep /etc/signify/openbsd-61-base.pub -x 030_xrstor.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/arch/amd64/amd64/fpu.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/fpu.c,v retrieving revision 1.33.6.1 diff -u -p -r1.33.6.1 fpu.c --- sys/arch/amd64/amd64/fpu.c 3 May 2017 02:29:16 -0000 1.33.6.1 +++ sys/arch/amd64/amd64/fpu.c 3 Oct 2017 21:31:58 -0000 @@ -56,6 +56,8 @@ #include +void xrstor_user(struct savefpu *_addr, uint64_t _mask); + /* * We do lazy initialization and switching using the TS bit in cr0 and the * MDP_USEDFPU bit in mdproc. @@ -254,7 +256,7 @@ fpudna(struct cpu_info *ci) p->p_md.md_flags |= MDP_USEDFPU; } else { if (xsave_mask) { - xrstor(sfp, xsave_mask); + xrstor_user(sfp, xsave_mask); } else { static double zero = 0.0; Index: sys/arch/amd64/amd64/locore.S =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/locore.S,v retrieving revision 1.84 diff -u -p -r1.84 locore.S --- sys/arch/amd64/amd64/locore.S 6 Feb 2017 09:15:51 -0000 1.84 +++ sys/arch/amd64/amd64/locore.S 3 Oct 2017 21:31:58 -0000 @@ -1203,6 +1203,15 @@ _C_LABEL(doreti_iret): iretq #endif /* !defined(GPROF) && defined(DDBPROF) */ +ENTRY(xrstor_user) + movq %rsi, %rdx + movl %esi, %eax + shrq $32, %rdx + .globl xrstor_fault +xrstor_fault: + xrstor (%rdi) + ret + ENTRY(pagezero) movq $-PAGE_SIZE,%rdx subq %rdx,%rdi Index: sys/arch/amd64/amd64/trap.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/trap.c,v retrieving revision 1.53.4.1 diff -u -p -r1.53.4.1 trap.c --- sys/arch/amd64/amd64/trap.c 26 Aug 2017 00:14:20 -0000 1.53.4.1 +++ sys/arch/amd64/amd64/trap.c 3 Oct 2017 21:31:58 -0000 @@ -148,7 +148,7 @@ trap(struct trapframe *frame) struct proc *p = curproc; int type = (int)frame->tf_trapno; struct pcb *pcb; - extern char doreti_iret[], resume_iret[]; + extern char doreti_iret[], resume_iret[], xrstor_fault[]; caddr_t onfault; int error; uint64_t cr2; @@ -222,6 +222,15 @@ trap(struct trapframe *frame) /*NOTREACHED*/ case T_PROTFLT: + /* + * Check for xrstor faulting because of invalid xstate + * We do this by looking at the address of the + * instruction that faulted. + */ + if (frame->tf_rip == (u_int64_t)xrstor_fault && p != NULL) { + fpusave_proc(p, 0); + goto user_trap; + } case T_SEGNPFLT: case T_ALIGNFLT: case T_TSSFLT: @@ -251,6 +260,7 @@ copyfault: case T_TSSFLT|T_USER: case T_SEGNPFLT|T_USER: case T_STKFLT|T_USER: +user_trap: #ifdef TRAP_SIGDEBUG printf("pid %d (%s): %s at rip %llx addr %llx\n", p->p_p->ps_pid, p->p_p->ps_comm, "BUS",