x86/speculation: Make "seccomp" the default mode for Speculative Store Bypass
commit f21b53b20c
upstream
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
61dfdc12ff
Коммит
0f18f44ce0
|
@ -3954,19 +3954,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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче