mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-04-05 16:23:19 +02:00
enh: add known fixed ucode versions for CVE-2023-23583 (Reptar) and CVE-2024-45332 (BPI)
This commit is contained in:
@@ -123,10 +123,12 @@ It must always be okay to run this script in a production environment.
|
||||
|
||||
Never look at the kernel version string to determine whether it supports a mitigation. This would defeat the script's purpose: it must detect mitigations in unknown, vendor-patched, or backported kernels. Similarly, do not blindly trust what `sysfs` reports when it is possible to verify directly.
|
||||
|
||||
### 3. Never hardcode microcode versions
|
||||
### 3. Never hardcode microcode versions (with one exception)
|
||||
|
||||
Never look at the microcode version to determine whether it has the proper mitigation mechanisms. Instead, probe for the mechanisms themselves (CPUID bits, MSR values), as the kernel would.
|
||||
|
||||
**Exception**: When a vulnerability is fixed purely by a microcode update and the fix exposes **no** detectable CPUID bit, MSR bit, or ARCH\_CAP flag, then we must hardcode the known-fixing microcode versions for each affected CPU stepping. In this case, build a `<vuln>_ucode_list` table of `FF-MM-SS/platformid_mask,fixed_ucode_version` tuples (sourced from the Intel affected processor list and the Intel-Linux-Processor-Microcode-Data-Files release notes), match against `cpu_cpuid` + `cpu_platformid` in `is_cpu_affected()`, and store the required version in a `g_<vuln>_fixed_ucode_version` global. The CVE check then compares `cpu_ucode` against this threshold. Because Intel never lists EOL CPUs, the microcode list may be incomplete: keep a model blacklist as a fallback so that affected CPUs without a known fix are still flagged as affected (the CVE check should handle the empty `g_<vuln>_fixed_ucode_version` case by reporting VULN with "no microcode update available"). See Reptar (`g_reptar_fixed_ucode_version`) and BPI (`g_bpi_fixed_ucode_version`) for reference implementations.
|
||||
|
||||
### 4. Assume affected unless proven otherwise (whitelist approach)
|
||||
|
||||
When a CPU is not explicitly known to be unaffected by a vulnerability, assume that it is affected. This conservative default has been the right call since the early Spectre/Meltdown days and remains sound.
|
||||
@@ -705,7 +707,7 @@ CVEs that need VMM context should call `check_has_vmm` early in their `_linux()`
|
||||
|
||||
### Key Rules to Remember
|
||||
|
||||
- **Never hardcode kernel or microcode versions** - detect capabilities directly (design principles 2 and 3).
|
||||
- **Never hardcode kernel or microcode versions** - detect capabilities directly (design principles 2 and 3). Exception: when a microcode fix has no detectable indicator, hardcode fixing versions per CPU (see principle 3).
|
||||
- **Assume affected by default** - only mark a CPU as unaffected when there is positive evidence (design principle 4).
|
||||
- **Always handle both live and offline modes** - use `$opt_live` to branch, and print `N/A "not testable in offline mode"` for runtime-only checks when offline.
|
||||
- **Use `explain()`** when reporting VULN to give actionable remediation advice (see "Cross-Cutting Features" above).
|
||||
|
||||
@@ -42,7 +42,7 @@ _is_cpu_affected_cached() {
|
||||
# Args: $1=cve_id (one of the $g_supported_cve_list items)
|
||||
# Returns: 0 if affected, 1 if not affected
|
||||
is_cpu_affected() {
|
||||
local result cpuid_hex reptar_ucode_list tuple fixed_ucode_ver affected_fmspi affected_fms ucode_platformid_mask affected_cpuid i cpupart cpuarch
|
||||
local result cpuid_hex reptar_ucode_list bpi_ucode_list tuple fixed_ucode_ver affected_fmspi affected_fms ucode_platformid_mask affected_cpuid i cpupart cpuarch
|
||||
|
||||
# if CPU is Intel and is in our dump of the Intel official affected CPUs page, use it:
|
||||
if is_intel; then
|
||||
@@ -296,16 +296,17 @@ is_cpu_affected() {
|
||||
# as the mitigation is only ucode-based and there's no flag exposed by the kernel or by an updated ucode.
|
||||
# we have to hardcode the truthtable of affected CPUs vs updated ucodes...
|
||||
# https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/redundant-prefix-issue.html
|
||||
# list taken from:
|
||||
# list initially taken from:
|
||||
# https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/commit/ece0d294a29a1375397941a4e6f2f7217910bc89#diff-e6fad0f2abbac6c9603b2e8f88fe1d151a83de708aeca1c1d93d881c958ecba4R26
|
||||
# both pages have a lot of inconsistencies, I've tried to fix the errors the best I could, the logic being: if it's not in the
|
||||
# blog page, then the microcode update in the commit is not related to reptar, if microcode versions differ, then the one in github is correct,
|
||||
# if a stepping exists in the blog page but not in the commit, then the blog page is right
|
||||
# updated 2026-04 with Intel affected processor list + releasenote.md:
|
||||
# added 06-9a-04/40 (AZB), 06-bd-01/80 (Lunar Lake, post-dates Reptar: first ucode already includes fix)
|
||||
g_reptar_fixed_ucode_version=''
|
||||
reptar_ucode_list='
|
||||
06-97-02/07,00000032
|
||||
06-97-05/07,00000032
|
||||
06-9a-03/80,00000430
|
||||
06-9a-04/80,00000430
|
||||
06-9a-04/40,00000005
|
||||
06-6c-01/10,01000268
|
||||
06-6a-06/87,0d0003b9
|
||||
06-7e-05/80,000000c2
|
||||
@@ -326,6 +327,7 @@ is_cpu_affected() {
|
||||
06-8d-01/c2,0000004e
|
||||
06-8d-00/c2,0000004e
|
||||
06-8c-02/c2,00000034
|
||||
06-bd-01/80,0000011f
|
||||
'
|
||||
for tuple in $reptar_ucode_list; do
|
||||
fixed_ucode_ver=$((0x$(echo "$tuple" | cut -d, -f2)))
|
||||
@@ -339,12 +341,35 @@ is_cpu_affected() {
|
||||
0x"$(echo "$affected_fms" | cut -d- -f3)"
|
||||
)
|
||||
if [ "$cpu_cpuid" = "$affected_cpuid" ] && [ $((cpu_platformid & ucode_platformid_mask)) -gt 0 ]; then
|
||||
# this is not perfect as Intel never tells about their EOL CPUs, so more CPUs might be affected but there's no way to tell
|
||||
_set_vuln reptar
|
||||
g_reptar_fixed_ucode_version=$fixed_ucode_ver
|
||||
break
|
||||
fi
|
||||
done
|
||||
# if we didn't match the ucode list above, also check the model blacklist:
|
||||
# Intel never tells about their EOL CPUs, so more CPUs might be affected
|
||||
# than the ones that received a microcode update (e.g. steppings with
|
||||
# different platform IDs that were dropped before the Reptar fix).
|
||||
if [ -z "$g_reptar_fixed_ucode_version" ] && [ "$cpu_family" = 6 ]; then
|
||||
set -u
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_ALDERLAKE" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ALDERLAKE_L" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ICELAKE_X" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ICELAKE_D" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ICELAKE_L" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ROCKETLAKE" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_TIGERLAKE_L" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_TIGERLAKE" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_SAPPHIRERAPIDS_X" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_RAPTORLAKE" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_RAPTORLAKE_P" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_RAPTORLAKE_S" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_LUNARLAKE_M" ]; then
|
||||
pr_debug "is_cpu_affected: reptar: affected (model match, no known fixing ucode)"
|
||||
_set_vuln reptar
|
||||
fi
|
||||
set +u
|
||||
fi
|
||||
|
||||
# Retbleed (Intel, CVE-2022-29901): Skylake through Rocket Lake, or any CPU with RSBA
|
||||
# kernel cpu_vuln_blacklist for RETBLEED (6b80b59b3555, 6ad0ad2bf8a6, f54d45372c6a)
|
||||
@@ -416,12 +441,76 @@ is_cpu_affected() {
|
||||
fi
|
||||
|
||||
# BPI (Branch Privilege Injection, CVE-2024-45332)
|
||||
# microcode-only fix (intel-microcode 20250512+), no kernel X86_BUG flag
|
||||
# Intel affected processor list: Coffee Lake through Arrow Lake/Lunar Lake,
|
||||
# plus some server parts (Cooper Lake, Sapphire/Emerald Rapids, Grand Ridge)
|
||||
# immunity: no ARCH_CAP bits
|
||||
# vendor scope: Intel only (family 6)
|
||||
if [ "$cpu_family" = 6 ]; then
|
||||
# microcode-only fix, no kernel X86_BUG flag, no CPUID/MSR indicator for the fix.
|
||||
# We have to hardcode the truthtable of affected CPUs vs fixing ucodes,
|
||||
# same approach as Reptar (see above).
|
||||
# https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/advisory-guidance/indirect-branch-predictor-delayed-updates.html
|
||||
# list taken from Intel affected processor list + Intel-Linux-Processor-Microcode-Data-Files releasenote.md
|
||||
# format: FF-MM-SS/platformid_mask,fixed_ucode_version
|
||||
g_bpi_fixed_ucode_version=''
|
||||
bpi_ucode_list='
|
||||
06-9e-0d/22,00000104
|
||||
06-8e-0a/c0,000000f6
|
||||
06-8e-0b/d0,000000f6
|
||||
06-8e-0c/94,00000100
|
||||
06-a5-02/20,00000100
|
||||
06-a5-03/22,00000100
|
||||
06-a5-05/22,00000100
|
||||
06-a6-00/80,00000102
|
||||
06-a6-01/80,00000100
|
||||
06-a7-01/02,00000065
|
||||
06-7e-05/80,000000cc
|
||||
06-6a-06/87,0d000421
|
||||
06-6c-01/10,010002f1
|
||||
06-8c-01/80,000000be
|
||||
06-8c-02/c2,0000003e
|
||||
06-8d-01/c2,00000058
|
||||
06-97-02/07,0000003e
|
||||
06-97-05/07,0000003e
|
||||
06-9a-03/80,0000043b
|
||||
06-9a-04/80,0000043b
|
||||
06-9a-04/40,0000000c
|
||||
06-be-00/19,00000021
|
||||
06-b7-01/32,00000133
|
||||
06-ba-02/e0,00006134
|
||||
06-ba-03/e0,00006134
|
||||
06-bf-02/07,0000003e
|
||||
06-bf-05/07,0000003e
|
||||
06-aa-04/e6,00000028
|
||||
06-b5-00/80,0000000d
|
||||
06-c5-02/82,0000011b
|
||||
06-c6-02/82,0000011b
|
||||
06-bd-01/80,00000125
|
||||
06-55-0b/bf,07002b01
|
||||
06-8f-07/87,2b000661
|
||||
06-8f-08/87,2b000661
|
||||
06-8f-08/10,2c000421
|
||||
06-cf-02/87,210002d3
|
||||
06-7a-08/01,00000026
|
||||
'
|
||||
for tuple in $bpi_ucode_list; do
|
||||
fixed_ucode_ver=$((0x$(echo "$tuple" | cut -d, -f2)))
|
||||
affected_fmspi=$(echo "$tuple" | cut -d, -f1)
|
||||
affected_fms=$(echo "$affected_fmspi" | cut -d/ -f1)
|
||||
ucode_platformid_mask=0x$(echo "$affected_fmspi" | cut -d/ -f2)
|
||||
affected_cpuid=$(
|
||||
fms2cpuid \
|
||||
0x"$(echo "$affected_fms" | cut -d- -f1)" \
|
||||
0x"$(echo "$affected_fms" | cut -d- -f2)" \
|
||||
0x"$(echo "$affected_fms" | cut -d- -f3)"
|
||||
)
|
||||
if [ "$cpu_cpuid" = "$affected_cpuid" ] && [ $((cpu_platformid & ucode_platformid_mask)) -gt 0 ]; then
|
||||
_set_vuln bpi
|
||||
g_bpi_fixed_ucode_version=$fixed_ucode_ver
|
||||
break
|
||||
fi
|
||||
done
|
||||
# if we didn't match the ucode list above, also check the model blacklist:
|
||||
# Intel never tells about their EOL CPUs, so more CPUs might be affected
|
||||
# than the ones that received a microcode update. In that case, we flag
|
||||
# the CPU as affected but g_bpi_fixed_ucode_version stays empty (the CVE
|
||||
# check will handle this by reporting VULN with no known fix).
|
||||
if [ -z "$g_bpi_fixed_ucode_version" ] && [ "$cpu_family" = 6 ]; then
|
||||
set -u
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_KABYLAKE_L" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_KABYLAKE" ] ||
|
||||
@@ -449,7 +538,7 @@ is_cpu_affected() {
|
||||
[ "$cpu_model" = "$INTEL_FAM6_EMERALDRAPIDS_X" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_PLUS" ] ||
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_CRESTMONT" ]; then
|
||||
pr_debug "is_cpu_affected: bpi: affected"
|
||||
pr_debug "is_cpu_affected: bpi: affected (model match, no known fixing ucode)"
|
||||
_set_vuln bpi
|
||||
fi
|
||||
set +u
|
||||
|
||||
@@ -15,8 +15,13 @@ check_CVE_2023_23583_linux() {
|
||||
# there is no sysfs file for this vuln, and no kernel patch,
|
||||
# the mitigation is only ucode-based and there's no flag exposed,
|
||||
# so most of the work has already been done by is_cpu_affected()
|
||||
# shellcheck disable=SC2154
|
||||
if ! is_cpu_affected "$cve"; then
|
||||
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
||||
elif [ -z "$g_reptar_fixed_ucode_version" ]; then
|
||||
# CPU matched the model blacklist but has no known fixing microcode
|
||||
# (likely an EOL stepping that Intel won't release a fix for)
|
||||
pvulnstatus "$cve" VULN "your CPU is affected and no microcode update is available for your CPU stepping"
|
||||
else
|
||||
pr_info_nol "* Reptar is mitigated by microcode: "
|
||||
if [ "$cpu_ucode" -lt "$g_reptar_fixed_ucode_version" ]; then
|
||||
|
||||
@@ -13,21 +13,34 @@ check_CVE_2024_45332_linux() {
|
||||
msg=''
|
||||
|
||||
# There is no dedicated sysfs file for this vulnerability, and no kernel
|
||||
# mitigation code. The fix is purely a microcode update (intel-microcode
|
||||
# 20250512+) that corrects the asynchronous branch predictor update timing
|
||||
# so that eIBRS and IBPB work as originally intended. There is no new
|
||||
# CPUID bit, MSR bit, or ARCH_CAP flag to detect the fix. The only
|
||||
# reliable indicator is the microcode version, which we cannot check
|
||||
# without violating design principle 3 (never hardcode microcode versions).
|
||||
# mitigation code. The fix is purely a microcode update that corrects the
|
||||
# asynchronous branch predictor update timing so that eIBRS and IBPB work
|
||||
# as originally intended. There is no new CPUID bit, MSR bit, or ARCH_CAP
|
||||
# flag to detect the fix, so we hardcode known-fixing microcode versions
|
||||
# per CPU (see bpi_ucode_list in is_cpu_affected).
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
if ! is_cpu_affected "$cve"; then
|
||||
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
||||
else
|
||||
pvulnstatus "$cve" UNK "the microcode fix for this vulnerability cannot be detected (no CPUID/MSR indicator); ensure you have intel-microcode 20250512 or later installed"
|
||||
elif [ -z "$g_bpi_fixed_ucode_version" ]; then
|
||||
# CPU matched the model blacklist but has no known fixing microcode
|
||||
# (likely an EOL stepping that Intel won't release a fix for)
|
||||
pvulnstatus "$cve" VULN "your CPU is affected and no microcode update is available for your CPU stepping"
|
||||
explain "CVE-2024-45332 (Branch Privilege Injection) is a race condition in the branch predictor\n" \
|
||||
"that undermines eIBRS and IBPB protections. The fix is a microcode update only (intel-microcode\n" \
|
||||
"20250512+). No kernel changes are required. Verify your microcode version with: grep microcode\n" \
|
||||
"/proc/cpuinfo. Contact your OS vendor to ensure the latest Intel microcode package is installed."
|
||||
"that undermines eIBRS and IBPB protections. The fix is a microcode update, but no\n" \
|
||||
"update is available for your specific CPU stepping."
|
||||
else
|
||||
pr_info_nol "* BPI is mitigated by microcode: "
|
||||
if [ "$cpu_ucode" -lt "$g_bpi_fixed_ucode_version" ]; then
|
||||
pstatus yellow NO "You have ucode $(printf "0x%x" "$cpu_ucode") and version $(printf "0x%x" "$g_bpi_fixed_ucode_version") minimum is required"
|
||||
pvulnstatus "$cve" VULN "Your microcode is too old to mitigate the vulnerability"
|
||||
explain "CVE-2024-45332 (Branch Privilege Injection) is a race condition in the branch predictor\n" \
|
||||
"that undermines eIBRS and IBPB protections. The fix is a microcode update only.\n" \
|
||||
"No kernel changes are required."
|
||||
else
|
||||
pstatus green YES "You have ucode $(printf "0x%x" "$cpu_ucode") which is recent enough (>= $(printf "0x%x" "$g_bpi_fixed_ucode_version"))"
|
||||
pvulnstatus "$cve" OK "Your microcode mitigates the vulnerability"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user