From: Konrad Rzeszutek Wilk Date: Thu, 1 Feb 2018 17:25:54 +0000 (-0500) Subject: x86/spectre_v2: Don't allow {ibrs,ipbp,lfence}_enabled to be toggled if retpoline X-Git-Tag: v4.1.12-124.31.3~1164 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a152f9821dc56887544d287649c1d727e56567d7;p=users%2Fjedix%2Flinux-maple.git x86/spectre_v2: Don't allow {ibrs,ipbp,lfence}_enabled to be toggled if retpoline is enabled. And also refresh the spectre_v2_enabled mode depending on whether the sysfs knobs are turned on/off. Preserve the ability to tweak IBPB if retpoline is enabled. Orabug: 27477743 CVE: CVE-2017-5715 Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: Darren Kenny Reviewed-by: Pavel Tatashin --- diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 540dd04d58f8..1d70864c19b0 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -982,5 +982,6 @@ void df_debug(struct pt_regs *regs, long error_code); void disable_retpoline(void); bool retpoline_enabled(void); +int refresh_set_spectre_v2_enabled(void); #endif /* _ASM_X86_PROCESSOR_H */ diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c index dc062b3e5597..a363f9cab12d 100644 --- a/arch/x86/kernel/cpu/bugs_64.c +++ b/arch/x86/kernel/cpu/bugs_64.c @@ -134,6 +134,27 @@ bool retpoline_enabled(void) return false; } +int refresh_set_spectre_v2_enabled(void) +{ + if (retpoline_enabled()) + return false; + + if (check_ibrs_inuse()) + spectre_v2_enabled = SPECTRE_V2_IBRS; + else { + /* + * If that didn't work (say no microcode or noibrs), we end up using + * lfence on system calls/exceptions/parameters. + */ + if (lfence_inuse) + spectre_v2_enabled = SPECTRE_V2_IBRS_LFENCE; + else + spectre_v2_enabled = SPECTRE_V2_NONE; + } + + return true; +} + static void __init spec2_print_if_insecure(const char *reason) { if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) @@ -377,9 +398,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev, if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) return sprintf(buf, "Not affected\n"); - return sprintf(buf, "%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], - ibrs_inuse ? "" /* As spectre_v2_strings has it. */ : - lfence_inuse ? " lfence " : "", + return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled], ibpb_inuse ? ", IBPB" : ""); } #endif diff --git a/arch/x86/kernel/cpu/spec_ctrl.c b/arch/x86/kernel/cpu/spec_ctrl.c index 9450e116bf59..93aa00cede93 100644 --- a/arch/x86/kernel/cpu/spec_ctrl.c +++ b/arch/x86/kernel/cpu/spec_ctrl.c @@ -56,6 +56,11 @@ static ssize_t ibrs_enabled_write(struct file *file, if (!ibrs_supported) return -ENODEV; + if (retpoline_enabled()) { + pr_warn("retpoline is enabled. Ignoring request to change ibrs state.\n"); + return -EINVAL; + } + len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; @@ -80,6 +85,7 @@ static ssize_t ibrs_enabled_write(struct file *file, } else { clear_ibrs_disabled(); } + refresh_set_spectre_v2_enabled(); mutex_unlock(&spec_ctrl_mutex); return count; @@ -130,6 +136,8 @@ static ssize_t ibpb_enabled_write(struct file *file, else clear_ibpb_disabled(); + refresh_set_spectre_v2_enabled(); + mutex_unlock(&spec_ctrl_mutex); return count; } @@ -160,8 +168,9 @@ static ssize_t lfence_enabled_write(struct file *file, unsigned int enable; /* You have to disable IBRS first. */ - if (ibrs_inuse) { - pr_warn("IBRS is enabled. Ignoring request to change lfence_enabled state."); + if (ibrs_inuse || retpoline_enabled()) { + pr_warn("%s is enabled. Ignoring request to change lfence_enabled state.\n", + ibrs_inuse ? "IBRS" : "retpoline"); return -EINVAL; } @@ -184,6 +193,8 @@ static ssize_t lfence_enabled_write(struct file *file, else clear_lfence_disabled(); + refresh_set_spectre_v2_enabled(); + mutex_unlock(&spec_ctrl_mutex); return count; }