untrusted comment: signature from openbsd 6.0 base secret key RWSho3oKSqgLQ7x/7TX0z5lu84+V137LjuAO6zKsia0XHdKKJlVxUhMizWg5cdhl+en8p7HdBUa+6JRAr2wy2Ji7HopVtUIsAAw= OpenBSD 6.0 errata 040, August 26, 2017: SMAP enforcement could be bypassed by userland code. Apply by doing: signify -Vep /etc/signify/openbsd-60-base.pub -x 040_smap.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/copy.S =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/copy.S,v retrieving revision 1.7 diff -u -p -r1.7 copy.S --- sys/arch/amd64/amd64/copy.S 25 Apr 2015 21:31:24 -0000 1.7 +++ sys/arch/amd64/amd64/copy.S 26 Aug 2017 00:05:09 -0000 @@ -45,23 +45,6 @@ #include /* - * As stac/clac SMAP instructions are 3 bytes, we want the fastest - * 3 byte nop sequence possible here. This will be replaced by - * stac/clac instructions if SMAP is detected after booting. - * - * This would be 'nop (%rax)' if binutils could cope. - * Intel documents multi-byte NOP sequences as being available - * on all family 0x6 and 0xf processors (ie 686+) - */ -#define SMAP_NOP .byte 0x0f, 0x1f, 0x00 -#define SMAP_STAC CODEPATCH_START ;\ - SMAP_NOP ;\ - CODEPATCH_END(CPTAG_STAC) -#define SMAP_CLAC CODEPATCH_START ;\ - SMAP_NOP ;\ - CODEPATCH_END(CPTAG_CLAC) - -/* * Copy routines from and to userland, plus a few more. See the * section 9 manpages for info. Some cases can be optimized more. * Index: sys/arch/amd64/amd64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v retrieving revision 1.101 diff -u -p -r1.101 cpu.c --- sys/arch/amd64/amd64/cpu.c 28 Jun 2016 05:37:50 -0000 1.101 +++ sys/arch/amd64/amd64/cpu.c 26 Aug 2017 00:05:09 -0000 @@ -838,7 +838,7 @@ cpu_init_msrs(struct cpu_info *ci) ((uint64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48)); wrmsr(MSR_LSTAR, (uint64_t)Xsyscall); wrmsr(MSR_CSTAR, (uint64_t)Xsyscall32); - wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D); + wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D|PSL_AC); wrmsr(MSR_FSBASE, 0); wrmsr(MSR_GSBASE, (u_int64_t)ci); Index: sys/arch/amd64/amd64/trap.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/trap.c,v retrieving revision 1.49 diff -u -p -r1.49 trap.c --- sys/arch/amd64/amd64/trap.c 27 Feb 2016 13:08:06 -0000 1.49 +++ sys/arch/amd64/amd64/trap.c 26 Aug 2017 00:05:09 -0000 @@ -169,6 +169,15 @@ trap(struct trapframe *frame) printf("pid %d\n", p->p_pid); } #endif +#ifdef DIAGNOSTIC + if (curcpu()->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) { + u_long rf = read_rflags(); + if (rf & PSL_AC) { + write_rflags(rf & ~PSL_AC); + panic("%s: AC set on entry", "trap"); + } + } +#endif if (!KERNELMODE(frame->tf_cs, frame->tf_rflags)) { type |= T_USER; @@ -506,6 +515,16 @@ syscall(struct trapframe *frame) int nsys; size_t argsize, argoff; register_t code, args[9], rval[2], *argp; + +#ifdef DIAGNOSTIC + if (curcpu()->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) { + u_long rf = read_rflags(); + if (rf & PSL_AC) { + write_rflags(rf & ~PSL_AC); + panic("%s: AC set on entry", "syscall"); + } + } +#endif uvmexp.syscalls++; p = curproc; Index: sys/arch/amd64/amd64/vector.S =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/vector.S,v retrieving revision 1.46 diff -u -p -r1.46 vector.S --- sys/arch/amd64/amd64/vector.S 22 Jun 2016 01:12:38 -0000 1.46 +++ sys/arch/amd64/amd64/vector.S 26 Aug 2017 00:05:09 -0000 @@ -125,6 +125,7 @@ IDTVEC(trap07) INTRENTRY sti cld + SMAP_CLAC movq CPUVAR(SELF),%rdi call _C_LABEL(fpudna) INTRFASTEXIT @@ -246,6 +247,7 @@ NENTRY(alltraps) sti calltrap: cld + SMAP_CLAC #ifdef DIAGNOSTIC movl CPUVAR(ILEVEL),%ebx #endif /* DIAGNOSTIC */ @@ -343,6 +345,7 @@ IDTVEC(resume_lapic_ipi) movl $IPL_IPI,CPUVAR(ILEVEL) sti cld + SMAP_CLAC pushq %rbx call _C_LABEL(x86_ipi_handler) jmp _C_LABEL(Xdoreti) @@ -426,6 +429,7 @@ IDTVEC(resume_lapic_ltimer) movl $IPL_CLOCK,CPUVAR(ILEVEL) sti cld + SMAP_CLAC pushq %rbx xorq %rdi,%rdi call _C_LABEL(lapic_clockintr) @@ -460,6 +464,7 @@ IDTVEC(resume_xen_upcall) movl $IPL_NET,CPUVAR(ILEVEL) sti cld + SMAP_CLAC pushq %rbx call _C_LABEL(xen_intr) jmp _C_LABEL(Xdoreti) @@ -494,6 +499,7 @@ IDTVEC(resume_hyperv_upcall) movl $IPL_NET,CPUVAR(ILEVEL) sti cld + SMAP_CLAC pushq %rbx call _C_LABEL(hv_intr) jmp _C_LABEL(Xdoreti) @@ -543,6 +549,7 @@ IDTVEC(intr_##name##num) ;\ movl %ebx,CPUVAR(ILEVEL) ;\ sti ;\ cld ;\ + SMAP_CLAC ;\ incl CPUVAR(IDEPTH) ;\ movq IS_HANDLERS(%r14),%rbx ;\ 6: \ Index: sys/arch/amd64/include/codepatch.h =================================================================== RCS file: /cvs/src/sys/arch/amd64/include/codepatch.h,v retrieving revision 1.2 diff -u -p -r1.2 codepatch.h --- sys/arch/amd64/include/codepatch.h 19 Apr 2015 19:45:21 -0000 1.2 +++ sys/arch/amd64/include/codepatch.h 26 Aug 2017 00:05:09 -0000 @@ -50,4 +50,21 @@ void codepatch_call(uint16_t tag, void * #define CPTAG_CLAC 2 #define CPTAG_EOI 3 +/* + * As stac/clac SMAP instructions are 3 bytes, we want the fastest + * 3 byte nop sequence possible here. This will be replaced by + * stac/clac instructions if SMAP is detected after booting. + * + * This would be 'nop (%rax)' if binutils could cope. + * Intel documents multi-byte NOP sequences as being available + * on all family 0x6 and 0xf processors (ie 686+) + */ +#define SMAP_NOP .byte 0x0f, 0x1f, 0x00 +#define SMAP_STAC CODEPATCH_START ;\ + SMAP_NOP ;\ + CODEPATCH_END(CPTAG_STAC) +#define SMAP_CLAC CODEPATCH_START ;\ + SMAP_NOP ;\ + CODEPATCH_END(CPTAG_CLAC) + #endif /* _MACHINE_CODEPATCH_H_ */ Index: sys/arch/i386/i386/locore.s =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v retrieving revision 1.170 diff -u -p -r1.170 locore.s --- sys/arch/i386/i386/locore.s 16 Jul 2016 06:04:29 -0000 1.170 +++ sys/arch/i386/i386/locore.s 26 Aug 2017 00:05:09 -0000 @@ -115,6 +115,7 @@ */ #define INTRENTRY \ cld ; \ + SMAP_CLAC ; \ pushl %eax ; \ pushl %ecx ; \ pushl %edx ; \ Index: sys/arch/i386/i386/trap.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/trap.c,v retrieving revision 1.125 diff -u -p -r1.125 trap.c --- sys/arch/i386/i386/trap.c 28 Feb 2016 15:46:18 -0000 1.125 +++ sys/arch/i386/i386/trap.c 26 Aug 2017 00:05:09 -0000 @@ -148,6 +148,15 @@ trap(struct trapframe *frame) printf("curproc %p\n", curproc); } #endif +#ifdef DIAGNOSTIC + if (curcpu()->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) { + u_int ef = read_eflags(); + if (ef & PSL_AC) { + write_eflags(ef & ~PSL_AC); + panic("%s: AC set on entry", "trap"); + } + } +#endif if (!KERNELMODE(frame->tf_cs, frame->tf_eflags)) { type |= T_USER; @@ -556,6 +565,16 @@ syscall(struct trapframe *frame) if (!USERMODE(frame->tf_cs, frame->tf_eflags)) panic("syscall"); #endif +#ifdef DIAGNOSTIC + if (curcpu()->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) { + u_int ef = read_eflags(); + if (ef & PSL_AC) { + write_eflags(ef & ~PSL_AC); + panic("%s: AC set on entry", "syscall"); + } + } +#endif + p = curproc; p->p_md.md_regs = frame; code = frame->tf_eax;