untrusted comment: signature from openbsd 6.0 base secret key RWSho3oKSqgLQ7PpOq+FMOp0pZF44oaBgHmZvHBBxODPWMy+5imAZ4x3Lh2IzicWYL+82ttXR7DfRqyV8xe7/mH0Emy34PviNw8= OpenBSD 6.0 errata 045, October 4th, 2017: Do not leak kernel address when restoring an invalid FPU context. Apply by doing: signify -Vep /etc/signify/openbsd-60-base.pub -x 045_xrstor_resume.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.2.1 diff -u -p -r1.33.2.1 fpu.c --- sys/arch/amd64/amd64/fpu.c 3 Oct 2017 22:08:05 -0000 1.33.2.1 +++ sys/arch/amd64/amd64/fpu.c 4 Oct 2017 13:21:53 -0000 @@ -56,7 +56,8 @@ #include -void xrstor_user(struct savefpu *_addr, uint64_t _mask); +int xrstor_user(struct savefpu *_addr, uint64_t _mask); +void trap(struct trapframe *); /* * We do lazy initialization and switching using the TS bit in cr0 and the @@ -112,7 +113,7 @@ xrstor(struct savefpu *addr, uint64_t ma __asm volatile("xrstor %0" : : "m" (*addr), "a" (lo), "d" (hi)); } -void fpudna(struct cpu_info *); +void fpudna(struct cpu_info *, struct trapframe *); static int x86fpflags_to_siginfo(u_int32_t); /* @@ -226,7 +227,7 @@ x86fpflags_to_siginfo(u_int32_t flags) * saved state. */ void -fpudna(struct cpu_info *ci) +fpudna(struct cpu_info *ci, struct trapframe *frame) { struct savefpu *sfp; struct proc *p; @@ -287,7 +288,12 @@ fpudna(struct cpu_info *ci) p->p_md.md_flags |= MDP_USEDFPU; } else { if (xsave_mask) { - xrstor_user(sfp, xsave_mask); + if (xrstor_user(sfp, xsave_mask)) { + fpusave_proc(p, 0); /* faulted */ + frame->tf_trapno = T_PROTFLT; + trap(frame); + return; + } } 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.2.1 diff -u -p -r1.82.2.1 locore.S --- sys/arch/amd64/amd64/locore.S 3 Oct 2017 22:08:05 -0000 1.82.2.1 +++ sys/arch/amd64/amd64/locore.S 4 Oct 2017 13:21:53 -0000 @@ -1167,6 +1167,10 @@ ENTRY(xrstor_user) .globl xrstor_fault xrstor_fault: xrstor (%rdi) + xorl %eax, %eax + ret +ENTRY(xrstor_resume) + movl $1, %eax ret ENTRY(pagezero) 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.2 diff -u -p -r1.49.2.2 trap.c --- sys/arch/amd64/amd64/trap.c 3 Oct 2017 22:08:05 -0000 1.49.2.2 +++ sys/arch/amd64/amd64/trap.c 4 Oct 2017 13:22:16 -0000 @@ -148,7 +148,8 @@ trap(struct trapframe *frame) struct proc *p = curproc; int type = (int)frame->tf_trapno; struct pcb *pcb; - extern char doreti_iret[], resume_iret[], xrstor_fault[]; + extern char doreti_iret[], resume_iret[]; + extern char xrstor_fault[], xrstor_resume[]; caddr_t onfault; int error; uint64_t cr2; @@ -228,8 +229,8 @@ trap(struct trapframe *frame) * instruction that faulted. */ if (frame->tf_rip == (u_int64_t)xrstor_fault && p != NULL) { - fpusave_proc(p, 0); - goto user_trap; + frame->tf_rip = (u_int64_t)xrstor_resume; + return; } case T_SEGNPFLT: case T_ALIGNFLT: @@ -261,7 +262,6 @@ 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()); Index: sys/arch/amd64/amd64/vector.S =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/vector.S,v retrieving revision 1.46.2.1 diff -u -p -r1.46.2.1 vector.S --- sys/arch/amd64/amd64/vector.S 26 Aug 2017 00:15:05 -0000 1.46.2.1 +++ sys/arch/amd64/amd64/vector.S 4 Oct 2017 13:21:53 -0000 @@ -127,6 +127,7 @@ IDTVEC(trap07) cld SMAP_CLAC movq CPUVAR(SELF),%rdi + movq %rsp, %rsi call _C_LABEL(fpudna) INTRFASTEXIT IDTVEC(trap08)