aboutsummaryrefslogtreecommitdiff
path: root/share/security/patches
diff options
context:
space:
mode:
authorGordon Tetlow <gordon@FreeBSD.org>2018-06-21 05:37:37 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2018-06-21 05:37:37 +0000
commit94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f (patch)
treeebe9a8e3d9a642726dd289d6f329efbf9f9e525d /share/security/patches
parent5f4afae8713e6dc8ce80c75a66d5e897828d7e1b (diff)
downloaddoc-94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f.tar.gz
doc-94c673d3909a12b9b7fb4d1a7c27d168aedf9b6f.zip
Add today's advisory and notices.
Approved by: so Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/head/; revision=51892
Diffstat (limited to 'share/security/patches')
-rw-r--r--share/security/patches/EN-18:07/pmap.patch78
-rw-r--r--share/security/patches/EN-18:07/pmap.patch.asc18
-rw-r--r--share/security/patches/SA-18:07/lazyfpu-11.patch373
-rw-r--r--share/security/patches/SA-18:07/lazyfpu-11.patch.asc18
4 files changed, 487 insertions, 0 deletions
diff --git a/share/security/patches/EN-18:07/pmap.patch b/share/security/patches/EN-18:07/pmap.patch
new file mode 100644
index 0000000000..e0b0f2ca7b
--- /dev/null
+++ b/share/security/patches/EN-18:07/pmap.patch
@@ -0,0 +1,78 @@
+--- sys/x86/xen/xen_apic.c.orig
++++ sys/x86/xen/xen_apic.c
+@@ -41,6 +41,7 @@
+ #include <machine/cpufunc.h>
+ #include <machine/cpu.h>
+ #include <machine/intr_machdep.h>
++#include <machine/md_var.h>
+ #include <machine/smp.h>
+
+ #include <x86/apicreg.h>
+@@ -439,6 +440,46 @@
+ invltlb_pcid_handler();
+ return (FILTER_HANDLED);
+ }
++
++static int
++xen_invltlb_invpcid_pti(void *arg)
++{
++
++ invltlb_invpcid_pti_handler();
++ return (FILTER_HANDLED);
++}
++
++static int
++xen_invlpg_invpcid_handler(void *arg)
++{
++
++ invlpg_invpcid_handler();
++ return (FILTER_HANDLED);
++}
++
++static int
++xen_invlpg_pcid_handler(void *arg)
++{
++
++ invlpg_pcid_handler();
++ return (FILTER_HANDLED);
++}
++
++static int
++xen_invlrng_invpcid_handler(void *arg)
++{
++
++ invlrng_invpcid_handler();
++ return (FILTER_HANDLED);
++}
++
++static int
++xen_invlrng_pcid_handler(void *arg)
++{
++
++ invlrng_pcid_handler();
++ return (FILTER_HANDLED);
++}
+ #endif
+
+ static int
+@@ -529,8 +570,18 @@
+
+ #ifdef __amd64__
+ if (pmap_pcid_enabled) {
+- xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = invpcid_works ?
+- xen_invltlb_invpcid : xen_invltlb_pcid;
++ if (pti)
++ xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
++ invpcid_works ? xen_invltlb_invpcid_pti :
++ xen_invltlb_pcid;
++ else
++ xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter =
++ invpcid_works ? xen_invltlb_invpcid :
++ xen_invltlb_pcid;
++ xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = invpcid_works ?
++ xen_invlpg_invpcid_handler : xen_invlpg_pcid_handler;
++ xen_ipis[IPI_TO_IDX(IPI_INVLRNG)].filter = invpcid_works ?
++ xen_invlrng_invpcid_handler : xen_invlrng_pcid_handler;
+ }
+ #endif
+ CPU_FOREACH(i)
diff --git a/share/security/patches/EN-18:07/pmap.patch.asc b/share/security/patches/EN-18:07/pmap.patch.asc
new file mode 100644
index 0000000000..269024cd58
--- /dev/null
+++ b/share/security/patches/EN-18:07/pmap.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN4FfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cI6+Q//dTnLur/Dtcz8y2b00OBdUvC1GL3kcFjFhk/fwcvceIdY1m6cC6u6ypxp
+Mehewv2YENgLw0fkIu61OsqtyCDmQ+O1LKuFNZpkYqPuiVRvhwAlXTHEWjVHmP8f
+52oSgspKxuZbpMKIDIZaQUiH3Ff7BcGIx8ru50wcsfe4dWXD0YJebqkK1etPuUYV
+HuMNrqbq7cH8BgBBaRzlAABqz6qeXjLZryyE3bDT4QGEdQPvyrs0muj/TtKzqmZB
+axX/V+aClQwnXARQ+EhGxCHDU+OoX4inH1N20+ZPwq7aGTjo0B19Yo/03cV1C7vs
+3NDJWKk4oxM6QP1bUIYZ37qlX+WSXH25q8PGtWucd/YdVZR04iXOwC4G1ncmEUWi
+1jEj9V7FOBzoLqCGdL2izibemVbKjza5FvODW2gq+Xzbe2F4eube0v12wOiLRED/
+mTn71RWsImgzsRvywIsGMkaZCZm4j7gWi53dgBqNteitmw75esM000tcKhy5T5yl
+VuxkhttAODFAujz7k4BRpUebzAf0autiRjec6QTHWek5jqD+bM3nGnlPVJMIzQrX
+GVibFJga+zrqHhXVXAEKM6QEgcF4nPOlwWOIJ1mBGxomnCM5dKt+Fr1W9lFsurun
+w83zqwX12Wz+gUENgBYeAawk9O86KoXC0gqf2pphjPnihN6x7Pc=
+=6sV+
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-18:07/lazyfpu-11.patch b/share/security/patches/SA-18:07/lazyfpu-11.patch
new file mode 100644
index 0000000000..39330e4cda
--- /dev/null
+++ b/share/security/patches/SA-18:07/lazyfpu-11.patch
@@ -0,0 +1,373 @@
+--- sys/amd64/amd64/cpu_switch.S.orig
++++ sys/amd64/amd64/cpu_switch.S
+@@ -105,10 +105,10 @@
+
+ /* have we used fp, and need a save? */
+ cmpq %rdi,PCPU(FPCURTHREAD)
+- jne 3f
++ jne 2f
+ movq PCB_SAVEFPU(%r8),%r8
+ clts
+- cmpl $0,use_xsave
++ cmpl $0,use_xsave(%rip)
+ jne 1f
+ fxsave (%r8)
+ jmp 2f
+@@ -120,12 +120,7 @@
+ /* This is patched to xsaveopt if supported, see fpuinit_bsp1() */
+ xsave (%r8)
+ movq %rcx,%rdx
+-2: smsw %ax
+- orb $CR0_TS,%al
+- lmsw %ax
+- xorl %eax,%eax
+- movq %rax,PCPU(FPCURTHREAD)
+-3:
++2:
+ /* Save is done. Now fire up new thread. Leave old vmspace. */
+ movq %rsi,%r12
+ movq %rdi,%r13
+@@ -212,6 +207,8 @@
+ movq PCB_RBX(%r8),%rbx
+ movq PCB_RIP(%r8),%rax
+ movq %rax,(%rsp)
++ movq PCPU(CURTHREAD),%rdi
++ call fpu_activate_sw
+ ret
+
+ /*
+--- sys/amd64/amd64/fpu.c.orig
++++ sys/amd64/amd64/fpu.c
+@@ -139,6 +139,11 @@
+ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+ SYSCTL_NULL_INT_PTR, 1, "Floating point instructions executed in hardware");
+
++int lazy_fpu_switch = 0;
++SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
++ &lazy_fpu_switch, 0,
++ "Lazily load FPU context after context switch");
++
+ int use_xsave; /* non-static for cpu_switch.S */
+ uint64_t xsave_mask; /* the same */
+ static uma_zone_t fpu_save_area_zone;
+@@ -204,6 +209,7 @@
+ u_int cp[4];
+ uint64_t xsave_mask_user;
+
++ TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
+ if ((cpu_feature2 & CPUID2_XSAVE) != 0) {
+ use_xsave = 1;
+ TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
+@@ -611,6 +617,45 @@
+ return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
+ }
+
++static void
++restore_fpu_curthread(struct thread *td)
++{
++ struct pcb *pcb;
++
++ /*
++ * Record new context early in case frstor causes a trap.
++ */
++ PCPU_SET(fpcurthread, td);
++
++ stop_emulating();
++ fpu_clean_state();
++ pcb = td->td_pcb;
++
++ if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
++ /*
++ * This is the first time this thread has used the FPU or
++ * the PCB doesn't contain a clean FPU state. Explicitly
++ * load an initial state.
++ *
++ * We prefer to restore the state from the actual save
++ * area in PCB instead of directly loading from
++ * fpu_initialstate, to ignite the XSAVEOPT
++ * tracking engine.
++ */
++ bcopy(fpu_initialstate, pcb->pcb_save,
++ cpu_max_ext_state_size);
++ fpurestore(pcb->pcb_save);
++ if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
++ fldcw(pcb->pcb_initial_fpucw);
++ if (PCB_USER_FPU(pcb))
++ set_pcb_flags(pcb, PCB_FPUINITDONE |
++ PCB_USERFPUINITDONE);
++ else
++ set_pcb_flags(pcb, PCB_FPUINITDONE);
++ } else
++ fpurestore(pcb->pcb_save);
++}
++
+ /*
+ * Device Not Available (DNA, #NM) exception handler.
+ *
+@@ -621,7 +666,9 @@
+ void
+ fpudna(void)
+ {
++ struct thread *td;
+
++ td = curthread;
+ /*
+ * This handler is entered with interrupts enabled, so context
+ * switches may occur before critical_enter() is executed. If
+@@ -635,49 +682,38 @@
+
+ KASSERT((curpcb->pcb_flags & PCB_FPUNOSAVE) == 0,
+ ("fpudna while in fpu_kern_enter(FPU_KERN_NOCTX)"));
+- if (PCPU_GET(fpcurthread) == curthread) {
+- printf("fpudna: fpcurthread == curthread\n");
++ if (__predict_false(PCPU_GET(fpcurthread) == td)) {
++ /*
++ * Some virtual machines seems to set %cr0.TS at
++ * arbitrary moments. Silently clear the TS bit
++ * regardless of the eager/lazy FPU context switch
++ * mode.
++ */
+ stop_emulating();
+- critical_exit();
+- return;
++ } else {
++ if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
++ panic(
++ "fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
++ PCPU_GET(fpcurthread),
++ PCPU_GET(fpcurthread)->td_tid, td, td->td_tid);
++ }
++ restore_fpu_curthread(td);
+ }
+- if (PCPU_GET(fpcurthread) != NULL) {
+- panic("fpudna: fpcurthread = %p (%d), curthread = %p (%d)\n",
+- PCPU_GET(fpcurthread), PCPU_GET(fpcurthread)->td_tid,
+- curthread, curthread->td_tid);
+- }
+- stop_emulating();
+- /*
+- * Record new context early in case frstor causes a trap.
+- */
+- PCPU_SET(fpcurthread, curthread);
++ critical_exit();
++}
+
+- fpu_clean_state();
++void fpu_activate_sw(struct thread *td); /* Called from the context switch */
++void
++fpu_activate_sw(struct thread *td)
++{
+
+- if ((curpcb->pcb_flags & PCB_FPUINITDONE) == 0) {
+- /*
+- * This is the first time this thread has used the FPU or
+- * the PCB doesn't contain a clean FPU state. Explicitly
+- * load an initial state.
+- *
+- * We prefer to restore the state from the actual save
+- * area in PCB instead of directly loading from
+- * fpu_initialstate, to ignite the XSAVEOPT
+- * tracking engine.
+- */
+- bcopy(fpu_initialstate, curpcb->pcb_save,
+- cpu_max_ext_state_size);
+- fpurestore(curpcb->pcb_save);
+- if (curpcb->pcb_initial_fpucw != __INITIAL_FPUCW__)
+- fldcw(curpcb->pcb_initial_fpucw);
+- if (PCB_USER_FPU(curpcb))
+- set_pcb_flags(curpcb,
+- PCB_FPUINITDONE | PCB_USERFPUINITDONE);
+- else
+- set_pcb_flags(curpcb, PCB_FPUINITDONE);
+- } else
+- fpurestore(curpcb->pcb_save);
+- critical_exit();
++ if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
++ !PCB_USER_FPU(td->td_pcb)) {
++ PCPU_SET(fpcurthread, NULL);
++ start_emulating();
++ } else if (PCPU_GET(fpcurthread) != td) {
++ restore_fpu_curthread(td);
++ }
+ }
+
+ void
+--- sys/i386/i386/swtch.s.orig
++++ sys/i386/i386/swtch.s
+@@ -293,6 +293,12 @@
+ cpu_switch_load_gs:
+ mov PCB_GS(%edx),%gs
+
++ pushl %edx
++ pushl PCPU(CURTHREAD)
++ call npxswitch
++ popl %edx
++ popl %edx
++
+ /* Test if debug registers should be restored. */
+ testl $PCB_DBREGS,PCB_FLAGS(%edx)
+ jz 1f
+--- sys/i386/isa/npx.c.orig
++++ sys/i386/isa/npx.c
+@@ -191,6 +191,11 @@
+ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+ &hw_float, 0, "Floating point instructions executed in hardware");
+
++int lazy_fpu_switch = 0;
++SYSCTL_INT(_hw, OID_AUTO, lazy_fpu_switch, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
++ &lazy_fpu_switch, 0,
++ "Lazily load FPU context after context switch");
++
+ int use_xsave;
+ uint64_t xsave_mask;
+ static uma_zone_t fpu_save_area_zone;
+@@ -327,6 +332,7 @@
+ u_int cp[4];
+ uint64_t xsave_mask_user;
+
++ TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch);
+ if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) {
+ use_xsave = 1;
+ TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
+@@ -785,47 +791,20 @@
+ return (fpetable[(mxcsr & (~mxcsr >> 7)) & 0x3f]);
+ }
+
+-/*
+- * Implement device not available (DNA) exception
+- *
+- * It would be better to switch FP context here (if curthread != fpcurthread)
+- * and not necessarily for every context switch, but it is too hard to
+- * access foreign pcb's.
+- */
+-
+-static int err_count = 0;
+-
+-int
+-npxdna(void)
++static void
++restore_npx_curthread(struct thread *td, struct pcb *pcb)
+ {
+
+- if (!hw_float)
+- return (0);
+- critical_enter();
+- if (PCPU_GET(fpcurthread) == curthread) {
+- printf("npxdna: fpcurthread == curthread %d times\n",
+- ++err_count);
+- stop_emulating();
+- critical_exit();
+- return (1);
+- }
+- if (PCPU_GET(fpcurthread) != NULL) {
+- printf("npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
+- PCPU_GET(fpcurthread),
+- PCPU_GET(fpcurthread)->td_proc->p_pid,
+- curthread, curthread->td_proc->p_pid);
+- panic("npxdna");
+- }
+- stop_emulating();
+ /*
+ * Record new context early in case frstor causes a trap.
+ */
+- PCPU_SET(fpcurthread, curthread);
++ PCPU_SET(fpcurthread, td);
+
++ stop_emulating();
+ if (cpu_fxsr)
+ fpu_clean_state();
+
+- if ((curpcb->pcb_flags & PCB_NPXINITDONE) == 0) {
++ if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) {
+ /*
+ * This is the first time this thread has used the FPU or
+ * the PCB doesn't contain a clean FPU state. Explicitly
+@@ -836,18 +815,54 @@
+ * npx_initialstate, to ignite the XSAVEOPT
+ * tracking engine.
+ */
+- bcopy(npx_initialstate, curpcb->pcb_save, cpu_max_ext_state_size);
+- fpurstor(curpcb->pcb_save);
+- if (curpcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
+- fldcw(curpcb->pcb_initial_npxcw);
+- curpcb->pcb_flags |= PCB_NPXINITDONE;
+- if (PCB_USER_FPU(curpcb))
+- curpcb->pcb_flags |= PCB_NPXUSERINITDONE;
++ bcopy(npx_initialstate, pcb->pcb_save, cpu_max_ext_state_size);
++ fpurstor(pcb->pcb_save);
++ if (pcb->pcb_initial_npxcw != __INITIAL_NPXCW__)
++ fldcw(pcb->pcb_initial_npxcw);
++ pcb->pcb_flags |= PCB_NPXINITDONE;
++ if (PCB_USER_FPU(pcb))
++ pcb->pcb_flags |= PCB_NPXUSERINITDONE;
+ } else {
+- fpurstor(curpcb->pcb_save);
++ fpurstor(pcb->pcb_save);
+ }
++}
++
++/*
++ * Implement device not available (DNA) exception
++ *
++ * It would be better to switch FP context here (if curthread != fpcurthread)
++ * and not necessarily for every context switch, but it is too hard to
++ * access foreign pcb's.
++ */
++int
++npxdna(void)
++{
++ struct thread *td;
++
++ if (!hw_float)
++ return (0);
++ td = curthread;
++ critical_enter();
++ if (__predict_false(PCPU_GET(fpcurthread) == td)) {
++ /*
++ * Some virtual machines seems to set %cr0.TS at
++ * arbitrary moments. Silently clear the TS bit
++ * regardless of the eager/lazy FPU context switch
++ * mode.
++ */
++ stop_emulating();
++ } else {
++ if (__predict_false(PCPU_GET(fpcurthread) != NULL)) {
++ printf(
++ "npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n",
++ PCPU_GET(fpcurthread),
++ PCPU_GET(fpcurthread)->td_proc->p_pid,
++ td, td->td_proc->p_pid);
++ panic("npxdna");
++ }
++ restore_npx_curthread(td, td->td_pcb);
++ }
+ critical_exit();
+-
+ return (1);
+ }
+
+@@ -869,10 +884,22 @@
+ xsaveopt((char *)addr, xsave_mask);
+ else
+ fpusave(addr);
+- start_emulating();
+- PCPU_SET(fpcurthread, NULL);
+ }
+
++void npxswitch(struct thread *td, struct pcb *pcb);
++void
++npxswitch(struct thread *td, struct pcb *pcb)
++{
++
++ if (lazy_fpu_switch || (td->td_pflags & TDP_KTHREAD) != 0 ||
++ !PCB_USER_FPU(pcb)) {
++ start_emulating();
++ PCPU_SET(fpcurthread, NULL);
++ } else if (PCPU_GET(fpcurthread) != td) {
++ restore_npx_curthread(td, pcb);
++ }
++}
++
+ /*
+ * Unconditionally save the current co-processor state across suspend and
+ * resume.
diff --git a/share/security/patches/SA-18:07/lazyfpu-11.patch.asc b/share/security/patches/SA-18:07/lazyfpu-11.patch.asc
new file mode 100644
index 0000000000..2479fd9255
--- /dev/null
+++ b/share/security/patches/SA-18:07/lazyfpu-11.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlsrN2xfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJY2Q/+KyfnyHr1YphdZkXYLPTtIKCJasfR1jWSh+6Amr/QDCSvMSvvjvbg6PL0
+snVq9108ycrKU7xOBebBQRYNYuS1KlRsjcw396dhpjoVwaoQ5mxuWqeiRbSudy/N
+hFuX91E22832j1o4AsovV/vpqTREz0o4BnMrw9fUiZvuhEiPXs3VHoBcn3lCflXf
+ubJVptVVCjIK7miVY/oGtvUnzNoSujjNQekpdhHmKyWxU+PrHHhh/kJg+CVEKNr9
+IkeJV8w2NkpbXEkf59rMUxoMd4OkxlVlNuoPqWekXBwcLGwd5Uux7GAeI+X8crGA
+cim6F8zniozsip7AptQU5e8yQL/mKYsoWpsghASEu1uanvwTjkmu82f3ER7/FX08
+0MmhWcSkqGEvKlenQAajCLA7CTzXiMcB3QoCd3VYUmXZOJqcnDAijaDRZ/FMuVJV
+wGDFus4cMiDhuC+WJTE699DGmveov3C3N6O65K7KNMdsECFwfP38xzzv+wvjzCbj
+JzaYW14YYr5cgsBdL24z0Yl8Pz9vXexiFdPH+VxOaRIHZGMSQqRe0TXG85M8Pv9F
+X0tje/gbMMnBpgHui3lUY3x45srRLSn8qt/v/j3W5zoxXINZTDTdqoZT7T9pKWpD
+EmWdlLMRDDDvQceXdDebZytM/cMAUf2PS2RtWipSwC4Frqz9eYY=
+=dd45
+-----END PGP SIGNATURE-----