x86/speculation: Make "seccomp" the default mode for Speculative Store Bypass

Unless explicitly opted out of, anything running under seccomp will have
SSB mitigations enabled. Choosing the "prctl" mode will disable this.

[ tglx: Adjusted it to the new arch_seccomp_spec_mitigate() mechanism ]

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Kees Cook 2018-05-03 14:37:54 -07:00 committed by Thomas Gleixner
parent 8bf37d8c06
commit f21b53b20c
3 changed files with 41 additions and 18 deletions

View File

@ -4049,19 +4049,27 @@
This parameter controls whether the Speculative Store This parameter controls whether the Speculative Store
Bypass optimization is used. Bypass optimization is used.
on - Unconditionally disable Speculative Store Bypass on - Unconditionally disable Speculative Store Bypass
off - Unconditionally enable Speculative Store Bypass off - Unconditionally enable Speculative Store Bypass
auto - Kernel detects whether the CPU model contains an auto - Kernel detects whether the CPU model contains an
implementation of Speculative Store Bypass and implementation of Speculative Store Bypass and
picks the most appropriate mitigation. picks the most appropriate mitigation. If the
prctl - Control Speculative Store Bypass per thread CPU is not vulnerable, "off" is selected. If the
via prctl. Speculative Store Bypass is enabled CPU is vulnerable the default mitigation is
for a process by default. The state of the control architecture and Kconfig dependent. See below.
is inherited on fork. prctl - Control Speculative Store Bypass per thread
via prctl. Speculative Store Bypass is enabled
for a process by default. The state of the control
is inherited on fork.
seccomp - Same as "prctl" above, but all seccomp threads
will disable SSB unless they explicitly opt out.
Not specifying this option is equivalent to Not specifying this option is equivalent to
spec_store_bypass_disable=auto. spec_store_bypass_disable=auto.
Default mitigations:
X86: If CONFIG_SECCOMP=y "seccomp", otherwise "prctl"
spia_io_base= [HW,MTD] spia_io_base= [HW,MTD]
spia_fio_base= spia_fio_base=
spia_pedr= spia_pedr=

View File

@ -233,6 +233,7 @@ enum ssb_mitigation {
SPEC_STORE_BYPASS_NONE, SPEC_STORE_BYPASS_NONE,
SPEC_STORE_BYPASS_DISABLE, SPEC_STORE_BYPASS_DISABLE,
SPEC_STORE_BYPASS_PRCTL, SPEC_STORE_BYPASS_PRCTL,
SPEC_STORE_BYPASS_SECCOMP,
}; };
extern char __indirect_thunk_start[]; extern char __indirect_thunk_start[];

View File

@ -416,22 +416,25 @@ enum ssb_mitigation_cmd {
SPEC_STORE_BYPASS_CMD_AUTO, SPEC_STORE_BYPASS_CMD_AUTO,
SPEC_STORE_BYPASS_CMD_ON, SPEC_STORE_BYPASS_CMD_ON,
SPEC_STORE_BYPASS_CMD_PRCTL, SPEC_STORE_BYPASS_CMD_PRCTL,
SPEC_STORE_BYPASS_CMD_SECCOMP,
}; };
static const char *ssb_strings[] = { static const char *ssb_strings[] = {
[SPEC_STORE_BYPASS_NONE] = "Vulnerable", [SPEC_STORE_BYPASS_NONE] = "Vulnerable",
[SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled", [SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled",
[SPEC_STORE_BYPASS_PRCTL] = "Mitigation: Speculative Store Bypass disabled via prctl" [SPEC_STORE_BYPASS_PRCTL] = "Mitigation: Speculative Store Bypass disabled via prctl",
[SPEC_STORE_BYPASS_SECCOMP] = "Mitigation: Speculative Store Bypass disabled via prctl and seccomp",
}; };
static const struct { static const struct {
const char *option; const char *option;
enum ssb_mitigation_cmd cmd; enum ssb_mitigation_cmd cmd;
} ssb_mitigation_options[] = { } ssb_mitigation_options[] = {
{ "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */ { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */
{ "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */ { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */
{ "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */ { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */
{ "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */ { "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */
{ "seccomp", SPEC_STORE_BYPASS_CMD_SECCOMP }, /* Disable Speculative Store Bypass via prctl and seccomp */
}; };
static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
@ -481,8 +484,15 @@ static enum ssb_mitigation_cmd __init __ssb_select_mitigation(void)
switch (cmd) { switch (cmd) {
case SPEC_STORE_BYPASS_CMD_AUTO: case SPEC_STORE_BYPASS_CMD_AUTO:
/* Choose prctl as the default mode */ case SPEC_STORE_BYPASS_CMD_SECCOMP:
mode = SPEC_STORE_BYPASS_PRCTL; /*
* Choose prctl+seccomp as the default mode if seccomp is
* enabled.
*/
if (IS_ENABLED(CONFIG_SECCOMP))
mode = SPEC_STORE_BYPASS_SECCOMP;
else
mode = SPEC_STORE_BYPASS_PRCTL;
break; break;
case SPEC_STORE_BYPASS_CMD_ON: case SPEC_STORE_BYPASS_CMD_ON:
mode = SPEC_STORE_BYPASS_DISABLE; mode = SPEC_STORE_BYPASS_DISABLE;
@ -530,12 +540,14 @@ static void ssb_select_mitigation()
} }
#undef pr_fmt #undef pr_fmt
#define pr_fmt(fmt) "Speculation prctl: " fmt
static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
{ {
bool update; bool update;
if (ssb_mode != SPEC_STORE_BYPASS_PRCTL) if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&
ssb_mode != SPEC_STORE_BYPASS_SECCOMP)
return -ENXIO; return -ENXIO;
switch (ctrl) { switch (ctrl) {
@ -583,7 +595,8 @@ int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
#ifdef CONFIG_SECCOMP #ifdef CONFIG_SECCOMP
void arch_seccomp_spec_mitigate(struct task_struct *task) void arch_seccomp_spec_mitigate(struct task_struct *task)
{ {
ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP)
ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE);
} }
#endif #endif
@ -592,6 +605,7 @@ static int ssb_prctl_get(struct task_struct *task)
switch (ssb_mode) { switch (ssb_mode) {
case SPEC_STORE_BYPASS_DISABLE: case SPEC_STORE_BYPASS_DISABLE:
return PR_SPEC_DISABLE; return PR_SPEC_DISABLE;
case SPEC_STORE_BYPASS_SECCOMP:
case SPEC_STORE_BYPASS_PRCTL: case SPEC_STORE_BYPASS_PRCTL:
if (task_spec_ssb_force_disable(task)) if (task_spec_ssb_force_disable(task))
return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;