Skip to content

Commit e45f11c

Browse files
committed
x86/bugs: Provide boot parameters for the spec_store_bypass_disable mitigation
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. Memory Disambiguation can expose 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. As a first step to mitigate against such attacks, provide two boot 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 an implementation of Speculative Store Bypass and picks the most appropriate mitigation. - on - disable Speculative Store Bypass - off - enable Speculative Store Bypass [ tglx: Reordered the checks so that the whole evaluation is not done when the CPU does not support RDS ] Signed-off-by: Konrad Rzeszutek Wilk <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Reviewed-by: Ingo Molnar <[email protected]> (cherry picked from commit 24f7fc8) Orabug: 28034177 CVE: CVE-2018-3639 Signed-off-by: Konrad Rzeszutek Wilk <[email protected]> Tested-by: Mihai Carabas <[email protected]> Reviewed-by: Mihai Carabas <[email protected]> Reviewed-by: John Haxby <[email protected]> Conflicts: Documentation/admin-guide/kernel-parameters.txt [As we have spectre_v2_heuristics] arch/x86/include/asm/cpufeatures.h [As we are already using that CPU bit, hence we have to use the next one]
1 parent bd38182 commit e45f11c

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,9 @@
26142614
allow data leaks with this option, which is equivalent
26152615
to spectre_v2=off.
26162616

2617+
nospec_store_bypass_disable
2618+
[HW] Disable all mitigations for the Speculative Store Bypass vulnerability
2619+
26172620
noxsave [BUGS=X86] Disables x86 extended register state save
26182621
and restore using xsave. The kernel will fallback to
26192622
enabling legacy floating-point and sse state.
@@ -3946,6 +3949,36 @@
39463949
Not specifying this option is equivalent to
39473950
spectre_v2=auto.
39483951

3952+
spec_store_bypass_disable=
3953+
[HW] Control Speculative Store Bypass (SSB) Disable mitigation
3954+
(Speculative Store Bypass vulnerability)
3955+
3956+
Certain CPUs are vulnerable to an exploit against a
3957+
a common industry wide performance optimization known
3958+
as "Speculative Store Bypass" in which recent stores
3959+
to the same memory location may not be observed by
3960+
later loads during speculative execution. The idea
3961+
is that such stores are unlikely and that they can
3962+
be detected prior to instruction retirement at the
3963+
end of a particular speculation execution window.
3964+
3965+
In vulnerable processors, the speculatively forwarded
3966+
store can be used in a cache side channel attack, for
3967+
example to read memory to which the attacker does not
3968+
directly have access (e.g. inside sandboxed code).
3969+
3970+
This parameter controls whether the Speculative Store
3971+
Bypass optimization is used.
3972+
3973+
on - Unconditionally disable Speculative Store Bypass
3974+
off - Unconditionally enable Speculative Store Bypass
3975+
auto - Kernel detects whether the CPU model contains an
3976+
implementation of Speculative Store Bypass and
3977+
picks the most appropriate mitigation
3978+
3979+
Not specifying this option is equivalent to
3980+
spec_store_bypass_disable=auto.
3981+
39493982
spectre_v2_heuristics=
39503983
[X86] Control Spectre_v2 variant heuristics.
39513984

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@
216216
#define X86_FEATURE_IBRS_ALL ( 7*32+23) /* IBRS all the time */
217217
#define X86_FEATURE_VMEXIT_RSB_FULL ( 7*32+27) /* "" Whether to stuff the RSB on VMEXIT. */
218218
#define X86_FEATURE_STUFF_RSB ( 7*32+28) /* "" Whether to stuff the RSB (usually dependent on !SMEP) */
219+
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+29) /* "" Disable Speculative Store Bypass. */
219220

220221
/* Virtualization flags: Linux defined, word 8 */
221222
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */

arch/x86/include/asm/nospec-branch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ extern u64 x86_spec_ctrl_get_default(void);
238238
extern void x86_spec_ctrl_set_guest(u64);
239239
extern void x86_spec_ctrl_restore_host(u64);
240240

241+
/* The Speculative Store Bypass disable variants */
242+
enum ssb_mitigation {
243+
SPEC_STORE_BYPASS_NONE,
244+
SPEC_STORE_BYPASS_DISABLE,
245+
};
246+
241247
extern char __indirect_thunk_start[];
242248
extern char __indirect_thunk_end[];
243249

arch/x86/kernel/cpu/bugs.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ int __init spectre_v2_heuristics_setup(char *p)
8484
__setup("spectre_v2_heuristics=", spectre_v2_heuristics_setup);
8585

8686
static void __init spectre_v2_select_mitigation(void);
87+
static void __init ssb_select_mitigation(void);
8788

8889
/*
8990
* Our boot-time value of the SPEC_CTRL MSR. We read it once so that any
@@ -123,6 +124,12 @@ void __init check_bugs(void)
123124
/* Select the proper spectre mitigation before patching alternatives */
124125
spectre_v2_select_mitigation();
125126

127+
/*
128+
* Select proper mitigation for any exposure to the Speculative Store
129+
* Bypass vulnerability.
130+
*/
131+
ssb_select_mitigation();
132+
126133
#ifdef CONFIG_X86_32
127134
/*
128135
* Check whether we are able to run this kernel safely on SMP.
@@ -590,6 +597,99 @@ static void __init spectre_v2_select_mitigation(void)
590597
}
591598
}
592599

600+
#undef pr_fmt
601+
#define pr_fmt(fmt) "Speculative Store Bypass: " fmt
602+
603+
static enum ssb_mitigation ssb_mode = SPEC_STORE_BYPASS_NONE;
604+
605+
/* The kernel command line selection */
606+
enum ssb_mitigation_cmd {
607+
SPEC_STORE_BYPASS_CMD_NONE,
608+
SPEC_STORE_BYPASS_CMD_AUTO,
609+
SPEC_STORE_BYPASS_CMD_ON,
610+
};
611+
612+
static const char *ssb_strings[] = {
613+
[SPEC_STORE_BYPASS_NONE] = "Vulnerable",
614+
[SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled"
615+
};
616+
617+
static const struct {
618+
const char *option;
619+
enum ssb_mitigation_cmd cmd;
620+
} ssb_mitigation_options[] = {
621+
{ "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */
622+
{ "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */
623+
{ "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */
624+
};
625+
626+
static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
627+
{
628+
enum ssb_mitigation_cmd cmd = SPEC_STORE_BYPASS_CMD_AUTO;
629+
char arg[20];
630+
int ret, i;
631+
632+
if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable")) {
633+
return SPEC_STORE_BYPASS_CMD_NONE;
634+
} else {
635+
ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable",
636+
arg, sizeof(arg));
637+
if (ret < 0)
638+
return SPEC_STORE_BYPASS_CMD_AUTO;
639+
640+
for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) {
641+
if (!match_option(arg, ret, ssb_mitigation_options[i].option))
642+
continue;
643+
644+
cmd = ssb_mitigation_options[i].cmd;
645+
break;
646+
}
647+
648+
if (i >= ARRAY_SIZE(ssb_mitigation_options)) {
649+
pr_err("unknown option (%s). Switching to AUTO select\n", arg);
650+
return SPEC_STORE_BYPASS_CMD_AUTO;
651+
}
652+
}
653+
654+
return cmd;
655+
}
656+
657+
static enum ssb_mitigation_cmd __init __ssb_select_mitigation(void)
658+
{
659+
enum ssb_mitigation mode = SPEC_STORE_BYPASS_NONE;
660+
enum ssb_mitigation_cmd cmd;
661+
662+
if (!boot_cpu_has(X86_FEATURE_RDS))
663+
return mode;
664+
665+
cmd = ssb_parse_cmdline();
666+
if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS) &&
667+
(cmd == SPEC_STORE_BYPASS_CMD_NONE ||
668+
cmd == SPEC_STORE_BYPASS_CMD_AUTO))
669+
return mode;
670+
671+
switch (cmd) {
672+
case SPEC_STORE_BYPASS_CMD_AUTO:
673+
case SPEC_STORE_BYPASS_CMD_ON:
674+
mode = SPEC_STORE_BYPASS_DISABLE;
675+
break;
676+
case SPEC_STORE_BYPASS_CMD_NONE:
677+
break;
678+
}
679+
680+
if (mode != SPEC_STORE_BYPASS_NONE)
681+
setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE);
682+
return mode;
683+
}
684+
685+
static void ssb_select_mitigation()
686+
{
687+
ssb_mode = __ssb_select_mitigation();
688+
689+
if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS))
690+
pr_info("%s\n", ssb_strings[ssb_mode]);
691+
}
692+
593693
#undef pr_fmt
594694

595695
#ifdef CONFIG_SYSFS
@@ -617,6 +717,9 @@ ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
617717
ibrs_firmware ? ", IBRS_FW" : "",
618718
spectre_v2_module_string());
619719

720+
case X86_BUG_SPEC_STORE_BYPASS:
721+
return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
722+
620723
default:
621724
break;
622725
}

0 commit comments

Comments
 (0)