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 <machine/codepatch.h>
/*
- * 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;