Linux Patch #6
Subsystems (3)
PATCH v6 6/10 Linux Patch #6
Contemporary high performance processors use a common industry-wide optimization known as "Speculative Store Bypass" in which loads from addresses to which a recent store has occurred may (speculatively) see an older value. Intel refers to this feature as "Memory Disambiguation", which is part of their "Smart Memory Access" capability in Nehalem and later generation processors. The capability to turn it off has a different name.
Some processors have an implementation bug that enables a cache side-channel attack against such speculatively read values. An attacker can create exploit code that allows them to read memory outside of a sandbox environment (for example, malicious JavaScript in a web page), or to perform more complex attacks against code running within the same privilege level, e.g. via the stack.
We provide two command line control knobs:
nospec_store_bypass_disable
spec_store_bypass_disable=[off,auto,on]
By default affected x86 processors will power on with Speculative Store Bypass enabled. Hence the provided kernel parameters are written from the point of view of whether to enable a mitigation or not. The parameters are as follows:
- auto - kernel detects whether your CPU model contains a vulnerable implementation of Speculative Store Bypass and picks the most appropriate mitigation
Some CPUs may have a Speculative Store Bypass implementation which is not vulnerable to the described attacks. For those, the 'auto' (default) option will pick the right choice.
- on - disable Speculative Store Bypass
- off - enable Speculative Store Bypass
---
v1.3:
- Wrong array was used when figuring mdd_v4= arguments
- If broken microcode found, also disable MD feature.
- s/mdd_v4/mdd/
- s/kernel/userpsace/
- Fix up the commit description
v1.4:
- Incorporate various feedback and suggestions from Jon Masters
- Change mdd parameters to allow only big hammer on/off for now
- Introduce "ssbd" industry standard term for cross-architecture
- Use mdd_ and MDD_ prefixes to clearly spell out that "enable" means we are actually disabling a CPU processor feature (MD)
v2:
- s/mdd/ssb/ in the x86 code to match with the 'ssb' part
v3:
- rip out mdd.
- remove 'Haswell' and such and replace with 'contemporary'
- s/ssb/spec_store_bypass/ and various other cleanups (Jon Masters)
v4: Rip out 'Memory Disambiguation Disable'
- Fix up documentation.
- Rip out the X86_FEATURE_STBUF_BYPASS
- s/X86_FEATURE_STBUF_MITIGATE/X86_FEATURE_STBUF_BYPASS_MITIGATE/
- On the functions change spec_store_bypass_ to ssb_
v5: Changed title.
- s/X86_FEATURE_STBUF_BYPASS_MITIGATE/X86_FEATURE_SPEC_STORE_BYPASS_DISABLE/
- Add logic to get out of ssb_parse_cmdline is bug is not present
v6: Added Memory Disambiguation to the title.
Added Reviewed-by
--- Documentation/admin-guide/kernel-parameters.txt | 32 +++++++++ arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/nospec-branch.h | 6 ++ arch/x86/kernel/cpu/bugs.c | 96 +++++++++++++++++++++++++ 4 files changed, 135 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +32 -0
@@ -2680,6 +2680,9 @@ allow data leaks with this option, which is equivalent to spectre_v2=off. + nospec_store_bypass_disable + [HW] Disable all mitigations for the Speculative Store Bypass vulnerability + noxsave [BUGS=X86] Disables x86 extended register state save and restore using xsave. The kernel will fallback to enabling legacy floating-point and sse state.
@@ -4025,6 +4028,35 @@ Not specifying this option is equivalent to spectre_v2=auto. + spec_store_bypass_disable= + [HW] Control Speculative Store Bypass (SSB) Disable mitigation + (Speculative Store Bypass vulnerability) + Certain CPUs are vulnerable to an exploit against a + a common industry wide performance optimization known + as "Speculative Store Bypass" in which recent stores + to the same memory location may not be observed by + later loads during speculative execution. The idea + is that such stores are unlikely and that they can + be detected prior to instruction retirement at the + end of a particular speculation execution window. + + In vulnerable processors, the speculatively forwarded + store can be used in a cache side channel attack, for + example to read memory to which the attacker does not + directly have access (e.g. inside sandboxed code). + + This parameter controls whether the Speculative Store + Bypass optimization is used. + + on - unconditionally disable Speculative Store Bypass + off - unconditionally enable Speculative Store Bypass + auto - kernel detects whether your CPU model contains a + vulnerable implementation of Speculative Store + Bypass and picks the most appropriate mitigation + + Not specifying this option is equivalent to + spec_store_bypass_disable=auto. + spia_io_base= [HW,MTD] spia_fio_base= spia_pedr=
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -214,6 +214,7 @@#define X86_FEATURE_USE_IBPB ( 7*32+21)/* "" Indirect Branch Prediction Barrier enabled */ #define X86_FEATURE_USE_IBRS_FW ( 7*32+22)/* "" Use IBRS during runtime firmware calls */ +#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23)/* "" Disable Speculative Store Bypass. */ /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0)/* Intel TPR Shadow */
arch/x86/include/asm/nospec-branch.h +6 -0
@@ -238,6 +238,12 @@ extern u64 x86_get_default_spec_ctrl(void);extern void x86_set_guest_spec_ctrl (u64 );extern void x86_restore_host_spec_ctrl (u64 ); +/* The Speculative Store Bypass disable variants */ +enum ssb_mitigation { +SPEC_STORE_BYPASS_NONE , +SPEC_STORE_BYPASS_DISABLE , +}; +extern char __indirect_thunk_start[];extern char __indirect_thunk_end[];
arch/x86/kernel/cpu/bugs.c +96 -0
120 lines not on this page · raw message
Signature · 1 line
2.14.3
arch/x86/kernel/cpu/bugs.c static void __init spectre_v2_select_mitigation(void) · line 400
Quoted 8 lines · speck for konrad.wilk_at_oracle.com
arch/x86/kernel/cpu/bugs.c +8
-0+static enum ssb_mitigation_cmd __init ssb_parse_cmdline (void ) +{ +char arg[20 ]; +int ret, i; +enum ssb_mitigation_cmd cmd =SPEC_STORE_BYPASS_CMD_AUTO ; + +if (!boot_cpu_has (X86_BUG_SPEC_STORE_BYPASS )) +return SPEC_STORE_BYPASS_CMD_NONE ;
This is pointless. See below.
arch/x86/kernel/cpu/bugs.c static void __init spectre_v2_select_mitigation(void) · line 404
Quoted 3 lines
arch/x86/kernel/cpu/bugs.c +3
-0+if (cmdline_find_option_bool (boot_command_line,"nospec_store_bypass_disable" )) +return SPEC_STORE_BYPASS_CMD_NONE ; +else {
Missing curly brackets for the if path
Quoted 21 lines
arch/x86/kernel/cpu/bugs.c +21
-0+ ret =cmdline_find_option (boot_command_line,"spec_store_bypass_disable" , + arg,sizeof (arg)); +if (ret <0 ) +return SPEC_STORE_BYPASS_CMD_AUTO ; + +for (i =0 ; i <ARRAY_SIZE (ssb_mitigation_options); i++) { +if (!match_option (arg, ret, ssb_mitigation_options[i].option)) +continue ; + + cmd = ssb_mitigation_options[i].cmd; +break ; + } + +if (i >=ARRAY_SIZE (ssb_mitigation_options)) { +pr_err ("unknown option (%s). Switching to AUTO select\n" , arg); +return SPEC_STORE_BYPASS_CMD_AUTO ; + } + } + +return cmd; +}
arch/x86/kernel/cpu/bugs.c static void __init spectre_v2_select_mitigation(void) · line 435
Quoted 10 lines
arch/x86/kernel/cpu/bugs.c +10
-0+ +static void __init ssb_select_mitigation (void ) +{ +enum ssb_mitigation_cmd cmd =ssb_parse_cmdline (); +enum ssb_mitigation mode =SPEC_STORE_BYPASS_NONE ; + +if (!boot_cpu_has_bug (X86_BUG_SPEC_STORE_BYPASS ) && + (cmd ==SPEC_STORE_BYPASS_CMD_NONE || + cmd ==SPEC_STORE_BYPASS_CMD_AUTO )) +return ;
This check is bogus along with the one above. because the one above returns SPEC_STORE_BYPASS_CMD_NONE when X86_BUG_SPEC_STORE_BYPASS is not set.
This also wants to have:
if (!boot_cpu_has(X86_FEATURE_RDS)) return;
because if that stuff is not available then trying to fiddle with the MSR is pointless and even dangerous on AMD.
The KVM code does check that FEATURE bit as well, but I cannot find a place where this is set for Intel. It's set for AMD though.
And the resulting code sequence is:
enum ssb_mitigation mode = SPEC_STORE_BYPASS_NONE; enum ssb_mitigation_cmd cmd; if (!boot_cpu_has(X86_FEATURE_RDS)) return;
cmd = ssb_parse_cmdline();
if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS) && (cmd == SPEC_STORE_BYPASS_CMD_NONE || cmd == SPEC_STORE_BYPASS_CMD_AUTO)) return;
Then it does what you wanted it to do.
Thanks,
tglx
Quoted 8 lines · speck for Thomas Gleixner
On Thu, 26 Apr 2018, speck for konrad.wilk_at_oracle.com wrote:
This also wants to have:if (!boot_cpu_has(X86_FEATURE_RDS)) return;because if that stuff is not available then trying to fiddle with the MSR is pointless and even dangerous on AMD.
It's even dangerous on Intel.
The bit is not necessarily ignored:
May be true for many existing projects but not guaranteed (e.g. low end Atom phones may #GP on attempts to set this bit; also parts without latest microcode update or without IA32_SPEC_CTRL support)
Enumeration of MSR bit: CPUID.7.0.EDX[31]
Thanks,
tglx
Quoted 4 lines · speck for Thomas Gleixner
On Thu, 26 Apr 2018, speck for konrad.wilk_at_oracle.com wrote:
The KVM code does check that FEATURE bit as well, but I cannot find a place where this is set for Intel. It's set for AMD though.
Bah. I hate the cpufeatures and cpu init maze. Its stored along with the rest of level 7 EDX ... and AMD just reuses it.