untrusted comment: signature from openbsd 6.0 base secret key RWSho3oKSqgLQ8qux8rz3eB2vYfGGBp/WEBKuVcfHufa00nR7p6V4CY/PXEgdDI9ppw8n4LLVaLAQGdoP1yAZ8bxfyVE9kIzLgI= OpenBSD 6.0 errata 044, 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-60-base.pub -x 044_xrstor.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: cd /usr/src/sys/arch/`machine`/conf KK=`sysctl -n kern.osversion | cut -d# -f1` config $KK cd ../compile/$KK 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 diff -u -p -r1.33 fpu.c --- sys/arch/amd64/amd64/fpu.c 21 Apr 2016 22:08:27 -0000 1.33 +++ sys/arch/amd64/amd64/fpu.c 3 Oct 2017 21:31:18 -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. @@ -285,7 +287,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.82 diff -u -p -r1.82 locore.S --- sys/arch/amd64/amd64/locore.S 16 Jul 2016 06:04:29 -0000 1.82 +++ sys/arch/amd64/amd64/locore.S 3 Oct 2017 21:31:18 -0000 @@ -1160,6 +1160,15 @@ _C_LABEL(doreti_iret): iretq +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.49.2.1 diff -u -p -r1.49.2.1 trap.c --- sys/arch/amd64/amd64/trap.c 26 Aug 2017 00:15:05 -0000 1.49.2.1 +++ sys/arch/amd64/amd64/trap.c 3 Oct 2017 21:40:14 -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: @@ -252,6 +261,7 @@ copyfault: case T_SEGNPFLT|T_USER: case T_STKFLT|T_USER: case T_NMI|T_USER: +user_trap: #ifdef TRAP_SIGDEBUG printf("pid %d (%s): BUS at rip %lx addr %lx\n", p->p_pid, p->p_comm, frame->tf_rip, rcr2());