|
@@ -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 */
|
|
|
|
- { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable 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 */
|
|
|
|
|
|
+ { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */
|
|
|
|
+ { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable 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 */
|
|
|
|
+ { "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 */
|
|
|
|
- mode = SPEC_STORE_BYPASS_PRCTL;
|
|
|
|
|
|
+ case SPEC_STORE_BYPASS_CMD_SECCOMP:
|
|
|
|
+ /*
|
|
|
|
+ * 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;
|