Control for Special Register Buffer Data Sampling mitigation.

New microcode update for Intel enables mitigation for SRBDS, which
slows down RDSEED and related instructions.  The update also provides
a control to limit the mitigation to SGX enclaves, which should
restore the speed of random generator by the cost of potential
cross-core bufer sampling.

See https://software.intel.com/security-software-guidance/insights/deep-dive-special-register-buffer-data-sampling

GIve the user control over it.

Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D25221
This commit is contained in:
Konstantin Belousov 2020-06-12 22:14:45 +00:00
parent 958d257ed5
commit 17edf152e5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362130
6 changed files with 69 additions and 1 deletions

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 16, 2020
.Dd June 11, 2020
.Dt SECURITY 7
.Os
.Sh NAME
@ -1040,6 +1040,13 @@ page table format used by hypervisors on Intel CPUs to map the guest
physical address space to machine physical memory.
May be disabled to work around a CPU Erratum called
Machine Check Error Avoidance on Page Size Change.
.It Dv machdep.mitigations.rngds.enable
amd64 and i386.
Controls mitigation of Special Register Buffer Data Sampling versus
optimization of the MCU access.
When set to zero, the mitigation is disabled, and the RDSEED and RDRAND
instructions do not incur serialization overhead for shared buffer accesses,
and do not serialize off-core memory accessses.
.It Dv kern.elf32.aslr.enable
Controls system-global Address Space Layout Randomization (ASLR) for
normal non-PIE (Position Independent Executable) 32bit binaries.

View File

@ -270,6 +270,7 @@ initializecpu(void)
hw_ibrs_recalculate(false);
hw_ssb_recalculate(false);
amd64_syscall_ret_flush_l1d_recalc();
x86_rngds_mitg_recalculate(false);
switch (cpu_vendor_id) {
case CPU_VENDOR_AMD:
case CPU_VENDOR_HYGON:

View File

@ -1791,6 +1791,9 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
TUNABLE_INT_FETCH("machdep.mitigations.taa.enable", &x86_taa_enable);
TUNABLE_INT_FETCH("machdep.mitigations.rndgs.enable",
&x86_rngds_mitg_enable);
finishidentcpu(); /* Final stage of CPU initialization */
initializecpu(); /* Initialize CPU registers */

View File

@ -547,6 +547,7 @@ cpuctl_do_eval_cpu_features(int cpu, struct thread *td)
#endif
hw_mds_recalculate();
x86_taa_recalculate();
x86_rngds_mitg_recalculate(true);
printcpuinfo();
return (0);
}

View File

@ -95,6 +95,7 @@ extern int hw_mds_disable;
extern int hw_ssb_active;
extern int x86_taa_enable;
extern int cpu_flush_rsb_ctxsw;
extern int x86_rngds_mitg_enable;
struct pcb;
struct thread;
@ -139,6 +140,7 @@ void hw_ibrs_recalculate(bool all_cpus);
void hw_mds_recalculate(void);
void hw_ssb_recalculate(bool all_cpus);
void x86_taa_recalculate(void);
void x86_rngds_mitg_recalculate(bool all_cpus);
void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame);
void nmi_call_kdb_smp(u_int type, struct trapframe *frame);
void nmi_handle_intr(u_int type, struct trapframe *frame);

View File

@ -1402,6 +1402,60 @@ SYSCTL_INT(_machdep_mitigations, OID_AUTO, flush_rsb_ctxsw,
CTLFLAG_RW | CTLFLAG_NOFETCH, &cpu_flush_rsb_ctxsw, 0,
"Flush Return Stack Buffer on context switch");
SYSCTL_NODE(_machdep_mitigations, OID_AUTO, rngds,
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"MCU Optimization, disable RDSEED mitigation");
int x86_rngds_mitg_enable = 1;
void
x86_rngds_mitg_recalculate(bool all_cpus)
{
if ((cpu_stdext_feature3 & CPUID_STDEXT3_MCUOPT) == 0)
return;
x86_msr_op(MSR_IA32_MCU_OPT_CTRL,
(x86_rngds_mitg_enable ? MSR_OP_OR : MSR_OP_ANDNOT) |
(all_cpus ? MSR_OP_RENDEZVOUS : MSR_OP_LOCAL),
IA32_RNGDS_MITG_DIS);
}
static int
sysctl_rngds_mitg_enable_handler(SYSCTL_HANDLER_ARGS)
{
int error, val;
val = x86_rngds_mitg_enable;
error = sysctl_handle_int(oidp, &val, 0, req);
if (error != 0 || req->newptr == NULL)
return (error);
x86_rngds_mitg_enable = val;
x86_rngds_mitg_recalculate(true);
return (0);
}
SYSCTL_PROC(_machdep_mitigations_rngds, OID_AUTO, enable, CTLTYPE_INT |
CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, NULL, 0,
sysctl_rngds_mitg_enable_handler, "I",
"MCU Optimization, disabling RDSEED mitigation control "
"(0 - mitigation disabled (RDSEED optimized), 1 - mitigation enabled");
static int
sysctl_rngds_state_handler(SYSCTL_HANDLER_ARGS)
{
const char *state;
if ((cpu_stdext_feature3 & CPUID_STDEXT3_MCUOPT) == 0) {
state = "Not applicable";
} else if (x86_rngds_mitg_enable == 0) {
state = "RDSEED not serialized";
} else {
state = "Mitigated";
}
return (SYSCTL_OUT(req, state, strlen(state)));
}
SYSCTL_PROC(_machdep_mitigations_rngds, OID_AUTO, state,
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
sysctl_rngds_state_handler, "A",
"MCU Optimization state");
/*
* Enable and restore kernel text write permissions.
* Callers must ensure that disable_wp()/restore_wp() are executed