From: Greg Kroah-Hartman Date: Tue, 8 Mar 2022 18:53:00 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.9.306~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cebdc3a4c12df84c9443542c1ff82cde68330016;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: cpu-smt-create-and-export-cpu_smt_possible.patch documentation-hw-vuln-update-spectre-doc.patch x86-bugs-unconditionally-allow-spectre_v2-retpoline-amd.patch x86-speculation-add-eibrs-retpoline-options.patch x86-speculation-include-unprivileged-ebpf-status-in-spectre-v2-mitigation-reporting.patch x86-speculation-merge-one-test-in-spectre_v2_user_select_mitigation.patch x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch x86-speculation-use-generic-retpoline-by-default-on-amd.patch x86-speculation-warn-about-eibrs-lfence-unprivileged-ebpf-smt.patch x86-speculation-warn-about-spectre-v2-lfence-mitigation.patch --- diff --git a/queue-4.9/cpu-smt-create-and-export-cpu_smt_possible.patch b/queue-4.9/cpu-smt-create-and-export-cpu_smt_possible.patch new file mode 100644 index 00000000000..31237d7af78 --- /dev/null +++ b/queue-4.9/cpu-smt-create-and-export-cpu_smt_possible.patch @@ -0,0 +1,68 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Vitaly Kuznetsov +Date: Mon, 16 Sep 2019 18:22:56 +0200 +Subject: cpu/SMT: create and export cpu_smt_possible() + +From: Vitaly Kuznetsov + +commit e1572f1d08be57a5412a464cff0712a23cd0b73e upstream. + +KVM needs to know if SMT is theoretically possible, this means it is +supported and not forcefully disabled ('nosmt=force'). Create and +export cpu_smt_possible() answering this question. + +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +[fllinden@amazon.com: backported to 4.9 (minor contextual conflict)] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/cpu.h | 2 ++ + kernel/cpu.c | 11 +++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -276,6 +276,7 @@ extern enum cpuhp_smt_control cpu_smt_co + extern void cpu_smt_disable(bool force); + extern void cpu_smt_check_topology_early(void); + extern void cpu_smt_check_topology(void); ++extern bool cpu_smt_possible(void); + extern int cpuhp_smt_enable(void); + extern int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval); + #else +@@ -283,6 +284,7 @@ extern int cpuhp_smt_disable(enum cpuhp_ + static inline void cpu_smt_disable(bool force) { } + static inline void cpu_smt_check_topology_early(void) { } + static inline void cpu_smt_check_topology(void) { } ++static inline bool cpu_smt_possible(void) { return false; } + static inline int cpuhp_smt_enable(void) { return 0; } + static inline int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval) { return 0; } + #endif +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -371,8 +371,7 @@ static bool cpu_smt_available __read_mos + + void __init cpu_smt_disable(bool force) + { +- if (cpu_smt_control == CPU_SMT_FORCE_DISABLED || +- cpu_smt_control == CPU_SMT_NOT_SUPPORTED) ++ if (!cpu_smt_possible()) + return; + + if (force) { +@@ -439,6 +438,14 @@ static inline bool cpu_smt_allowed(unsig + */ + return !per_cpu(cpuhp_state, cpu).booted_once; + } ++ ++/* Returns true if SMT is not supported of forcefully (irreversibly) disabled */ ++bool cpu_smt_possible(void) ++{ ++ return cpu_smt_control != CPU_SMT_FORCE_DISABLED && ++ cpu_smt_control != CPU_SMT_NOT_SUPPORTED; ++} ++EXPORT_SYMBOL_GPL(cpu_smt_possible); + #else + static inline bool cpu_smt_allowed(unsigned int cpu) { return true; } + #endif diff --git a/queue-4.9/documentation-hw-vuln-update-spectre-doc.patch b/queue-4.9/documentation-hw-vuln-update-spectre-doc.patch new file mode 100644 index 00000000000..8962c99e418 --- /dev/null +++ b/queue-4.9/documentation-hw-vuln-update-spectre-doc.patch @@ -0,0 +1,40 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Peter Zijlstra +Date: Wed, 16 Feb 2022 20:57:02 +0100 +Subject: Documentation/hw-vuln: Update spectre doc + +From: Peter Zijlstra + +commit 5ad3eb1132453b9795ce5fd4572b1c18b292cca9 upstream. + +Update the doc with the new fun. + + [ bp: Massage commit message. ] + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov +Reviewed-by: Thomas Gleixner +[fllinden@amazon.com: backported, no spectrev2-specific doc in 4.9] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/kernel-parameters.txt | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -4174,8 +4174,12 @@ bytes respectively. Such letter suffixes + Specific mitigations can also be selected manually: + + retpoline - replace indirect branches +- retpoline,generic - google's original retpoline +- retpoline,amd - AMD-specific minimal thunk ++ retpoline,generic - Retpolines ++ retpoline,lfence - LFENCE; indirect branch ++ retpoline,amd - alias for retpoline,lfence ++ eibrs - enhanced IBRS ++ eibrs,retpoline - enhanced IBRS + Retpolines ++ eibrs,lfence - enhanced IBRS + LFENCE + + Not specifying this option is equivalent to + spectre_v2=auto. diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..42faf3fc11b --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,10 @@ +cpu-smt-create-and-export-cpu_smt_possible.patch +x86-speculation-merge-one-test-in-spectre_v2_user_select_mitigation.patch +x86-bugs-unconditionally-allow-spectre_v2-retpoline-amd.patch +x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch +x86-speculation-add-eibrs-retpoline-options.patch +documentation-hw-vuln-update-spectre-doc.patch +x86-speculation-include-unprivileged-ebpf-status-in-spectre-v2-mitigation-reporting.patch +x86-speculation-use-generic-retpoline-by-default-on-amd.patch +x86-speculation-warn-about-spectre-v2-lfence-mitigation.patch +x86-speculation-warn-about-eibrs-lfence-unprivileged-ebpf-smt.patch diff --git a/queue-4.9/x86-bugs-unconditionally-allow-spectre_v2-retpoline-amd.patch b/queue-4.9/x86-bugs-unconditionally-allow-spectre_v2-retpoline-amd.patch new file mode 100644 index 00000000000..765c3199575 --- /dev/null +++ b/queue-4.9/x86-bugs-unconditionally-allow-spectre_v2-retpoline-amd.patch @@ -0,0 +1,39 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Peter Zijlstra +Date: Tue, 26 Oct 2021 14:01:46 +0200 +Subject: x86,bugs: Unconditionally allow spectre_v2=retpoline,amd + +From: Peter Zijlstra + +commit f8a66d608a3e471e1202778c2a36cbdc96bae73b upstream. + +Currently Linux prevents usage of retpoline,amd on !AMD hardware, this +is unfriendly and gets in the way of testing. Remove this restriction. + +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Borislav Petkov +Acked-by: Josh Poimboeuf +Tested-by: Alexei Starovoitov +Link: https://lore.kernel.org/r/20211026120310.487348118@infradead.org +[fllinden@amazon.com: backported to 4.9 (no Hygon in 4.9)] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -845,12 +845,6 @@ static enum spectre_v2_mitigation_cmd __ + return SPECTRE_V2_CMD_AUTO; + } + +- if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD && +- boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { +- pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); +- return SPECTRE_V2_CMD_AUTO; +- } +- + spec_v2_print_cond(mitigation_options[i].option, + mitigation_options[i].secure); + return cmd; diff --git a/queue-4.9/x86-speculation-add-eibrs-retpoline-options.patch b/queue-4.9/x86-speculation-add-eibrs-retpoline-options.patch new file mode 100644 index 00000000000..f8c29ff1c55 --- /dev/null +++ b/queue-4.9/x86-speculation-add-eibrs-retpoline-options.patch @@ -0,0 +1,320 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Peter Zijlstra +Date: Wed, 16 Feb 2022 20:57:01 +0100 +Subject: x86/speculation: Add eIBRS + Retpoline options + +From: Peter Zijlstra + +commit 1e19da8522c81bf46b335f84137165741e0d82b7 upstream. + +Thanks to the chaps at VUsec it is now clear that eIBRS is not +sufficient, therefore allow enabling of retpolines along with eIBRS. + +Add spectre_v2=eibrs, spectre_v2=eibrs,lfence and +spectre_v2=eibrs,retpoline options to explicitly pick your preferred +means of mitigation. + +Since there's new mitigations there's also user visible changes in +/sys/devices/system/cpu/vulnerabilities/spectre_v2 to reflect these +new mitigations. + + [ bp: Massage commit message, trim error messages, + do more precise eIBRS mode checking. ] + +Co-developed-by: Josh Poimboeuf +Signed-off-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov +Reviewed-by: Patrick Colp +Reviewed-by: Thomas Gleixner +[ fllinden@amazon.com: 4.9 backport: remove explicit 'minimal' + retpoline modes, print " (minimal)" after any of the retpoline + variants instead, to keep things manageable] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/nospec-branch.h | 6 - + arch/x86/kernel/cpu/bugs.c | 157 +++++++++++++++++++++++++---------- + 2 files changed, 117 insertions(+), 46 deletions(-) + +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -212,11 +212,11 @@ + /* The Spectre V2 mitigation variants */ + enum spectre_v2_mitigation { + SPECTRE_V2_NONE, +- SPECTRE_V2_RETPOLINE_MINIMAL, +- SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE, + SPECTRE_V2_RETPOLINE, + SPECTRE_V2_LFENCE, +- SPECTRE_V2_IBRS_ENHANCED, ++ SPECTRE_V2_EIBRS, ++ SPECTRE_V2_EIBRS_RETPOLINE, ++ SPECTRE_V2_EIBRS_LFENCE, + }; + + /* The indirect branch speculation control variants */ +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -621,6 +621,9 @@ enum spectre_v2_mitigation_cmd { + SPECTRE_V2_CMD_RETPOLINE, + SPECTRE_V2_CMD_RETPOLINE_GENERIC, + SPECTRE_V2_CMD_RETPOLINE_LFENCE, ++ SPECTRE_V2_CMD_EIBRS, ++ SPECTRE_V2_CMD_EIBRS_RETPOLINE, ++ SPECTRE_V2_CMD_EIBRS_LFENCE, + }; + + enum spectre_v2_user_cmd { +@@ -693,6 +696,13 @@ spectre_v2_parse_user_cmdline(enum spect + return SPECTRE_V2_USER_CMD_AUTO; + } + ++static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) ++{ ++ return (mode == SPECTRE_V2_EIBRS || ++ mode == SPECTRE_V2_EIBRS_RETPOLINE || ++ mode == SPECTRE_V2_EIBRS_LFENCE); ++} ++ + static void __init + spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) + { +@@ -760,7 +770,7 @@ spectre_v2_user_select_mitigation(enum s + */ + if (!boot_cpu_has(X86_FEATURE_STIBP) || + !smt_possible || +- spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) ++ spectre_v2_in_eibrs_mode(spectre_v2_enabled)) + return; + + /* +@@ -780,11 +790,11 @@ set_mode: + + static const char * const spectre_v2_strings[] = { + [SPECTRE_V2_NONE] = "Vulnerable", +- [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal Retpolines", +- [SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE] = "Vulnerable: Minimal LFENCE", + [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", +- [SPECTRE_V2_RETPOLINE_LFENCE] = "Mitigation: LFENCE", +- [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS", ++ [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE", ++ [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced IBRS", ++ [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced IBRS + LFENCE", ++ [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced IBRS + Retpolines", + }; + + static const struct { +@@ -798,6 +808,9 @@ static const struct { + { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, + { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, + { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, ++ { "eibrs", SPECTRE_V2_CMD_EIBRS, false }, ++ { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, ++ { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, + { "auto", SPECTRE_V2_CMD_AUTO, false }, + }; + +@@ -812,6 +825,21 @@ static inline bool retp_compiler(void) + return __is_defined(RETPOLINE); + } + ++static const char *spectre_v2_retp(enum spectre_v2_mitigation mode) ++{ ++ switch (mode) { ++ case SPECTRE_V2_RETPOLINE: ++ case SPECTRE_V2_LFENCE: ++ case SPECTRE_V2_EIBRS_LFENCE: ++ case SPECTRE_V2_EIBRS_RETPOLINE: ++ if (!retp_compiler()) ++ return " (minimal)"; ++ /* fallthrough */ ++ default: ++ return ""; ++ } ++} ++ + static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) + { + enum spectre_v2_mitigation_cmd cmd = SPECTRE_V2_CMD_AUTO; +@@ -840,15 +868,29 @@ static enum spectre_v2_mitigation_cmd __ + + if ((cmd == SPECTRE_V2_CMD_RETPOLINE || + cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || +- cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && ++ cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && + !IS_ENABLED(CONFIG_RETPOLINE)) { +- pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); ++ pr_err("%s selected but not compiled in. Switching to AUTO select\n", ++ mitigation_options[i].option); ++ return SPECTRE_V2_CMD_AUTO; ++ } ++ ++ if ((cmd == SPECTRE_V2_CMD_EIBRS || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && ++ !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { ++ pr_err("%s selected but CPU doesn't have eIBRS. Switching to AUTO select\n", ++ mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + +- if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE) && ++ if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || ++ cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && + !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { +- pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", mitigation_options[i].option); ++ pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", ++ mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + +@@ -857,6 +899,24 @@ static enum spectre_v2_mitigation_cmd __ + return cmd; + } + ++static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void) ++{ ++ if (!IS_ENABLED(CONFIG_RETPOLINE)) { ++ pr_err("Kernel not compiled with retpoline; no mitigation available!"); ++ return SPECTRE_V2_NONE; ++ } ++ ++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { ++ if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { ++ pr_err("LFENCE not serializing, switching to generic retpoline\n"); ++ return SPECTRE_V2_RETPOLINE; ++ } ++ return SPECTRE_V2_LFENCE; ++ } ++ ++ return SPECTRE_V2_RETPOLINE; ++} ++ + static void __init spectre_v2_select_mitigation(void) + { + enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); +@@ -877,52 +937,62 @@ static void __init spectre_v2_select_mit + case SPECTRE_V2_CMD_FORCE: + case SPECTRE_V2_CMD_AUTO: + if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { +- mode = SPECTRE_V2_IBRS_ENHANCED; +- /* Force it so VMEXIT will restore correctly */ +- x86_spec_ctrl_base |= SPEC_CTRL_IBRS; +- wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); +- goto specv2_set_mode; ++ mode = SPECTRE_V2_EIBRS; ++ break; + } +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_auto; ++ ++ mode = spectre_v2_select_retpoline(); + break; ++ + case SPECTRE_V2_CMD_RETPOLINE_LFENCE: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_lfence; ++ mode = SPECTRE_V2_LFENCE; + break; ++ + case SPECTRE_V2_CMD_RETPOLINE_GENERIC: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_generic; ++ mode = SPECTRE_V2_RETPOLINE; + break; ++ + case SPECTRE_V2_CMD_RETPOLINE: +- if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_auto; ++ mode = spectre_v2_select_retpoline(); ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS: ++ mode = SPECTRE_V2_EIBRS; ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS_LFENCE: ++ mode = SPECTRE_V2_EIBRS_LFENCE; ++ break; ++ ++ case SPECTRE_V2_CMD_EIBRS_RETPOLINE: ++ mode = SPECTRE_V2_EIBRS_RETPOLINE; + break; + } +- pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); +- return; + +-retpoline_auto: +- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- retpoline_lfence: +- if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { +- pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); +- goto retpoline_generic; +- } +- mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_LFENCE : +- SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE; ++ if (spectre_v2_in_eibrs_mode(mode)) { ++ /* Force it so VMEXIT will restore correctly */ ++ x86_spec_ctrl_base |= SPEC_CTRL_IBRS; ++ wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); ++ } ++ ++ switch (mode) { ++ case SPECTRE_V2_NONE: ++ case SPECTRE_V2_EIBRS: ++ break; ++ ++ case SPECTRE_V2_LFENCE: ++ case SPECTRE_V2_EIBRS_LFENCE: + setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); ++ /* fallthrough */ ++ ++ case SPECTRE_V2_RETPOLINE: ++ case SPECTRE_V2_EIBRS_RETPOLINE: + setup_force_cpu_cap(X86_FEATURE_RETPOLINE); +- } else { +- retpoline_generic: +- mode = retp_compiler() ? SPECTRE_V2_RETPOLINE : +- SPECTRE_V2_RETPOLINE_MINIMAL; +- setup_force_cpu_cap(X86_FEATURE_RETPOLINE); ++ break; + } + +-specv2_set_mode: + spectre_v2_enabled = mode; +- pr_info("%s\n", spectre_v2_strings[mode]); ++ pr_info("%s%s\n", spectre_v2_strings[mode], spectre_v2_retp(mode)); + + /* + * If spectre v2 protection has been enabled, unconditionally fill +@@ -946,7 +1016,7 @@ specv2_set_mode: + * the CPU supports Enhanced IBRS, kernel might un-intentionally not + * enable IBRS around firmware calls. + */ +- if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) { ++ if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_eibrs_mode(mode)) { + setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); + pr_info("Enabling Restricted Speculation for firmware calls\n"); + } +@@ -1606,7 +1676,7 @@ static ssize_t tsx_async_abort_show_stat + + static char *stibp_state(void) + { +- if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) ++ if (spectre_v2_in_eibrs_mode(spectre_v2_enabled)) + return ""; + + switch (spectre_v2_user_stibp) { +@@ -1658,7 +1728,8 @@ static ssize_t cpu_show_common(struct de + return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); + + case X86_BUG_SPECTRE_V2: +- return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], ++ return sprintf(buf, "%s%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], ++ spectre_v2_retp(spectre_v2_enabled), + ibpb_state(), + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", + stibp_state(), diff --git a/queue-4.9/x86-speculation-include-unprivileged-ebpf-status-in-spectre-v2-mitigation-reporting.patch b/queue-4.9/x86-speculation-include-unprivileged-ebpf-status-in-spectre-v2-mitigation-reporting.patch new file mode 100644 index 00000000000..732d2729102 --- /dev/null +++ b/queue-4.9/x86-speculation-include-unprivileged-ebpf-status-in-spectre-v2-mitigation-reporting.patch @@ -0,0 +1,153 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Josh Poimboeuf +Date: Fri, 18 Feb 2022 11:49:08 -0800 +Subject: x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting + +From: Josh Poimboeuf + +commit 44a3918c8245ab10c6c9719dd12e7a8d291980d8 upstream. + +With unprivileged eBPF enabled, eIBRS (without retpoline) is vulnerable +to Spectre v2 BHB-based attacks. + +When both are enabled, print a warning message and report it in the +'spectre_v2' sysfs vulnerabilities file. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Borislav Petkov +Reviewed-by: Thomas Gleixner +[fllinden@amazon.com: backported to 4.9] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 37 ++++++++++++++++++++++++++++++------- + include/linux/bpf.h | 12 ++++++++++++ + kernel/sysctl.c | 8 ++++++++ + 3 files changed, 50 insertions(+), 7 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "cpu.h" + +@@ -606,6 +607,16 @@ static inline const char *spectre_v2_mod + static inline const char *spectre_v2_module_string(void) { return ""; } + #endif + ++#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" ++ ++#ifdef CONFIG_BPF_SYSCALL ++void unpriv_ebpf_notify(int new_state) ++{ ++ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state) ++ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); ++} ++#endif ++ + static inline bool match_option(const char *arg, int arglen, const char *opt) + { + int len = strlen(opt); +@@ -969,6 +980,9 @@ static void __init spectre_v2_select_mit + break; + } + ++ if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) ++ pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); ++ + if (spectre_v2_in_eibrs_mode(mode)) { + /* Force it so VMEXIT will restore correctly */ + x86_spec_ctrl_base |= SPEC_CTRL_IBRS; +@@ -1706,6 +1720,21 @@ static char *ibpb_state(void) + return ""; + } + ++static ssize_t spectre_v2_show_state(char *buf) ++{ ++ if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) ++ return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); ++ ++ return sprintf(buf, "%s%s%s%s%s%s%s\n", ++ spectre_v2_strings[spectre_v2_enabled], ++ spectre_v2_retp(spectre_v2_enabled), ++ ibpb_state(), ++ boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", ++ stibp_state(), ++ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", ++ spectre_v2_module_string()); ++} ++ + static ssize_t srbds_show_state(char *buf) + { + return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]); +@@ -1728,13 +1757,7 @@ static ssize_t cpu_show_common(struct de + return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); + + case X86_BUG_SPECTRE_V2: +- return sprintf(buf, "%s%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], +- spectre_v2_retp(spectre_v2_enabled), +- ibpb_state(), +- boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", +- stibp_state(), +- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", +- spectre_v2_module_string()); ++ return spectre_v2_show_state(buf); + + case X86_BUG_SPEC_STORE_BYPASS: + return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); +--- a/include/linux/bpf.h ++++ b/include/linux/bpf.h +@@ -295,6 +295,12 @@ static inline void bpf_long_memcpy(void + + /* verify correctness of eBPF program */ + int bpf_check(struct bpf_prog **fp, union bpf_attr *attr); ++ ++static inline bool unprivileged_ebpf_enabled(void) ++{ ++ return !sysctl_unprivileged_bpf_disabled; ++} ++ + #else + static inline void bpf_register_prog_type(struct bpf_prog_type_list *tl) + { +@@ -322,6 +328,12 @@ static inline struct bpf_prog *bpf_prog_ + { + return ERR_PTR(-EOPNOTSUPP); + } ++ ++static inline bool unprivileged_ebpf_enabled(void) ++{ ++ return false; ++} ++ + #endif /* CONFIG_BPF_SYSCALL */ + + /* verifier prototypes for helper functions called from eBPF programs */ +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -222,6 +222,11 @@ static int sysrq_sysctl_handler(struct c + #endif + + #ifdef CONFIG_BPF_SYSCALL ++ ++void __weak unpriv_ebpf_notify(int new_state) ++{ ++} ++ + static int bpf_unpriv_handler(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { +@@ -239,6 +244,9 @@ static int bpf_unpriv_handler(struct ctl + return -EPERM; + *(int *)table->data = unpriv_enable; + } ++ ++ unpriv_ebpf_notify(unpriv_enable); ++ + return ret; + } + #endif diff --git a/queue-4.9/x86-speculation-merge-one-test-in-spectre_v2_user_select_mitigation.patch b/queue-4.9/x86-speculation-merge-one-test-in-spectre_v2_user_select_mitigation.patch new file mode 100644 index 00000000000..34584f93854 --- /dev/null +++ b/queue-4.9/x86-speculation-merge-one-test-in-spectre_v2_user_select_mitigation.patch @@ -0,0 +1,63 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Borislav Petkov +Date: Mon, 15 Jun 2020 08:51:25 +0200 +Subject: x86/speculation: Merge one test in spectre_v2_user_select_mitigation() + +From: Borislav Petkov + +commit a5ce9f2bb665d1d2b31f139a02dbaa2dfbb62fa6 upstream. + +Merge the test whether the CPU supports STIBP into the test which +determines whether STIBP is required. Thus try to simplify what is +already an insane logic. + +Remove a superfluous newline in a comment, while at it. + +Signed-off-by: Borislav Petkov +Cc: Anthony Steinhauser +Link: https://lkml.kernel.org/r/20200615065806.GB14668@zn.tnic +[fllinden@amazon.com: fixed contextual conflict (comment) for 4.9] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -755,10 +755,12 @@ spectre_v2_user_select_mitigation(enum s + } + + /* +- * If enhanced IBRS is enabled or SMT impossible, STIBP is not ++ * If no STIBP, enhanced IBRS is enabled or SMT impossible, STIBP is not + * required. + */ +- if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) ++ if (!boot_cpu_has(X86_FEATURE_STIBP) || ++ !smt_possible || ++ spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) + return; + + /* +@@ -770,12 +772,6 @@ spectre_v2_user_select_mitigation(enum s + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + +- /* +- * If STIBP is not available, clear the STIBP mode. +- */ +- if (!boot_cpu_has(X86_FEATURE_STIBP)) +- mode = SPECTRE_V2_USER_NONE; +- + spectre_v2_user_stibp = mode; + + set_mode: +@@ -1263,7 +1259,6 @@ static int ib_prctl_set(struct task_stru + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) + return 0; +- + /* + * With strict mode for both IBPB and STIBP, the instruction + * code paths avoid checking this task flag and instead, diff --git a/queue-4.9/x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch b/queue-4.9/x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch new file mode 100644 index 00000000000..bcf481ea978 --- /dev/null +++ b/queue-4.9/x86-speculation-rename-retpoline_amd-to-retpoline_lfence.patch @@ -0,0 +1,184 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: "Peter Zijlstra (Intel)" +Date: Wed, 16 Feb 2022 20:57:00 +0100 +Subject: x86/speculation: Rename RETPOLINE_AMD to RETPOLINE_LFENCE + +From: "Peter Zijlstra (Intel)" + +commit d45476d9832409371537013ebdd8dc1a7781f97a upstream. + +The RETPOLINE_AMD name is unfortunate since it isn't necessarily +AMD only, in fact Hygon also uses it. Furthermore it will likely be +sufficient for some Intel processors. Therefore rename the thing to +RETPOLINE_LFENCE to better describe what it is. + +Add the spectre_v2=retpoline,lfence option as an alias to +spectre_v2=retpoline,amd to preserve existing setups. However, the output +of /sys/devices/system/cpu/vulnerabilities/spectre_v2 will be changed. + + [ bp: Fix typos, massage. ] + +Co-developed-by: Josh Poimboeuf +Signed-off-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Borislav Petkov +Reviewed-by: Thomas Gleixner +[fllinden@amazon.com: backported to 4.9 - conflicts with minimal +retpoline modes] +Signed-off-by: Frank van der Linden +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/cpufeatures.h | 2 - + arch/x86/include/asm/nospec-branch.h | 10 ++++---- + arch/x86/kernel/cpu/bugs.c | 35 ++++++++++++++++++------------- + tools/arch/x86/include/asm/cpufeatures.h | 2 - + 4 files changed, 28 insertions(+), 21 deletions(-) + +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -195,7 +195,7 @@ + #define X86_FEATURE_FENCE_SWAPGS_USER ( 7*32+10) /* "" LFENCE in user entry SWAPGS path */ + #define X86_FEATURE_FENCE_SWAPGS_KERNEL ( 7*32+11) /* "" LFENCE in kernel entry SWAPGS path */ + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +-#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ ++#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCE for Spectre variant 2 */ + + #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ + #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -119,7 +119,7 @@ + ANNOTATE_NOSPEC_ALTERNATIVE + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg), \ + __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ +- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD ++ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_LFENCE + #else + jmp *\reg + #endif +@@ -130,7 +130,7 @@ + ANNOTATE_NOSPEC_ALTERNATIVE + ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg), \ + __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ +- __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD ++ __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_LFENCE + #else + call *\reg + #endif +@@ -213,9 +213,9 @@ + enum spectre_v2_mitigation { + SPECTRE_V2_NONE, + SPECTRE_V2_RETPOLINE_MINIMAL, +- SPECTRE_V2_RETPOLINE_MINIMAL_AMD, +- SPECTRE_V2_RETPOLINE_GENERIC, +- SPECTRE_V2_RETPOLINE_AMD, ++ SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE, ++ SPECTRE_V2_RETPOLINE, ++ SPECTRE_V2_LFENCE, + SPECTRE_V2_IBRS_ENHANCED, + }; + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -620,7 +620,7 @@ enum spectre_v2_mitigation_cmd { + SPECTRE_V2_CMD_FORCE, + SPECTRE_V2_CMD_RETPOLINE, + SPECTRE_V2_CMD_RETPOLINE_GENERIC, +- SPECTRE_V2_CMD_RETPOLINE_AMD, ++ SPECTRE_V2_CMD_RETPOLINE_LFENCE, + }; + + enum spectre_v2_user_cmd { +@@ -780,10 +780,10 @@ set_mode: + + static const char * const spectre_v2_strings[] = { + [SPECTRE_V2_NONE] = "Vulnerable", +- [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline", +- [SPECTRE_V2_RETPOLINE_MINIMAL_AMD] = "Vulnerable: Minimal AMD ASM retpoline", +- [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline", +- [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline", ++ [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal Retpolines", ++ [SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE] = "Vulnerable: Minimal LFENCE", ++ [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", ++ [SPECTRE_V2_RETPOLINE_LFENCE] = "Mitigation: LFENCE", + [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS", + }; + +@@ -795,7 +795,8 @@ static const struct { + { "off", SPECTRE_V2_CMD_NONE, false }, + { "on", SPECTRE_V2_CMD_FORCE, true }, + { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, +- { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false }, ++ { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, ++ { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, + { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, + { "auto", SPECTRE_V2_CMD_AUTO, false }, + }; +@@ -838,13 +839,19 @@ static enum spectre_v2_mitigation_cmd __ + } + + if ((cmd == SPECTRE_V2_CMD_RETPOLINE || +- cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || ++ cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || + cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && + !IS_ENABLED(CONFIG_RETPOLINE)) { + pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + ++ if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE) && ++ !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { ++ pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", mitigation_options[i].option); ++ return SPECTRE_V2_CMD_AUTO; ++ } ++ + spec_v2_print_cond(mitigation_options[i].option, + mitigation_options[i].secure); + return cmd; +@@ -879,9 +886,9 @@ static void __init spectre_v2_select_mit + if (IS_ENABLED(CONFIG_RETPOLINE)) + goto retpoline_auto; + break; +- case SPECTRE_V2_CMD_RETPOLINE_AMD: ++ case SPECTRE_V2_CMD_RETPOLINE_LFENCE: + if (IS_ENABLED(CONFIG_RETPOLINE)) +- goto retpoline_amd; ++ goto retpoline_lfence; + break; + case SPECTRE_V2_CMD_RETPOLINE_GENERIC: + if (IS_ENABLED(CONFIG_RETPOLINE)) +@@ -897,18 +904,18 @@ static void __init spectre_v2_select_mit + + retpoline_auto: + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- retpoline_amd: ++ retpoline_lfence: + if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { + pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); + goto retpoline_generic; + } +- mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD : +- SPECTRE_V2_RETPOLINE_MINIMAL_AMD; +- setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); ++ mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_LFENCE : ++ SPECTRE_V2_RETPOLINE_MINIMAL_LFENCE; ++ setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); + setup_force_cpu_cap(X86_FEATURE_RETPOLINE); + } else { + retpoline_generic: +- mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_GENERIC : ++ mode = retp_compiler() ? SPECTRE_V2_RETPOLINE : + SPECTRE_V2_RETPOLINE_MINIMAL; + setup_force_cpu_cap(X86_FEATURE_RETPOLINE); + } +--- a/tools/arch/x86/include/asm/cpufeatures.h ++++ b/tools/arch/x86/include/asm/cpufeatures.h +@@ -194,7 +194,7 @@ + #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ + + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +-#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ ++#define X86_FEATURE_RETPOLINE_LFENCE ( 7*32+13) /* "" Use LFENCEs for Spectre variant 2 */ + + #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ + #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ diff --git a/queue-4.9/x86-speculation-use-generic-retpoline-by-default-on-amd.patch b/queue-4.9/x86-speculation-use-generic-retpoline-by-default-on-amd.patch new file mode 100644 index 00000000000..b2d1a23e659 --- /dev/null +++ b/queue-4.9/x86-speculation-use-generic-retpoline-by-default-on-amd.patch @@ -0,0 +1,41 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Kim Phillips +Date: Mon, 28 Feb 2022 11:23:15 -0600 +Subject: x86/speculation: Use generic retpoline by default on AMD + +From: Kim Phillips + +commit 244d00b5dd4755f8df892c86cab35fb2cfd4f14b upstream. + +AMD retpoline may be susceptible to speculation. The speculation +execution window for an incorrect indirect branch prediction using +LFENCE/JMP sequence may potentially be large enough to allow +exploitation using Spectre V2. + +By default, don't use retpoline,lfence on AMD. Instead, use the +generic retpoline. + +Signed-off-by: Kim Phillips +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -917,14 +917,6 @@ static enum spectre_v2_mitigation __init + return SPECTRE_V2_NONE; + } + +- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { +- pr_err("LFENCE not serializing, switching to generic retpoline\n"); +- return SPECTRE_V2_RETPOLINE; +- } +- return SPECTRE_V2_LFENCE; +- } +- + return SPECTRE_V2_RETPOLINE; + } + diff --git a/queue-4.9/x86-speculation-warn-about-eibrs-lfence-unprivileged-ebpf-smt.patch b/queue-4.9/x86-speculation-warn-about-eibrs-lfence-unprivileged-ebpf-smt.patch new file mode 100644 index 00000000000..f84b7aaa34b --- /dev/null +++ b/queue-4.9/x86-speculation-warn-about-eibrs-lfence-unprivileged-ebpf-smt.patch @@ -0,0 +1,93 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Josh Poimboeuf +Date: Fri, 25 Feb 2022 14:32:28 -0800 +Subject: x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT + +From: Josh Poimboeuf + +commit 0de05d056afdb00eca8c7bbb0c79a3438daf700c upstream. + +The commit + + 44a3918c8245 ("x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting") + +added a warning for the "eIBRS + unprivileged eBPF" combination, which +has been shown to be vulnerable against Spectre v2 BHB-based attacks. + +However, there's no warning about the "eIBRS + LFENCE retpoline + +unprivileged eBPF" combo. The LFENCE adds more protection by shortening +the speculation window after a mispredicted branch. That makes an attack +significantly more difficult, even with unprivileged eBPF. So at least +for now the logic doesn't warn about that combination. + +But if you then add SMT into the mix, the SMT attack angle weakens the +effectiveness of the LFENCE considerably. + +So extend the "eIBRS + unprivileged eBPF" warning to also include the +"eIBRS + LFENCE + unprivileged eBPF + SMT" case. + + [ bp: Massage commit message. ] + +Suggested-by: Alyssa Milburn +Signed-off-by: Josh Poimboeuf +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -609,12 +609,27 @@ static inline const char *spectre_v2_mod + + #define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n" + #define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" ++#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n" + + #ifdef CONFIG_BPF_SYSCALL + void unpriv_ebpf_notify(int new_state) + { +- if (spectre_v2_enabled == SPECTRE_V2_EIBRS && !new_state) ++ if (new_state) ++ return; ++ ++ /* Unprivileged eBPF is enabled */ ++ ++ switch (spectre_v2_enabled) { ++ case SPECTRE_V2_EIBRS: + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); ++ break; ++ case SPECTRE_V2_EIBRS_LFENCE: ++ if (sched_smt_active()) ++ pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); ++ break; ++ default: ++ break; ++ } + } + #endif + +@@ -1094,6 +1109,10 @@ void arch_smt_update(void) + { + mutex_lock(&spec_ctrl_mutex); + ++ if (sched_smt_active() && unprivileged_ebpf_enabled() && ++ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) ++ pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); ++ + switch (spectre_v2_user_stibp) { + case SPECTRE_V2_USER_NONE: + break; +@@ -1720,7 +1739,11 @@ static ssize_t spectre_v2_show_state(cha + return sprintf(buf, "Vulnerable: LFENCE\n"); + + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) +- return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); ++ return sprintf(buf, "Vulnerable: eIBRS with unprivileged eBPF\n"); ++ ++ if (sched_smt_active() && unprivileged_ebpf_enabled() && ++ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) ++ return sprintf(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); + + return sprintf(buf, "%s%s%s%s%s%s%s\n", + spectre_v2_strings[spectre_v2_enabled], diff --git a/queue-4.9/x86-speculation-warn-about-spectre-v2-lfence-mitigation.patch b/queue-4.9/x86-speculation-warn-about-spectre-v2-lfence-mitigation.patch new file mode 100644 index 00000000000..989f018dd39 --- /dev/null +++ b/queue-4.9/x86-speculation-warn-about-spectre-v2-lfence-mitigation.patch @@ -0,0 +1,62 @@ +From foo@baz Tue Mar 8 07:51:35 PM CET 2022 +From: Josh Poimboeuf +Date: Fri, 25 Feb 2022 14:31:49 -0800 +Subject: x86/speculation: Warn about Spectre v2 LFENCE mitigation + +From: Josh Poimboeuf + +commit eafd987d4a82c7bb5aa12f0e3b4f8f3dea93e678 upstream. + +With: + + f8a66d608a3e ("x86,bugs: Unconditionally allow spectre_v2=retpoline,amd") + +it became possible to enable the LFENCE "retpoline" on Intel. However, +Intel doesn't recommend it, as it has some weaknesses compared to +retpoline. + +Now AMD doesn't recommend it either. + +It can still be left available as a cmdline option. It's faster than +retpoline but is weaker in certain scenarios -- particularly SMT, but +even non-SMT may be vulnerable in some cases. + +So just unconditionally warn if the user requests it on the cmdline. + + [ bp: Massage commit message. ] + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Borislav Petkov +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/bugs.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -607,6 +607,7 @@ static inline const char *spectre_v2_mod + static inline const char *spectre_v2_module_string(void) { return ""; } + #endif + ++#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n" + #define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" + + #ifdef CONFIG_BPF_SYSCALL +@@ -948,6 +949,7 @@ static void __init spectre_v2_select_mit + break; + + case SPECTRE_V2_CMD_RETPOLINE_LFENCE: ++ pr_err(SPECTRE_V2_LFENCE_MSG); + mode = SPECTRE_V2_LFENCE; + break; + +@@ -1714,6 +1716,9 @@ static char *ibpb_state(void) + + static ssize_t spectre_v2_show_state(char *buf) + { ++ if (spectre_v2_enabled == SPECTRE_V2_LFENCE) ++ return sprintf(buf, "Vulnerable: LFENCE\n"); ++ + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) + return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); +