Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'x86_bugs_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 mitigation updates from Borislav Petkov:

- Add VMSCAPE to the attack vector controls infrastructure

- A bunch of the usual cleanups and fixlets, some of them resulting
from fuzzing the different mitigation options

* tag 'x86_bugs_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/bugs: Report correct retbleed mitigation status
x86/bugs: Fix reporting of LFENCE retpoline
x86/bugs: Fix spectre_v2 forcing
x86/bugs: Remove uses of cpu_mitigations_off()
x86/bugs: Simplify SSB cmdline parsing
x86/bugs: Use early_param() for spectre_v2
x86/bugs: Use early_param() for spectre_v2_user
x86/bugs: Add attack vector controls for VMSCAPE
x86/its: Move ITS indirect branch thunks to .text..__x86.indirect_thunk

+220 -281
+1
Documentation/admin-guide/hw-vuln/attack_vector_controls.rst
··· 218 218 SSB X 219 219 TAA X X X X * (Note 2) 220 220 TSA X X X X 221 + VMSCAPE X 221 222 =============== ============== ============ ============= ============== ============ ======== 222 223 223 224 Notes:
+1
arch/x86/include/asm/nospec-branch.h
··· 514 514 /* The Speculative Store Bypass disable variants */ 515 515 enum ssb_mitigation { 516 516 SPEC_STORE_BYPASS_NONE, 517 + SPEC_STORE_BYPASS_AUTO, 517 518 SPEC_STORE_BYPASS_DISABLE, 518 519 SPEC_STORE_BYPASS_PRCTL, 519 520 SPEC_STORE_BYPASS_SECCOMP,
+178 -246
arch/x86/kernel/cpu/bugs.c
··· 434 434 case X86_BUG_SPEC_STORE_BYPASS: 435 435 return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER); 436 436 437 + case X86_BUG_VMSCAPE: 438 + return cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST); 439 + 437 440 default: 438 441 WARN(1, "Unknown bug %x\n", bug); 439 442 return false; ··· 687 684 688 685 static void __init mmio_select_mitigation(void) 689 686 { 690 - if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || 691 - cpu_mitigations_off()) { 687 + if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { 692 688 mmio_mitigation = MMIO_MITIGATION_OFF; 693 689 return; 694 690 } ··· 1462 1460 retbleed_mitigation = RETBLEED_MITIGATION_EIBRS; 1463 1461 break; 1464 1462 default: 1465 - if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF) 1463 + if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF) { 1466 1464 pr_err(RETBLEED_INTEL_MSG); 1465 + retbleed_mitigation = RETBLEED_MITIGATION_NONE; 1466 + } 1467 1467 } 1468 1468 } 1469 1469 ··· 1846 1842 SPECTRE_V2_CMD_IBRS, 1847 1843 }; 1848 1844 1849 - static enum spectre_v2_mitigation_cmd spectre_v2_cmd __ro_after_init = SPECTRE_V2_CMD_AUTO; 1845 + static enum spectre_v2_mitigation_cmd spectre_v2_cmd __ro_after_init = 1846 + IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? SPECTRE_V2_CMD_AUTO : SPECTRE_V2_CMD_NONE; 1850 1847 1851 - enum spectre_v2_user_cmd { 1848 + enum spectre_v2_user_mitigation_cmd { 1852 1849 SPECTRE_V2_USER_CMD_NONE, 1853 1850 SPECTRE_V2_USER_CMD_AUTO, 1854 1851 SPECTRE_V2_USER_CMD_FORCE, ··· 1859 1854 SPECTRE_V2_USER_CMD_SECCOMP_IBPB, 1860 1855 }; 1861 1856 1857 + static enum spectre_v2_user_mitigation_cmd spectre_v2_user_cmd __ro_after_init = 1858 + IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? SPECTRE_V2_USER_CMD_AUTO : SPECTRE_V2_USER_CMD_NONE; 1859 + 1862 1860 static const char * const spectre_v2_user_strings[] = { 1863 1861 [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", 1864 1862 [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", ··· 1870 1862 [SPECTRE_V2_USER_SECCOMP] = "User space: Mitigation: STIBP via seccomp and prctl", 1871 1863 }; 1872 1864 1873 - static const struct { 1874 - const char *option; 1875 - enum spectre_v2_user_cmd cmd; 1876 - bool secure; 1877 - } v2_user_options[] __initconst = { 1878 - { "auto", SPECTRE_V2_USER_CMD_AUTO, false }, 1879 - { "off", SPECTRE_V2_USER_CMD_NONE, false }, 1880 - { "on", SPECTRE_V2_USER_CMD_FORCE, true }, 1881 - { "prctl", SPECTRE_V2_USER_CMD_PRCTL, false }, 1882 - { "prctl,ibpb", SPECTRE_V2_USER_CMD_PRCTL_IBPB, false }, 1883 - { "seccomp", SPECTRE_V2_USER_CMD_SECCOMP, false }, 1884 - { "seccomp,ibpb", SPECTRE_V2_USER_CMD_SECCOMP_IBPB, false }, 1885 - }; 1886 - 1887 - static void __init spec_v2_user_print_cond(const char *reason, bool secure) 1865 + static int __init spectre_v2_user_parse_cmdline(char *str) 1888 1866 { 1889 - if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2) != secure) 1890 - pr_info("spectre_v2_user=%s forced on command line.\n", reason); 1867 + if (!str) 1868 + return -EINVAL; 1869 + 1870 + if (!strcmp(str, "auto")) 1871 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_AUTO; 1872 + else if (!strcmp(str, "off")) 1873 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_NONE; 1874 + else if (!strcmp(str, "on")) 1875 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_FORCE; 1876 + else if (!strcmp(str, "prctl")) 1877 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_PRCTL; 1878 + else if (!strcmp(str, "prctl,ibpb")) 1879 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_PRCTL_IBPB; 1880 + else if (!strcmp(str, "seccomp")) 1881 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_SECCOMP; 1882 + else if (!strcmp(str, "seccomp,ibpb")) 1883 + spectre_v2_user_cmd = SPECTRE_V2_USER_CMD_SECCOMP_IBPB; 1884 + else 1885 + pr_err("Ignoring unknown spectre_v2_user option (%s).", str); 1886 + 1887 + return 0; 1891 1888 } 1892 - 1893 - static enum spectre_v2_user_cmd __init spectre_v2_parse_user_cmdline(void) 1894 - { 1895 - char arg[20]; 1896 - int ret, i; 1897 - 1898 - if (!IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2)) 1899 - return SPECTRE_V2_USER_CMD_NONE; 1900 - 1901 - ret = cmdline_find_option(boot_command_line, "spectre_v2_user", 1902 - arg, sizeof(arg)); 1903 - if (ret < 0) 1904 - return SPECTRE_V2_USER_CMD_AUTO; 1905 - 1906 - for (i = 0; i < ARRAY_SIZE(v2_user_options); i++) { 1907 - if (match_option(arg, ret, v2_user_options[i].option)) { 1908 - spec_v2_user_print_cond(v2_user_options[i].option, 1909 - v2_user_options[i].secure); 1910 - return v2_user_options[i].cmd; 1911 - } 1912 - } 1913 - 1914 - pr_err("Unknown user space protection option (%s). Switching to default\n", arg); 1915 - return SPECTRE_V2_USER_CMD_AUTO; 1916 - } 1889 + early_param("spectre_v2_user", spectre_v2_user_parse_cmdline); 1917 1890 1918 1891 static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) 1919 1892 { ··· 1906 1917 if (!boot_cpu_has(X86_FEATURE_IBPB) && !boot_cpu_has(X86_FEATURE_STIBP)) 1907 1918 return; 1908 1919 1909 - switch (spectre_v2_parse_user_cmdline()) { 1920 + switch (spectre_v2_user_cmd) { 1910 1921 case SPECTRE_V2_USER_CMD_NONE: 1911 1922 return; 1912 1923 case SPECTRE_V2_USER_CMD_FORCE: ··· 2034 2045 static const char * const spectre_v2_strings[] = { 2035 2046 [SPECTRE_V2_NONE] = "Vulnerable", 2036 2047 [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", 2037 - [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE", 2048 + [SPECTRE_V2_LFENCE] = "Vulnerable: LFENCE", 2038 2049 [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced / Automatic IBRS", 2039 2050 [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced / Automatic IBRS + LFENCE", 2040 2051 [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced / Automatic IBRS + Retpolines", 2041 2052 [SPECTRE_V2_IBRS] = "Mitigation: IBRS", 2042 2053 }; 2043 2054 2044 - static const struct { 2045 - const char *option; 2046 - enum spectre_v2_mitigation_cmd cmd; 2047 - bool secure; 2048 - } mitigation_options[] __initconst = { 2049 - { "off", SPECTRE_V2_CMD_NONE, false }, 2050 - { "on", SPECTRE_V2_CMD_FORCE, true }, 2051 - { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, 2052 - { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, 2053 - { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, 2054 - { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, 2055 - { "eibrs", SPECTRE_V2_CMD_EIBRS, false }, 2056 - { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, 2057 - { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, 2058 - { "auto", SPECTRE_V2_CMD_AUTO, false }, 2059 - { "ibrs", SPECTRE_V2_CMD_IBRS, false }, 2060 - }; 2055 + static bool nospectre_v2 __ro_after_init; 2061 2056 2062 - static void __init spec_v2_print_cond(const char *reason, bool secure) 2057 + static int __init nospectre_v2_parse_cmdline(char *str) 2063 2058 { 2064 - if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2) != secure) 2065 - pr_info("%s selected on command line.\n", reason); 2059 + nospectre_v2 = true; 2060 + spectre_v2_cmd = SPECTRE_V2_CMD_NONE; 2061 + return 0; 2066 2062 } 2063 + early_param("nospectre_v2", nospectre_v2_parse_cmdline); 2067 2064 2068 - static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) 2065 + static int __init spectre_v2_parse_cmdline(char *str) 2069 2066 { 2070 - enum spectre_v2_mitigation_cmd cmd; 2071 - char arg[20]; 2072 - int ret, i; 2067 + if (!str) 2068 + return -EINVAL; 2073 2069 2074 - cmd = IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? SPECTRE_V2_CMD_AUTO : SPECTRE_V2_CMD_NONE; 2075 - if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) 2076 - return SPECTRE_V2_CMD_NONE; 2070 + if (nospectre_v2) 2071 + return 0; 2077 2072 2078 - ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); 2079 - if (ret < 0) 2080 - return cmd; 2081 - 2082 - for (i = 0; i < ARRAY_SIZE(mitigation_options); i++) { 2083 - if (!match_option(arg, ret, mitigation_options[i].option)) 2084 - continue; 2085 - cmd = mitigation_options[i].cmd; 2086 - break; 2073 + if (!strcmp(str, "off")) { 2074 + spectre_v2_cmd = SPECTRE_V2_CMD_NONE; 2075 + } else if (!strcmp(str, "on")) { 2076 + spectre_v2_cmd = SPECTRE_V2_CMD_FORCE; 2077 + setup_force_cpu_bug(X86_BUG_SPECTRE_V2); 2078 + setup_force_cpu_bug(X86_BUG_SPECTRE_V2_USER); 2079 + } else if (!strcmp(str, "retpoline")) { 2080 + spectre_v2_cmd = SPECTRE_V2_CMD_RETPOLINE; 2081 + } else if (!strcmp(str, "retpoline,amd") || 2082 + !strcmp(str, "retpoline,lfence")) { 2083 + spectre_v2_cmd = SPECTRE_V2_CMD_RETPOLINE_LFENCE; 2084 + } else if (!strcmp(str, "retpoline,generic")) { 2085 + spectre_v2_cmd = SPECTRE_V2_CMD_RETPOLINE_GENERIC; 2086 + } else if (!strcmp(str, "eibrs")) { 2087 + spectre_v2_cmd = SPECTRE_V2_CMD_EIBRS; 2088 + } else if (!strcmp(str, "eibrs,lfence")) { 2089 + spectre_v2_cmd = SPECTRE_V2_CMD_EIBRS_LFENCE; 2090 + } else if (!strcmp(str, "eibrs,retpoline")) { 2091 + spectre_v2_cmd = SPECTRE_V2_CMD_EIBRS_RETPOLINE; 2092 + } else if (!strcmp(str, "auto")) { 2093 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2094 + } else if (!strcmp(str, "ibrs")) { 2095 + spectre_v2_cmd = SPECTRE_V2_CMD_IBRS; 2096 + } else { 2097 + pr_err("Ignoring unknown spectre_v2 option (%s).", str); 2087 2098 } 2088 2099 2089 - if (i >= ARRAY_SIZE(mitigation_options)) { 2090 - pr_err("unknown option (%s). Switching to default mode\n", arg); 2091 - return cmd; 2092 - } 2093 - 2094 - if ((cmd == SPECTRE_V2_CMD_RETPOLINE || 2095 - cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || 2096 - cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || 2097 - cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || 2098 - cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && 2099 - !IS_ENABLED(CONFIG_MITIGATION_RETPOLINE)) { 2100 - pr_err("%s selected but not compiled in. Switching to AUTO select\n", 2101 - mitigation_options[i].option); 2102 - return SPECTRE_V2_CMD_AUTO; 2103 - } 2104 - 2105 - if ((cmd == SPECTRE_V2_CMD_EIBRS || 2106 - cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || 2107 - cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && 2108 - !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { 2109 - pr_err("%s selected but CPU doesn't have Enhanced or Automatic IBRS. Switching to AUTO select\n", 2110 - mitigation_options[i].option); 2111 - return SPECTRE_V2_CMD_AUTO; 2112 - } 2113 - 2114 - if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || 2115 - cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && 2116 - !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { 2117 - pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", 2118 - mitigation_options[i].option); 2119 - return SPECTRE_V2_CMD_AUTO; 2120 - } 2121 - 2122 - if (cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_MITIGATION_IBRS_ENTRY)) { 2123 - pr_err("%s selected but not compiled in. Switching to AUTO select\n", 2124 - mitigation_options[i].option); 2125 - return SPECTRE_V2_CMD_AUTO; 2126 - } 2127 - 2128 - if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { 2129 - pr_err("%s selected but not Intel CPU. Switching to AUTO select\n", 2130 - mitigation_options[i].option); 2131 - return SPECTRE_V2_CMD_AUTO; 2132 - } 2133 - 2134 - if (cmd == SPECTRE_V2_CMD_IBRS && !boot_cpu_has(X86_FEATURE_IBRS)) { 2135 - pr_err("%s selected but CPU doesn't have IBRS. Switching to AUTO select\n", 2136 - mitigation_options[i].option); 2137 - return SPECTRE_V2_CMD_AUTO; 2138 - } 2139 - 2140 - if (cmd == SPECTRE_V2_CMD_IBRS && cpu_feature_enabled(X86_FEATURE_XENPV)) { 2141 - pr_err("%s selected but running as XenPV guest. Switching to AUTO select\n", 2142 - mitigation_options[i].option); 2143 - return SPECTRE_V2_CMD_AUTO; 2144 - } 2145 - 2146 - spec_v2_print_cond(mitigation_options[i].option, 2147 - mitigation_options[i].secure); 2148 - return cmd; 2100 + return 0; 2149 2101 } 2102 + early_param("spectre_v2", spectre_v2_parse_cmdline); 2150 2103 2151 2104 static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void) 2152 2105 { ··· 2237 2306 { 2238 2307 if (spectre_v2_cmd == SPECTRE_V2_CMD_NONE) 2239 2308 bhi_mitigation = BHI_MITIGATION_OFF; 2240 - 2241 - if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2) && 2242 - spectre_v2_cmd == SPECTRE_V2_CMD_AUTO) 2243 - bhi_mitigation = BHI_MITIGATION_OFF; 2244 2309 } 2245 2310 2246 2311 static void __init bhi_apply_mitigation(void) ··· 2272 2345 2273 2346 static void __init spectre_v2_select_mitigation(void) 2274 2347 { 2275 - spectre_v2_cmd = spectre_v2_parse_cmdline(); 2348 + if ((spectre_v2_cmd == SPECTRE_V2_CMD_RETPOLINE || 2349 + spectre_v2_cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || 2350 + spectre_v2_cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || 2351 + spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || 2352 + spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && 2353 + !IS_ENABLED(CONFIG_MITIGATION_RETPOLINE)) { 2354 + pr_err("RETPOLINE selected but not compiled in. Switching to AUTO select\n"); 2355 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2356 + } 2276 2357 2277 - if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2) && 2278 - (spectre_v2_cmd == SPECTRE_V2_CMD_NONE || spectre_v2_cmd == SPECTRE_V2_CMD_AUTO)) 2358 + if ((spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS || 2359 + spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || 2360 + spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && 2361 + !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { 2362 + pr_err("EIBRS selected but CPU doesn't have Enhanced or Automatic IBRS. Switching to AUTO select\n"); 2363 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2364 + } 2365 + 2366 + if ((spectre_v2_cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || 2367 + spectre_v2_cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && 2368 + !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { 2369 + pr_err("LFENCE selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n"); 2370 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2371 + } 2372 + 2373 + if (spectre_v2_cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_MITIGATION_IBRS_ENTRY)) { 2374 + pr_err("IBRS selected but not compiled in. Switching to AUTO select\n"); 2375 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2376 + } 2377 + 2378 + if (spectre_v2_cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { 2379 + pr_err("IBRS selected but not Intel CPU. Switching to AUTO select\n"); 2380 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2381 + } 2382 + 2383 + if (spectre_v2_cmd == SPECTRE_V2_CMD_IBRS && !boot_cpu_has(X86_FEATURE_IBRS)) { 2384 + pr_err("IBRS selected but CPU doesn't have IBRS. Switching to AUTO select\n"); 2385 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2386 + } 2387 + 2388 + if (spectre_v2_cmd == SPECTRE_V2_CMD_IBRS && cpu_feature_enabled(X86_FEATURE_XENPV)) { 2389 + pr_err("IBRS selected but running as XenPV guest. Switching to AUTO select\n"); 2390 + spectre_v2_cmd = SPECTRE_V2_CMD_AUTO; 2391 + } 2392 + 2393 + if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) { 2394 + spectre_v2_cmd = SPECTRE_V2_CMD_NONE; 2279 2395 return; 2396 + } 2280 2397 2281 2398 switch (spectre_v2_cmd) { 2282 2399 case SPECTRE_V2_CMD_NONE: ··· 2526 2555 #undef pr_fmt 2527 2556 #define pr_fmt(fmt) "Speculative Store Bypass: " fmt 2528 2557 2529 - static enum ssb_mitigation ssb_mode __ro_after_init = SPEC_STORE_BYPASS_NONE; 2530 - 2531 - /* The kernel command line selection */ 2532 - enum ssb_mitigation_cmd { 2533 - SPEC_STORE_BYPASS_CMD_NONE, 2534 - SPEC_STORE_BYPASS_CMD_AUTO, 2535 - SPEC_STORE_BYPASS_CMD_ON, 2536 - SPEC_STORE_BYPASS_CMD_PRCTL, 2537 - SPEC_STORE_BYPASS_CMD_SECCOMP, 2538 - }; 2558 + static enum ssb_mitigation ssb_mode __ro_after_init = 2559 + IS_ENABLED(CONFIG_MITIGATION_SSB) ? SPEC_STORE_BYPASS_AUTO : SPEC_STORE_BYPASS_NONE; 2539 2560 2540 2561 static const char * const ssb_strings[] = { 2541 2562 [SPEC_STORE_BYPASS_NONE] = "Vulnerable", ··· 2536 2573 [SPEC_STORE_BYPASS_SECCOMP] = "Mitigation: Speculative Store Bypass disabled via prctl and seccomp", 2537 2574 }; 2538 2575 2539 - static const struct { 2540 - const char *option; 2541 - enum ssb_mitigation_cmd cmd; 2542 - } ssb_mitigation_options[] __initconst = { 2543 - { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */ 2544 - { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */ 2545 - { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */ 2546 - { "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */ 2547 - { "seccomp", SPEC_STORE_BYPASS_CMD_SECCOMP }, /* Disable Speculative Store Bypass via prctl and seccomp */ 2548 - }; 2576 + static bool nossb __ro_after_init; 2549 2577 2550 - static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) 2578 + static int __init nossb_parse_cmdline(char *str) 2551 2579 { 2552 - enum ssb_mitigation_cmd cmd; 2553 - char arg[20]; 2554 - int ret, i; 2555 - 2556 - cmd = IS_ENABLED(CONFIG_MITIGATION_SSB) ? 2557 - SPEC_STORE_BYPASS_CMD_AUTO : SPEC_STORE_BYPASS_CMD_NONE; 2558 - if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable") || 2559 - cpu_mitigations_off()) { 2560 - return SPEC_STORE_BYPASS_CMD_NONE; 2561 - } else { 2562 - ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", 2563 - arg, sizeof(arg)); 2564 - if (ret < 0) 2565 - return cmd; 2566 - 2567 - for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) { 2568 - if (!match_option(arg, ret, ssb_mitigation_options[i].option)) 2569 - continue; 2570 - 2571 - cmd = ssb_mitigation_options[i].cmd; 2572 - break; 2573 - } 2574 - 2575 - if (i >= ARRAY_SIZE(ssb_mitigation_options)) { 2576 - pr_err("unknown option (%s). Switching to default mode\n", arg); 2577 - return cmd; 2578 - } 2579 - } 2580 - 2581 - return cmd; 2580 + nossb = true; 2581 + ssb_mode = SPEC_STORE_BYPASS_NONE; 2582 + return 0; 2582 2583 } 2584 + early_param("nospec_store_bypass_disable", nossb_parse_cmdline); 2585 + 2586 + static int __init ssb_parse_cmdline(char *str) 2587 + { 2588 + if (!str) 2589 + return -EINVAL; 2590 + 2591 + if (nossb) 2592 + return 0; 2593 + 2594 + if (!strcmp(str, "auto")) 2595 + ssb_mode = SPEC_STORE_BYPASS_AUTO; 2596 + else if (!strcmp(str, "on")) 2597 + ssb_mode = SPEC_STORE_BYPASS_DISABLE; 2598 + else if (!strcmp(str, "off")) 2599 + ssb_mode = SPEC_STORE_BYPASS_NONE; 2600 + else if (!strcmp(str, "prctl")) 2601 + ssb_mode = SPEC_STORE_BYPASS_PRCTL; 2602 + else if (!strcmp(str, "seccomp")) 2603 + ssb_mode = IS_ENABLED(CONFIG_SECCOMP) ? 2604 + SPEC_STORE_BYPASS_SECCOMP : SPEC_STORE_BYPASS_PRCTL; 2605 + else 2606 + pr_err("Ignoring unknown spec_store_bypass_disable option (%s).\n", 2607 + str); 2608 + 2609 + return 0; 2610 + } 2611 + early_param("spec_store_bypass_disable", ssb_parse_cmdline); 2583 2612 2584 2613 static void __init ssb_select_mitigation(void) 2585 2614 { 2586 - enum ssb_mitigation_cmd cmd; 2587 - 2588 - if (!boot_cpu_has(X86_FEATURE_SSBD)) 2589 - goto out; 2590 - 2591 - cmd = ssb_parse_cmdline(); 2592 - if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS) && 2593 - (cmd == SPEC_STORE_BYPASS_CMD_NONE || 2594 - cmd == SPEC_STORE_BYPASS_CMD_AUTO)) 2615 + if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) { 2616 + ssb_mode = SPEC_STORE_BYPASS_NONE; 2595 2617 return; 2618 + } 2596 2619 2597 - switch (cmd) { 2598 - case SPEC_STORE_BYPASS_CMD_SECCOMP: 2599 - /* 2600 - * Choose prctl+seccomp as the default mode if seccomp is 2601 - * enabled. 2602 - */ 2603 - if (IS_ENABLED(CONFIG_SECCOMP)) 2604 - ssb_mode = SPEC_STORE_BYPASS_SECCOMP; 2605 - else 2606 - ssb_mode = SPEC_STORE_BYPASS_PRCTL; 2607 - break; 2608 - case SPEC_STORE_BYPASS_CMD_ON: 2609 - ssb_mode = SPEC_STORE_BYPASS_DISABLE; 2610 - break; 2611 - case SPEC_STORE_BYPASS_CMD_AUTO: 2620 + if (ssb_mode == SPEC_STORE_BYPASS_AUTO) { 2612 2621 if (should_mitigate_vuln(X86_BUG_SPEC_STORE_BYPASS)) 2613 2622 ssb_mode = SPEC_STORE_BYPASS_PRCTL; 2614 2623 else 2615 2624 ssb_mode = SPEC_STORE_BYPASS_NONE; 2616 - break; 2617 - case SPEC_STORE_BYPASS_CMD_PRCTL: 2618 - ssb_mode = SPEC_STORE_BYPASS_PRCTL; 2619 - break; 2620 - case SPEC_STORE_BYPASS_CMD_NONE: 2621 - break; 2622 2625 } 2623 2626 2624 - out: 2625 - if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) 2626 - pr_info("%s\n", ssb_strings[ssb_mode]); 2627 + if (!boot_cpu_has(X86_FEATURE_SSBD)) 2628 + ssb_mode = SPEC_STORE_BYPASS_NONE; 2629 + 2630 + pr_info("%s\n", ssb_strings[ssb_mode]); 2627 2631 } 2628 2632 2629 2633 static void __init ssb_apply_mitigation(void) ··· 2806 2876 return PR_SPEC_DISABLE; 2807 2877 case SPEC_STORE_BYPASS_SECCOMP: 2808 2878 case SPEC_STORE_BYPASS_PRCTL: 2879 + case SPEC_STORE_BYPASS_AUTO: 2809 2880 if (task_spec_ssb_force_disable(task)) 2810 2881 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; 2811 2882 if (task_spec_ssb_noexec(task)) ··· 3126 3195 3127 3196 static void __init srso_update_mitigation(void) 3128 3197 { 3198 + if (!boot_cpu_has_bug(X86_BUG_SRSO)) 3199 + return; 3200 + 3129 3201 /* If retbleed is using IBPB, that works for SRSO as well */ 3130 3202 if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB && 3131 3203 boot_cpu_has(X86_FEATURE_IBPB_BRTYPE)) 3132 3204 srso_mitigation = SRSO_MITIGATION_IBPB; 3133 3205 3134 - if (boot_cpu_has_bug(X86_BUG_SRSO) && 3135 - !cpu_mitigations_off()) 3136 - pr_info("%s\n", srso_strings[srso_mitigation]); 3206 + pr_info("%s\n", srso_strings[srso_mitigation]); 3137 3207 } 3138 3208 3139 3209 static void __init srso_apply_mitigation(void) ··· 3236 3304 3237 3305 static void __init vmscape_select_mitigation(void) 3238 3306 { 3239 - if (cpu_mitigations_off() || 3240 - !boot_cpu_has_bug(X86_BUG_VMSCAPE) || 3307 + if (!boot_cpu_has_bug(X86_BUG_VMSCAPE) || 3241 3308 !boot_cpu_has(X86_FEATURE_IBPB)) { 3242 3309 vmscape_mitigation = VMSCAPE_MITIGATION_NONE; 3243 3310 return; 3244 3311 } 3245 3312 3246 - if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO) 3247 - vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER; 3313 + if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO) { 3314 + if (should_mitigate_vuln(X86_BUG_VMSCAPE)) 3315 + vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER; 3316 + else 3317 + vmscape_mitigation = VMSCAPE_MITIGATION_NONE; 3318 + } 3248 3319 } 3249 3320 3250 3321 static void __init vmscape_update_mitigation(void) ··· 3561 3626 3562 3627 static ssize_t spectre_v2_show_state(char *buf) 3563 3628 { 3564 - if (spectre_v2_enabled == SPECTRE_V2_LFENCE) 3565 - return sysfs_emit(buf, "Vulnerable: LFENCE\n"); 3566 - 3567 3629 if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) 3568 3630 return sysfs_emit(buf, "Vulnerable: eIBRS with unprivileged eBPF\n"); 3569 3631
+40 -35
arch/x86/lib/retpoline.S
··· 15 15 16 16 .section .text..__x86.indirect_thunk 17 17 18 - 19 18 .macro POLINE reg 20 19 ANNOTATE_INTRA_FUNCTION_CALL 21 20 call .Ldo_rop_\@ ··· 72 73 #undef GEN 73 74 74 75 #ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING 76 + 75 77 .macro CALL_THUNK reg 76 78 .align RETPOLINE_THUNK_SIZE 77 79 ··· 126 126 #define GEN(reg) __EXPORT_THUNK(__x86_indirect_jump_thunk_ ## reg) 127 127 #include <asm/GEN-for-each-reg.h> 128 128 #undef GEN 129 - #endif 129 + 130 + #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ 131 + 132 + #ifdef CONFIG_MITIGATION_ITS 133 + 134 + .macro ITS_THUNK reg 135 + 136 + /* 137 + * If CFI paranoid is used then the ITS thunk starts with opcodes (0xea; jne 1b) 138 + * that complete the fineibt_paranoid caller sequence. 139 + */ 140 + 1: .byte 0xea 141 + SYM_INNER_LABEL(__x86_indirect_paranoid_thunk_\reg, SYM_L_GLOBAL) 142 + UNWIND_HINT_UNDEFINED 143 + ANNOTATE_NOENDBR 144 + jne 1b 145 + SYM_INNER_LABEL(__x86_indirect_its_thunk_\reg, SYM_L_GLOBAL) 146 + UNWIND_HINT_UNDEFINED 147 + ANNOTATE_NOENDBR 148 + ANNOTATE_RETPOLINE_SAFE 149 + jmp *%\reg 150 + int3 151 + .align 32, 0xcc /* fill to the end of the line */ 152 + .skip 32 - (__x86_indirect_its_thunk_\reg - 1b), 0xcc /* skip to the next upper half */ 153 + .endm 154 + 155 + /* ITS mitigation requires thunks be aligned to upper half of cacheline */ 156 + .align 64, 0xcc 157 + .skip 29, 0xcc 158 + 159 + #define GEN(reg) ITS_THUNK reg 160 + #include <asm/GEN-for-each-reg.h> 161 + #undef GEN 162 + 163 + .align 64, 0xcc 164 + SYM_FUNC_ALIAS(__x86_indirect_its_thunk_array, __x86_indirect_its_thunk_rax) 165 + SYM_CODE_END(__x86_indirect_its_thunk_array) 166 + 167 + #endif /* CONFIG_MITIGATION_ITS */ 130 168 131 169 #ifdef CONFIG_MITIGATION_RETHUNK 132 170 ··· 407 369 #endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */ 408 370 409 371 #ifdef CONFIG_MITIGATION_ITS 410 - 411 - .macro ITS_THUNK reg 412 - 413 - /* 414 - * If CFI paranoid is used then the ITS thunk starts with opcodes (0xea; jne 1b) 415 - * that complete the fineibt_paranoid caller sequence. 416 - */ 417 - 1: .byte 0xea 418 - SYM_INNER_LABEL(__x86_indirect_paranoid_thunk_\reg, SYM_L_GLOBAL) 419 - UNWIND_HINT_UNDEFINED 420 - ANNOTATE_NOENDBR 421 - jne 1b 422 - SYM_INNER_LABEL(__x86_indirect_its_thunk_\reg, SYM_L_GLOBAL) 423 - UNWIND_HINT_UNDEFINED 424 - ANNOTATE_NOENDBR 425 - ANNOTATE_RETPOLINE_SAFE 426 - jmp *%\reg 427 - int3 428 - .align 32, 0xcc /* fill to the end of the line */ 429 - .skip 32 - (__x86_indirect_its_thunk_\reg - 1b), 0xcc /* skip to the next upper half */ 430 - .endm 431 - 432 - /* ITS mitigation requires thunks be aligned to upper half of cacheline */ 433 - .align 64, 0xcc 434 - .skip 29, 0xcc 435 - 436 - #define GEN(reg) ITS_THUNK reg 437 - #include <asm/GEN-for-each-reg.h> 438 - #undef GEN 439 - 440 - .align 64, 0xcc 441 - SYM_FUNC_ALIAS(__x86_indirect_its_thunk_array, __x86_indirect_its_thunk_rax) 442 - SYM_CODE_END(__x86_indirect_its_thunk_array) 443 372 444 373 .align 64, 0xcc 445 374 .skip 32, 0xcc