mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2024-10-31 18:58:03 +01:00
Added support for MDS related vulnerabilities (#282)
This commit is contained in:
parent
d547ce4ab4
commit
8e870db4f5
14
README.md
14
README.md
@ -1,7 +1,7 @@
|
||||
Spectre & Meltdown Checker
|
||||
==========================
|
||||
|
||||
A shell script to tell if your system is vulnerable against the several "speculative execution" CVEs that were made public in 2018.
|
||||
A shell script to tell if your system is vulnerable against the several "speculative execution" CVEs that were made public since 2018.
|
||||
- CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1'
|
||||
- CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2'
|
||||
- CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3'
|
||||
@ -10,6 +10,10 @@ A shell script to tell if your system is vulnerable against the several "specula
|
||||
- CVE-2018-3615 [L1 terminal fault] aka 'Foreshadow (SGX)'
|
||||
- CVE-2018-3620 [L1 terminal fault] aka 'Foreshadow-NG (OS)'
|
||||
- CVE-2018-3646 [L1 terminal fault] aka 'Foreshadow-NG (VMM)'
|
||||
- CVE-2018-12126 [MSBDS] Microarchitectural Store Buffer Data Sampling
|
||||
- CVE-2018-12130 [MFBDS] Microarchitectural Fill Buffer Data Sampling
|
||||
- CVE-2018-12127 [MLPDS] Microarchitectural Load Port Data Sampling
|
||||
- CVE-2019-11091 [MDSUM] Microarchitectural Data Sampling Uncacheable Memory
|
||||
|
||||
Supported operating systems:
|
||||
- Linux (all versions, flavors and distros)
|
||||
@ -129,6 +133,14 @@ docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/m
|
||||
updated kernel (with L1d flush)
|
||||
- Performance impact of the mitigation: low to significant
|
||||
|
||||
**CVE-2018-12126** [MSBDS] Microarchitectural Store Buffer Data Sampling
|
||||
**CVE-2018-12130** [MFBDS] Microarchitectural Fill Buffer Data Sampling
|
||||
**CVE-2018-12127** [MLPDS] Microarchitectural Load Port Data Sampling
|
||||
**CVE-2019-11091** [MDSUM] Microarchitectural Data Sampling Uncacheable Memory
|
||||
|
||||
- Impact: Kernel
|
||||
- Mitigation: microcode update + kernel update making possible to protect various CPU internal buffers from unprivilaged speculative access to data
|
||||
|
||||
## Understanding what this script does and doesn't
|
||||
|
||||
This tool does its best to determine whether your system is immune (or has proper mitigations in place) for the collectively named "speculative execution" vulnerabilities. It doesn't attempt to run any kind of exploit, and can't guarantee that your system is secure, but rather helps you verifying whether your system has the known correct mitigations in place.
|
||||
|
@ -76,7 +76,7 @@ show_usage()
|
||||
--batch nrpe produce machine readable output formatted for NRPE
|
||||
--batch prometheus produce output for consumption by prometheus-node-exporter
|
||||
|
||||
--variant [1,2,3,3a,4,l1tf] specify which variant you'd like to check, by default all variants are checked
|
||||
--variant [1,2,3,3a,4,l1tf,msbds,mfbds,mlpds,mdsum] specify which variant you'd like to check, by default all variants are checked
|
||||
--cve [cve1,cve2,...] specify which CVE you'd like to check, by default all supported CVEs are checked
|
||||
can be specified multiple times (e.g. --variant 2 --variant 3)
|
||||
--hw-only only check for CPU information, don't check for any variant
|
||||
@ -153,7 +153,7 @@ global_critical=0
|
||||
global_unknown=0
|
||||
nrpe_vuln=''
|
||||
|
||||
supported_cve_list='CVE-2017-5753 CVE-2017-5715 CVE-2017-5754 CVE-2018-3640 CVE-2018-3639 CVE-2018-3615 CVE-2018-3620 CVE-2018-3646'
|
||||
supported_cve_list='CVE-2017-5753 CVE-2017-5715 CVE-2017-5754 CVE-2018-3640 CVE-2018-3639 CVE-2018-3615 CVE-2018-3620 CVE-2018-3646 CVE-2018-12126 CVE-2018-12130 CVE-2018-12127 CVE-2019-11091'
|
||||
|
||||
# find a sane command to print colored messages, we prefer `printf` over `echo`
|
||||
# because `printf` behavior is more standard across Linux/BSD
|
||||
@ -271,6 +271,10 @@ cve2name()
|
||||
CVE-2018-3615) echo "Foreshadow (SGX), L1 terminal fault";;
|
||||
CVE-2018-3620) echo "Foreshadow-NG (OS), L1 terminal fault";;
|
||||
CVE-2018-3646) echo "Foreshadow-NG (VMM), L1 terminal fault";;
|
||||
CVE-2018-12126) echo "Microarchitectural Store Buffer Data Sampling (MSBDS)";;
|
||||
CVE-2018-12130) echo "Microarchitectural Fill Buffer Data Sampling (MFBDS)";;
|
||||
CVE-2018-12127) echo "Microarchitectural Load Port Data Sampling (MLPDS)";;
|
||||
CVE-2019-11091) echo "Microarchitectural Data Sampling Uncacheable Memory (MDSUM)";;
|
||||
*) echo "$0: error: invalid CVE '$1' passed to cve2name()" >&2; exit 255;;
|
||||
esac
|
||||
}
|
||||
@ -288,6 +292,10 @@ _is_cpu_vulnerable_cached()
|
||||
CVE-2018-3615) return $variantl1tf_sgx;;
|
||||
CVE-2018-3620) return $variantl1tf;;
|
||||
CVE-2018-3646) return $variantl1tf;;
|
||||
CVE-2018-12126) return $variant_msbds;;
|
||||
CVE-2018-12130) return $variant_mfbds;;
|
||||
CVE-2018-12127) return $variant_mlpds;;
|
||||
CVE-2019-11091) return $variant_mdsum;;
|
||||
*) echo "$0: error: invalid variant '$1' passed to is_cpu_vulnerable()" >&2; exit 255;;
|
||||
esac
|
||||
}
|
||||
@ -310,6 +318,10 @@ is_cpu_vulnerable()
|
||||
variant3a=''
|
||||
variant4=''
|
||||
variantl1tf=''
|
||||
variant_msbds=''
|
||||
variant_mfbds=''
|
||||
variant_mlpds=''
|
||||
variant_mdsum=''
|
||||
|
||||
if is_cpu_specex_free; then
|
||||
variant1=immune
|
||||
@ -318,6 +330,10 @@ is_cpu_vulnerable()
|
||||
variant3a=immune
|
||||
variant4=immune
|
||||
variantl1tf=immune
|
||||
variant_msbds=immune
|
||||
variant_mfbds=immune
|
||||
variant_mlpds=immune
|
||||
variant_mdsum=immune
|
||||
elif is_intel; then
|
||||
# Intel
|
||||
# https://github.com/crozone/SpectrePoC/issues/1 ^F E5200 => spectre 2 not vulnerable
|
||||
@ -347,6 +363,13 @@ is_cpu_vulnerable()
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
|
||||
fi
|
||||
if is_cpu_mds_free; then
|
||||
[ -z "$variant_msbds" ] && variant_msbds=immune
|
||||
[ -z "$variant_mfbds" ] && variant_mfbds=immune
|
||||
[ -z "$variant_mlpds" ] && variant_mlpds=immune
|
||||
[ -z "$variant_mdsum" ] && variant_mdsum=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by Microarchitectural Data Sampling"
|
||||
fi
|
||||
# variant 4a for xeon phi
|
||||
if [ "$cpu_family" = 6 ]; then
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ]; then
|
||||
@ -395,6 +418,13 @@ is_cpu_vulnerable()
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
|
||||
fi
|
||||
if is_cpu_mds_free; then
|
||||
[ -z "$variant_msbds" ] && variant_msbds=immune
|
||||
[ -z "$variant_mfbds" ] && variant_mfbds=immune
|
||||
[ -z "$variant_mlpds" ] && variant_mlpds=immune
|
||||
[ -z "$variant_mdsum" ] && variant_mdsum=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by Microarchitectural Data Sampling"
|
||||
fi
|
||||
variantl1tf=immune
|
||||
elif [ "$cpu_vendor" = CAVIUM ]; then
|
||||
variant3=immune
|
||||
@ -496,6 +526,10 @@ is_cpu_vulnerable()
|
||||
[ "$variant3a" = "immune" ] && variant3a=1 || variant3a=0
|
||||
[ "$variant4" = "immune" ] && variant4=1 || variant4=0
|
||||
[ "$variantl1tf" = "immune" ] && variantl1tf=1 || variantl1tf=0
|
||||
[ "$variant_msbds" = "immune" ] && variant_msbds=1 || variant_msbds=0
|
||||
[ "$variant_mfbds" = "immune" ] && variant_mfbds=1 || variant_mfbds=0
|
||||
[ "$variant_mlpds" = "immune" ] && variant_mlpds=1 || variant_mlpds=0
|
||||
[ "$variant_mdsum" = "immune" ] && variant_mdsum=1 || variant_mdsum=0
|
||||
variantl1tf_sgx="$variantl1tf"
|
||||
# even if we are vulnerable to L1TF, if there's no SGX, we're safe for the original foreshadow
|
||||
[ "$cpuid_sgx" = 0 ] && variantl1tf_sgx=1
|
||||
@ -538,6 +572,51 @@ is_cpu_specex_free()
|
||||
return 1
|
||||
}
|
||||
|
||||
is_cpu_mds_free()
|
||||
{
|
||||
# return true (0) if the CPU isn't affected by microarchitectural data sampling, false (1) if it does.
|
||||
# if it's not in the list we know, return false (1).
|
||||
# source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c
|
||||
#VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
|
||||
#VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
|
||||
#VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
|
||||
|
||||
#/* AMD Family 0xf - 0x12 */
|
||||
#VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
#VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
#VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
#VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
|
||||
|
||||
#/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
|
||||
#VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
|
||||
#VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
|
||||
parse_cpu_details
|
||||
if is_intel; then
|
||||
if [ "$cpu_family" = 6 ]; then
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_X" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_PLUS" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if is_amd; then
|
||||
if [ "$cpu_family" = "18" ] || \
|
||||
[ "$cpu_family" = "17" ] || \
|
||||
[ "$cpu_family" = "16" ] || \
|
||||
[ "$cpu_family" = "15" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if is_hygon; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
is_cpu_ssb_free()
|
||||
{
|
||||
# return true (0) if the CPU isn't affected by speculative store bypass, false (1) if it does.
|
||||
@ -798,6 +877,10 @@ while [ -n "$1" ]; do
|
||||
3) opt_cve_list="$opt_cve_list CVE-2017-5754"; opt_cve_all=0;;
|
||||
3a) opt_cve_list="$opt_cve_list CVE-2018-3640"; opt_cve_all=0;;
|
||||
4) opt_cve_list="$opt_cve_list CVE-2018-3639"; opt_cve_all=0;;
|
||||
msbds) opt_cve_list="$opt_cve_list CVE-2018-12126"; opt_cve_all=0;;
|
||||
mfbds) opt_cve_list="$opt_cve_list CVE-2018-12130"; opt_cve_all=0;;
|
||||
mlpds) opt_cve_list="$opt_cve_list CVE-2018-12127"; opt_cve_all=0;;
|
||||
mdsum) opt_cve_list="$opt_cve_list CVE-2019-11091"; opt_cve_all=0;;
|
||||
l1tf) opt_cve_list="$opt_cve_list CVE-2018-3615 CVE-2018-3620 CVE-2018-3646"; opt_cve_all=0;;
|
||||
*)
|
||||
echo "$0: error: invalid parameter '$2' for --variant, expected either 1, 2, 3, 3a, 4 or l1tf" >&2;
|
||||
@ -872,6 +955,10 @@ pvulnstatus()
|
||||
CVE-2018-3615) aka="L1TF SGX";;
|
||||
CVE-2018-3620) aka="L1TF OS";;
|
||||
CVE-2018-3646) aka="L1TF VMM";;
|
||||
CVE-2018-12126) aka="MSBDS";;
|
||||
CVE-2018-12130) aka="MFBDS";;
|
||||
CVE-2018-12127) aka="MLPDS";;
|
||||
CVE-2019-11091) aka="MDSUM";;
|
||||
*) echo "$0: error: invalid CVE '$1' passed to pvulnstatus()" >&2; exit 255;;
|
||||
esac
|
||||
|
||||
@ -2267,6 +2354,8 @@ check_cpu()
|
||||
fi
|
||||
|
||||
_info_nol " * ARCH_CAPABILITIES MSR advertises IBRS_ALL capability: "
|
||||
mds_no=-1
|
||||
capabilities_mds_no=-1
|
||||
capabilities_rdcl_no=-1
|
||||
capabilities_ibrs_all=-1
|
||||
capabilities_rsba=-1
|
||||
@ -2276,6 +2365,7 @@ check_cpu()
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$cpuid_arch_capabilities" != 1 ]; then
|
||||
capabilities_rdcl_no=0
|
||||
capabilities_mds_no=0
|
||||
capabilities_ibrs_all=0
|
||||
capabilities_rsba=0
|
||||
capabilities_l1dflush_no=0
|
||||
@ -2307,6 +2397,7 @@ check_cpu()
|
||||
done
|
||||
capabilities=$val_cap_msr
|
||||
capabilities_rdcl_no=0
|
||||
capabilities_mds_no=0
|
||||
capabilities_ibrs_all=0
|
||||
capabilities_rsba=0
|
||||
capabilities_l1dflush_no=0
|
||||
@ -2318,7 +2409,8 @@ check_cpu()
|
||||
[ $(( capabilities >> 2 & 1 )) -eq 1 ] && capabilities_rsba=1
|
||||
[ $(( capabilities >> 3 & 1 )) -eq 1 ] && capabilities_l1dflush_no=1
|
||||
[ $(( capabilities >> 4 & 1 )) -eq 1 ] && capabilities_ssb_no=1
|
||||
_debug "capabilities says rdcl_no=$capabilities_rdcl_no ibrs_all=$capabilities_ibrs_all rsba=$capabilities_rsba l1dflush_no=$capabilities_l1dflush_no ssb_no=$capabilities_ssb_no"
|
||||
[ $(( capabilities >> 5 & 1 )) -eq 1 ] && capabilities_mds_no=1
|
||||
_debug "capabilities says rdcl_no=$capabilities_rdcl_no ibrs_all=$capabilities_ibrs_all rsba=$capabilities_rsba l1dflush_no=$capabilities_l1dflush_no ssb_no=$capabilities_ssb_no mds_no=$capabilities_mds_no"
|
||||
if [ "$capabilities_ibrs_all" = 1 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
pstatus green YES
|
||||
@ -2372,6 +2464,15 @@ check_cpu()
|
||||
else
|
||||
pstatus blue NO
|
||||
fi
|
||||
|
||||
_info_nol " * CPU explicitly indicates not being vulnerable to Microarchitectural Data Sampling (MDC_NO): "
|
||||
if [ "$capabilities_mds_no" = -1 ]; then
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$capabilities_mds_no" = 1 ]; then
|
||||
pstatus green YES
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
fi
|
||||
|
||||
_info_nol " * CPU supports Software Guard Extensions (SGX): "
|
||||
@ -4114,6 +4215,111 @@ check_CVE_2018_3646_bsd()
|
||||
fi
|
||||
}
|
||||
|
||||
###################
|
||||
# MSBDS SECTION
|
||||
|
||||
# Microarchitectural Store Buffer Data Sampling
|
||||
check_CVE_2018_12126()
|
||||
{
|
||||
cve='CVE-2018-12126'
|
||||
|
||||
check_mds $cve
|
||||
}
|
||||
|
||||
###################
|
||||
# MFBDS SECTION
|
||||
|
||||
# Microarchitectural Fill Buffer Data Sampling
|
||||
check_CVE_2018_12130()
|
||||
{
|
||||
cve='CVE-2018-12130'
|
||||
|
||||
check_mds $cve
|
||||
}
|
||||
|
||||
###################
|
||||
# MLPDS SECTION
|
||||
|
||||
# Microarchitectural Load Port Data Sampling
|
||||
check_CVE_2018_12127()
|
||||
{
|
||||
cve='CVE-2018-12127'
|
||||
|
||||
check_mds $cve
|
||||
}
|
||||
|
||||
###################
|
||||
# MDSUM SECTION
|
||||
|
||||
# Microarchitectural Data Sampling Uncacheable Memory
|
||||
check_CVE_2019_11091()
|
||||
{
|
||||
cve='CVE-2019-11091'
|
||||
|
||||
check_mds $cve
|
||||
}
|
||||
|
||||
# Microarchitectural Data Sampling
|
||||
check_mds()
|
||||
{
|
||||
sys_interface_available=0
|
||||
|
||||
cve=$1
|
||||
_info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m"
|
||||
|
||||
if [ "$opt_live" != 1 ]; then
|
||||
pstatus blue N/A "not testable in offline mode"
|
||||
pvulnstatus $cve UNK
|
||||
return
|
||||
fi
|
||||
|
||||
if ! is_cpu_vulnerable "$cve" ; then
|
||||
# override status & msg in case CPU is not vulnerable after all
|
||||
pvulnstatus $cve OK "your CPU vendor reported your CPU model as not vulnerable"
|
||||
return
|
||||
fi
|
||||
|
||||
if sys_interface_check '/sys/devices/system/cpu/vulnerabilities/mds'; then
|
||||
# this kernel has the /sys interface, trust it over everything
|
||||
sys_interface_available=1
|
||||
fi
|
||||
|
||||
if [ "$sys_interface_available" = 1 ]; then
|
||||
if grep -Eq 'Not affected' "/sys/devices/system/cpu/vulnerabilities/mds"; then
|
||||
mds_mitigated=1
|
||||
elif grep -Eq '(Mitigation: Clear CPU buffers)' "/sys/devices/system/cpu/vulnerabilities/mds"; then
|
||||
if grep -Eq '(SMT mitigated|disabled)' "/sys/devices/system/cpu/vulnerabilities/mds"; then
|
||||
mds_mitigated=1
|
||||
else
|
||||
#Simultaneous multi-threading (aka SMT or HyperThreading) is enabled. System may be vulnerable in some environments.
|
||||
mds_mitigated=0
|
||||
_info_nol "* Disable SMT to have complete mitigation\n"
|
||||
fi
|
||||
elif grep -Eq 'Vulnerable' "/sys/devices/system/cpu/vulnerabilities/mds"; then
|
||||
mds_mitigated=0
|
||||
_info_nol "* For more info check Linux kernel Documentation/admin-guide/hw-vuln/mds.rst\n"
|
||||
else
|
||||
mds_mitigated=-1
|
||||
fi
|
||||
|
||||
if grep -Eq 'no microcode' "/sys/devices/system/cpu/vulnerabilities/mds"; then
|
||||
mds_mitigated=0
|
||||
_info_nol "* CPU microcode is needed to mitigate the vulnerability\n"
|
||||
fi
|
||||
else
|
||||
pstatus yellow UNKNOWN "can't find or interpret /sys/devices/system/cpu/vulnerabilities/mds"
|
||||
mds_mitigated=-1
|
||||
fi
|
||||
|
||||
if [ $mds_mitigated = 0 ];then
|
||||
pvulnstatus $cve VULN
|
||||
elif [ $mds_mitigated = 1 ]; then
|
||||
pvulnstatus $cve OK
|
||||
else
|
||||
pvulnstatus $cve UNK "further action may be needed to mitigate this vulnerability. For more info check Linux kernel Documentation/admin-guide/hw-vuln/mds.rst"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$opt_no_hw" = 0 ] && [ -z "$opt_arch_prefix" ]; then
|
||||
check_cpu
|
||||
check_cpu_vulnerabilities
|
||||
|
Loading…
Reference in New Issue
Block a user