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:
parent
8bf37d8c06
commit
f21b53b20c
@ -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=
|
||||||
|
@ -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[];
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user