untrusted comment: signature from openbsd 6.1 base secret key
RWQEQa33SgQSEtYeZhycwDBBioEqjGw/GRt5yv1iTlknUr3kbYj/kDc7uP38O8Bq+NAvbbrbROuiyEFCGsEnSzTOo0cTxS0oUAw=
OpenBSD 6.1 errata 026, August 26, 2017:
SMAP enforcement could be bypassed by userland code.
Apply by doing:
signify -Vep /etc/signify/openbsd-61-base.pub -x 026_smap.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/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 25 Aug 2017 21:18:11 -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.102
diff -u -p -r1.102 cpu.c
--- sys/arch/amd64/amd64/cpu.c 28 Jul 2016 21:57:57 -0000 1.102
+++ sys/arch/amd64/amd64/cpu.c 25 Aug 2017 21:18:11 -0000
@@ -839,7 +839,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.53
diff -u -p -r1.53 trap.c
--- sys/arch/amd64/amd64/trap.c 3 Mar 2017 20:49:47 -0000 1.53
+++ sys/arch/amd64/amd64/trap.c 25 Aug 2017 21:18:11 -0000
@@ -169,6 +169,15 @@ trap(struct trapframe *frame)
printf("pid %d\n", p->p_p->ps_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;
@@ -509,6 +518,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.47
diff -u -p -r1.47 vector.S
--- sys/arch/amd64/amd64/vector.S 4 Sep 2016 09:22:28 -0000 1.47
+++ sys/arch/amd64/amd64/vector.S 25 Aug 2017 21:18:11 -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 */
@@ -360,6 +362,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)
@@ -443,6 +446,7 @@ IDTVEC(resume_lapic_ltimer)
movl $IPL_CLOCK,CPUVAR(ILEVEL)
sti
cld
+ SMAP_CLAC
pushq %rbx
xorq %rdi,%rdi
call _C_LABEL(lapic_clockintr)
@@ -477,6 +481,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)
@@ -511,6 +516,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)
@@ -560,6 +566,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 25 Aug 2017 21:18:11 -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.172
diff -u -p -r1.172 locore.s
--- sys/arch/i386/i386/locore.s 6 Feb 2017 09:13:41 -0000 1.172
+++ sys/arch/i386/i386/locore.s 25 Aug 2017 21:18:11 -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.128
diff -u -p -r1.128 trap.c
--- sys/arch/i386/i386/trap.c 9 Mar 2017 20:31:41 -0000 1.128
+++ sys/arch/i386/i386/trap.c 25 Aug 2017 21:18:11 -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;