mirror of
https://github.com/speed47/spectre-meltdown-checker
synced 2024-12-22 12:23:36 +01:00
feat: add detection of iTLB Multihit vuln/mitigation (CVE-2018-12207)
This commit is contained in:
parent
8ddf6b2d6d
commit
bd47275501
6
.github/workflows/check.yml
vendored
6
.github/workflows/check.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
fi
|
||||
- name: check direct execution
|
||||
run: |
|
||||
expected=13
|
||||
expected=14
|
||||
nb=$(sudo ./spectre-meltdown-checker.sh --batch json | jq '.[]|.CVE' | wc -l)
|
||||
if [ "$nb" -ne "$expected" ]; then
|
||||
echo "Invalid number of CVEs reported: $nb instead of $expected"
|
||||
@ -34,7 +34,7 @@ jobs:
|
||||
fi
|
||||
- name: check docker-compose run execution
|
||||
run: |
|
||||
expected=13
|
||||
expected=14
|
||||
docker-compose build
|
||||
nb=$(docker-compose run --rm spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l)
|
||||
if [ "$nb" -ne "$expected" ]; then
|
||||
@ -45,7 +45,7 @@ jobs:
|
||||
fi
|
||||
- name: check docker run execution
|
||||
run: |
|
||||
expected=13
|
||||
expected=14
|
||||
docker build -t spectre-meltdown-checker .
|
||||
nb=$(docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/modules:/lib/modules:ro spectre-meltdown-checker --batch json | jq '.[]|.CVE' | wc -l)
|
||||
if [ "$nb" -ne "$expected" ]; then
|
||||
|
11
README.md
11
README.md
@ -14,7 +14,8 @@ A shell script to tell if your system is vulnerable against the several "specula
|
||||
- CVE-2018-12130 [microarchitectural fill buffer data sampling (MFBDS)] aka 'ZombieLoad'
|
||||
- CVE-2018-12127 [microarchitectural load port data sampling (MLPDS)] aka 'RIDL'
|
||||
- CVE-2019-11091 [microarchitectural data sampling uncacheable memory (MDSUM)] aka 'RIDL'
|
||||
- CVE-2019-11135 [TSX asynchronous abort] aka 'TAA'
|
||||
- CVE-2019-11135 [TSX asynchronous abort] aka 'TAA' aka 'ZombieLoad V2'
|
||||
- CVE-2018-12207 [iTLB Multihit] aka 'No eXcuses'
|
||||
|
||||
Supported operating systems:
|
||||
- Linux (all versions, flavors and distros)
|
||||
@ -146,12 +147,18 @@ docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/m
|
||||
- Mitigation: microcode update + kernel update making possible to protect various CPU internal buffers from unprivileged speculative access to data
|
||||
- Performance impact of the mitigation: low to significant
|
||||
|
||||
**CVE-2019-11135** TSX Asynchronous Abort (TAA)
|
||||
**CVE-2019-11135** TSX Asynchronous Abort (TAA, ZombieLoad V2)
|
||||
|
||||
- Impact: Kernel
|
||||
- Mitigation: microcode update + kernel update making possible to protect various CPU internal buffers from unprivileged speculative access to data
|
||||
- Performance impact of the mitigation: low to significant
|
||||
|
||||
**CVE-2018-12207** iTLB Multihit (No eXcuses)
|
||||
|
||||
- Impact: Virtualization software and Virtual Machine Monitors
|
||||
- Mitigation: disable hugepages use in hypervisor, or update hypervisor to benefit from mitigation
|
||||
- Performance impact of the mitigation: low to significant
|
||||
|
||||
## 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.
|
||||
|
@ -163,7 +163,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 CVE-2018-12126 CVE-2018-12130 CVE-2018-12127 CVE-2019-11091 CVE-2019-11135'
|
||||
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 CVE-2019-11135 CVE-2018-12207'
|
||||
|
||||
# find a sane command to print colored messages, we prefer `printf` over `echo`
|
||||
# because `printf` behavior is more standard across Linux/BSD
|
||||
@ -285,7 +285,8 @@ cve2name()
|
||||
CVE-2018-12130) echo "ZombieLoad, microarchitectural fill buffer data sampling (MFBDS)";;
|
||||
CVE-2018-12127) echo "RIDL, microarchitectural load port data sampling (MLPDS)";;
|
||||
CVE-2019-11091) echo "RIDL, microarchitectural data sampling uncacheable memory (MDSUM)";;
|
||||
CVE-2019-11135) echo "Transactional Synchronization Extensions (TSX) Asynchronous Abort (TAA)";;
|
||||
CVE-2019-11135) echo "ZombieLoad V2, TSX Asynchronous Abort (TAA)";;
|
||||
CVE-2018-12207) echo "No eXcuses, iTLB Multihit";;
|
||||
*) echo "$0: error: invalid CVE '$1' passed to cve2name()" >&2; exit 255;;
|
||||
esac
|
||||
}
|
||||
@ -308,6 +309,7 @@ _is_cpu_vulnerable_cached()
|
||||
CVE-2018-12127) return $variant_mlpds;;
|
||||
CVE-2019-11091) return $variant_mdsum;;
|
||||
CVE-2019-11135) return $variant_taa;;
|
||||
CVE-2018-12207) return $variant_itlbmh;;
|
||||
*) echo "$0: error: invalid variant '$1' passed to is_cpu_vulnerable()" >&2; exit 255;;
|
||||
esac
|
||||
}
|
||||
@ -335,6 +337,7 @@ is_cpu_vulnerable()
|
||||
variant_mlpds=''
|
||||
variant_mdsum=''
|
||||
variant_taa=''
|
||||
variant_itlbmh=''
|
||||
|
||||
if is_cpu_mds_free; then
|
||||
[ -z "$variant_msbds" ] && variant_msbds=immune
|
||||
@ -406,25 +409,55 @@ is_cpu_vulnerable()
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_BONNELL_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_X" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT_NP" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_X" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_PLUS" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_TREMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ]; then
|
||||
|
||||
_debug "is_cpu_vulnerable: intel family 6 but model known to be immune"
|
||||
_debug "is_cpu_vulnerable: intel family 6 but model known to be immune to l1tf"
|
||||
[ -z "$variantl1tf" ] && variantl1tf=immune
|
||||
else
|
||||
_debug "is_cpu_vulnerable: intel family 6 is vuln"
|
||||
[ -z "$variantl1tf" ] && variantl1tf=vuln
|
||||
_debug "is_cpu_vulnerable: intel family 6 is vuln to l1tf"
|
||||
variantl1tf=vuln
|
||||
fi
|
||||
elif [ "$cpu_family" -lt 6 ]; then
|
||||
_debug "is_cpu_vulnerable: intel family < 6 is immune"
|
||||
_debug "is_cpu_vulnerable: intel family < 6 is immune to l1tf"
|
||||
[ -z "$variantl1tf" ] && variantl1tf=immune
|
||||
fi
|
||||
# iTLB MultiHit
|
||||
# commit f9aa6b73a407b714c9aac44734eb4045c893c6f7
|
||||
if [ "$cpu_model" = 6 ]; then
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_ATOM_SALTWELL" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SALTWELL_TABLET" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SALTWELL_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_BONNELL" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_BONNELL_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT_MID" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_PLUS" ]; then
|
||||
_debug "is_cpu_vulnerable: intel family 6 but model known to be immune to itlbmh"
|
||||
[ -z "$variantitlbmh" ] && variantitlbmh=immune
|
||||
else
|
||||
_debug "is_cpu_vulnerable: intel family 6 is vuln to itlbmh"
|
||||
variantitlbmh=vuln
|
||||
fi
|
||||
elif [ "$cpu_family" -lt 6 ]; then
|
||||
_debug "is_cpu_vulnerable: intel family < 6 is immune to itlbmh"
|
||||
[ -z "$variantitlbmh" ] && variantitlbmh=immune
|
||||
fi
|
||||
elif is_amd || is_hygon; then
|
||||
# AMD revised their statement about variant2 => vulnerable
|
||||
# https://www.amd.com/en/corporate/speculative-execution
|
||||
@ -439,10 +472,12 @@ is_cpu_vulnerable()
|
||||
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
|
||||
fi
|
||||
variantl1tf=immune
|
||||
variantitlbmh=immune
|
||||
elif [ "$cpu_vendor" = CAVIUM ]; then
|
||||
variant3=immune
|
||||
variant3a=immune
|
||||
variantl1tf=immune
|
||||
variantitlbmh=immune
|
||||
elif [ "$cpu_vendor" = ARM ]; then
|
||||
# ARM
|
||||
# reference: https://developer.arm.com/support/security-update
|
||||
@ -531,19 +566,21 @@ is_cpu_vulnerable()
|
||||
_debug "is_cpu_vulnerable: for cpu$i and so far, we have <$variant1> <$variant2> <$variant3> <$variant3a> <$variant4>"
|
||||
done
|
||||
variantl1tf=immune
|
||||
variantitlbmh=immune
|
||||
fi
|
||||
_debug "is_cpu_vulnerable: temp results are <$variant1> <$variant2> <$variant3> <$variant3a> <$variant4> <$variantl1tf>"
|
||||
[ "$variant1" = "immune" ] && variant1=1 || variant1=0
|
||||
[ "$variant2" = "immune" ] && variant2=1 || variant2=0
|
||||
[ "$variant3" = "immune" ] && variant3=1 || variant3=0
|
||||
[ "$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
|
||||
[ "$variant_taa" = "immune" ] && variant_taa=1 || variant_taa=0
|
||||
[ "$variant1" = "immune" ] && variant1=1 || variant1=0
|
||||
[ "$variant2" = "immune" ] && variant2=1 || variant2=0
|
||||
[ "$variant3" = "immune" ] && variant3=1 || variant3=0
|
||||
[ "$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
|
||||
[ "$variant_taa" = "immune" ] && variant_taa=1 || variant_taa=0
|
||||
[ "$variant_itlbmh" = "immune" ] && variant_itlbmh=1 || variant_itlbmh=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
|
||||
@ -608,7 +645,7 @@ is_cpu_mds_free()
|
||||
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_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_GOLDMONT_PLUS" ]; then
|
||||
return 0
|
||||
fi
|
||||
@ -675,7 +712,7 @@ is_cpu_ssb_free()
|
||||
if [ "$cpu_family" = 6 ]; then
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_X" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_D" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT_MID" ]; then
|
||||
return 0
|
||||
elif [ "$cpu_model" = "$INTEL_FAM6_CORE_YONAH" ] || \
|
||||
@ -1077,6 +1114,7 @@ pvulnstatus()
|
||||
CVE-2018-12127) aka="MLPDS";;
|
||||
CVE-2019-11091) aka="MDSUM";;
|
||||
CVE-2019-11135) aka="TAA";;
|
||||
CVE-2018-12207) aka="ITLBMH";;
|
||||
*) echo "$0: error: invalid CVE '$1' passed to pvulnstatus()" >&2; exit 255;;
|
||||
esac
|
||||
|
||||
@ -1513,66 +1551,68 @@ parse_cpu_details()
|
||||
ucode_found=$(printf "model 0x%x family 0x%x stepping 0x%x ucode 0x%x cpuid 0x%x" "$cpu_model" "$cpu_family" "$cpu_stepping" "$cpu_ucode" "$cpu_cpuid")
|
||||
|
||||
# also define those that we will need in other funcs
|
||||
# taken from ttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/intel-family.h
|
||||
# taken from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/include/asm/intel-family.h
|
||||
# curl -s 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/arch/x86/include/asm/intel-family.h' | awk '/#define INTEL_FAM6/ {print $2"=$(( "$3" )) # "$4,$5,$6,$7,$8,$9}'
|
||||
# shellcheck disable=SC2034
|
||||
{
|
||||
INTEL_FAM6_CORE_YONAH=$(( 0x0E )) #
|
||||
INTEL_FAM6_CORE2_MEROM=$(( 0x0F )) #
|
||||
INTEL_FAM6_CORE2_MEROM_L=$(( 0x16 )) #
|
||||
INTEL_FAM6_CORE2_PENRYN=$(( 0x17 )) #
|
||||
INTEL_FAM6_CORE2_DUNNINGTON=$(( 0x1D )) #
|
||||
INTEL_FAM6_NEHALEM=$(( 0x1E )) #
|
||||
INTEL_FAM6_NEHALEM_G=$(( 0x1F )) # /* Auburndale / Havendale */
|
||||
INTEL_FAM6_NEHALEM_EP=$(( 0x1A )) #
|
||||
INTEL_FAM6_NEHALEM_EX=$(( 0x2E )) #
|
||||
INTEL_FAM6_WESTMERE=$(( 0x25 )) #
|
||||
INTEL_FAM6_WESTMERE_EP=$(( 0x2C )) #
|
||||
INTEL_FAM6_WESTMERE_EX=$(( 0x2F )) #
|
||||
INTEL_FAM6_SANDYBRIDGE=$(( 0x2A )) #
|
||||
INTEL_FAM6_SANDYBRIDGE_X=$(( 0x2D )) #
|
||||
INTEL_FAM6_IVYBRIDGE=$(( 0x3A )) #
|
||||
INTEL_FAM6_IVYBRIDGE_X=$(( 0x3E )) #
|
||||
INTEL_FAM6_HASWELL=$(( 0x3C )) #
|
||||
INTEL_FAM6_HASWELL_X=$(( 0x3F )) #
|
||||
INTEL_FAM6_HASWELL_L=$(( 0x45 )) #
|
||||
INTEL_FAM6_HASWELL_G=$(( 0x46 )) #
|
||||
INTEL_FAM6_BROADWELL=$(( 0x3D )) #
|
||||
INTEL_FAM6_BROADWELL_G=$(( 0x47 )) #
|
||||
INTEL_FAM6_BROADWELL_X=$(( 0x4F )) #
|
||||
INTEL_FAM6_BROADWELL_D=$(( 0x56 )) #
|
||||
INTEL_FAM6_SKYLAKE_L=$(( 0x4E )) #
|
||||
INTEL_FAM6_SKYLAKE=$(( 0x5E )) #
|
||||
INTEL_FAM6_SKYLAKE_X=$(( 0x55 )) #
|
||||
INTEL_FAM6_KABYLAKE_L=$(( 0x8E )) #
|
||||
INTEL_FAM6_KABYLAKE=$(( 0x9E )) #
|
||||
INTEL_FAM6_CANNONLAKE_L=$(( 0x66 )) #
|
||||
INTEL_FAM6_ICELAKE_X=$(( 0x6A )) #
|
||||
INTEL_FAM6_ICELAKE_D=$(( 0x6C )) #
|
||||
INTEL_FAM6_ICELAKE=$(( 0x7D )) #
|
||||
INTEL_FAM6_ICELAKE_L=$(( 0x7E )) #
|
||||
INTEL_FAM6_ICELAKE_NNPI=$(( 0x9D )) #
|
||||
INTEL_FAM6_TIGERLAKE_L=$(( 0x8C )) #
|
||||
INTEL_FAM6_TIGERLAKE=$(( 0x8D )) #
|
||||
INTEL_FAM6_COMETLAKE=$(( 0xA5 )) #
|
||||
INTEL_FAM6_COMETLAKE_L=$(( 0xA6 )) #
|
||||
INTEL_FAM6_ATOM_BONNELL=$(( 0x1C )) # /* Diamondville, Pineview */
|
||||
INTEL_FAM6_ATOM_BONNELL_MID=$(( 0x26 )) # /* Silverthorne, Lincroft */
|
||||
INTEL_FAM6_ATOM_SALTWELL=$(( 0x36 )) # /* Cedarview */
|
||||
INTEL_FAM6_ATOM_SALTWELL_MID=$(( 0x27 )) # /* Penwell */
|
||||
INTEL_FAM6_ATOM_SALTWELL_TABLET=$(( 0x35 )) # /* Cloverview */
|
||||
INTEL_FAM6_ATOM_SILVERMONT=$(( 0x37 )) # /* Bay Trail, Valleyview */
|
||||
INTEL_FAM6_ATOM_SILVERMONT_D=$(( 0x4D )) # /* Avaton, Rangely */
|
||||
INTEL_FAM6_ATOM_SILVERMONT_MID=$(( 0x4A )) # /* Merriefield */
|
||||
INTEL_FAM6_ATOM_AIRMONT=$(( 0x4C )) # /* Cherry Trail, Braswell */
|
||||
INTEL_FAM6_ATOM_AIRMONT_MID=$(( 0x5A )) # /* Moorefield */
|
||||
INTEL_FAM6_ATOM_AIRMONT_NP=$(( 0x75 )) # /* Lightning Mountain */
|
||||
INTEL_FAM6_ATOM_GOLDMONT=$(( 0x5C )) # /* Apollo Lake */
|
||||
INTEL_FAM6_ATOM_GOLDMONT_D=$(( 0x5F )) # /* Denverton */
|
||||
INTEL_FAM6_ATOM_GOLDMONT_PLUS=$(( 0x7A )) # /* Gemini Lake */
|
||||
INTEL_FAM6_ATOM_TREMONT_D=$(( 0x86 )) # /* Jacobsville */
|
||||
INTEL_FAM6_ATOM_TREMONT=$(( 0x96 )) # /* Elkhart Lake */
|
||||
INTEL_FAM6_XEON_PHI_KNL=$(( 0x57 )) # /* Knights Landing */
|
||||
INTEL_FAM6_XEON_PHI_KNM=$(( 0x85 )) # /* Knights Mill */
|
||||
INTEL_FAM6_CORE_YONAH=$(( 0x0E ))
|
||||
|
||||
INTEL_FAM6_CORE2_MEROM=$(( 0x0F ))
|
||||
INTEL_FAM6_CORE2_MEROM_L=$(( 0x16 ))
|
||||
INTEL_FAM6_CORE2_PENRYN=$(( 0x17 ))
|
||||
INTEL_FAM6_CORE2_DUNNINGTON=$(( 0x1D ))
|
||||
|
||||
INTEL_FAM6_NEHALEM=$(( 0x1E ))
|
||||
INTEL_FAM6_NEHALEM_G=$(( 0x1F ))
|
||||
INTEL_FAM6_NEHALEM_EP=$(( 0x1A ))
|
||||
INTEL_FAM6_NEHALEM_EX=$(( 0x2E ))
|
||||
|
||||
INTEL_FAM6_WESTMERE=$(( 0x25 ))
|
||||
INTEL_FAM6_WESTMERE_EP=$(( 0x2C ))
|
||||
INTEL_FAM6_WESTMERE_EX=$(( 0x2F ))
|
||||
|
||||
INTEL_FAM6_SANDYBRIDGE=$(( 0x2A ))
|
||||
INTEL_FAM6_SANDYBRIDGE_X=$(( 0x2D ))
|
||||
INTEL_FAM6_IVYBRIDGE=$(( 0x3A ))
|
||||
INTEL_FAM6_IVYBRIDGE_X=$(( 0x3E ))
|
||||
|
||||
INTEL_FAM6_HASWELL_CORE=$(( 0x3C ))
|
||||
INTEL_FAM6_HASWELL_X=$(( 0x3F ))
|
||||
INTEL_FAM6_HASWELL_ULT=$(( 0x45 ))
|
||||
INTEL_FAM6_HASWELL_GT3E=$(( 0x46 ))
|
||||
|
||||
INTEL_FAM6_BROADWELL_CORE=$(( 0x3D ))
|
||||
INTEL_FAM6_BROADWELL_GT3E=$(( 0x47 ))
|
||||
INTEL_FAM6_BROADWELL_X=$(( 0x4F ))
|
||||
INTEL_FAM6_BROADWELL_XEON_D=$(( 0x56 ))
|
||||
|
||||
INTEL_FAM6_SKYLAKE_MOBILE=$(( 0x4E ))
|
||||
INTEL_FAM6_SKYLAKE_DESKTOP=$(( 0x5E ))
|
||||
INTEL_FAM6_SKYLAKE_X=$(( 0x55 ))
|
||||
INTEL_FAM6_KABYLAKE_MOBILE=$(( 0x8E ))
|
||||
INTEL_FAM6_KABYLAKE_DESKTOP=$(( 0x9E ))
|
||||
|
||||
# /* "Small Core" Processors (Atom) */
|
||||
|
||||
INTEL_FAM6_ATOM_BONNELL=$(( 0x1C ))
|
||||
INTEL_FAM6_ATOM_BONNELL_MID=$(( 0x26 ))
|
||||
INTEL_FAM6_ATOM_SALTWELL_MID=$(( 0x27 ))
|
||||
INTEL_FAM6_ATOM_SALTWELL_TABLET=$(( 0x35 ))
|
||||
INTEL_FAM6_ATOM_SALTWELL=$(( 0x36 ))
|
||||
INTEL_FAM6_ATOM_SILVERMONT=$(( 0x37 ))
|
||||
INTEL_FAM6_ATOM_SILVERMONT_MID=$(( 0x4A ))
|
||||
INTEL_FAM6_ATOM_SILVERMONT_X=$(( 0x4D ))
|
||||
INTEL_FAM6_ATOM_AIRMONT=$(( 0x4C ))
|
||||
INTEL_FAM6_ATOM_AIRMONT_MID=$(( 0x5A ))
|
||||
INTEL_FAM6_ATOM_GOLDMONT=$(( 0x5C ))
|
||||
INTEL_FAM6_ATOM_GOLDMONT_X=$(( 0x5F ))
|
||||
INTEL_FAM6_ATOM_GOLDMONT_PLUS=$(( 0x7A ))
|
||||
|
||||
# /* Xeon Phi */
|
||||
|
||||
INTEL_FAM6_XEON_PHI_KNL=$(( 0x57 ))
|
||||
INTEL_FAM6_XEON_PHI_KNM=$(( 0x85 ))
|
||||
}
|
||||
parse_cpu_details_done=1
|
||||
}
|
||||
@ -1639,7 +1679,7 @@ is_ucode_blacklisted()
|
||||
$INTEL_FAM6_BROADWELL_XEON_D,0x03,0x07000011 \
|
||||
$INTEL_FAM6_BROADWELL_X,0x01,0x0b000023 \
|
||||
$INTEL_FAM6_BROADWELL_X,0x01,0x0b000025 \
|
||||
$INTEL_FAM6_HASWELL_ULT,0x01,0x21 \
|
||||
$INTEL_FAM6_HASWELL_L,0x01,0x21 \
|
||||
$INTEL_FAM6_HASWELL_GT3E,0x01,0x18 \
|
||||
$INTEL_FAM6_HASWELL_CORE,0x03,0x23 \
|
||||
$INTEL_FAM6_HASWELL_X,0x02,0x3b \
|
||||
@ -1648,10 +1688,10 @@ is_ucode_blacklisted()
|
||||
$INTEL_FAM6_SANDYBRIDGE_X,0x06,0x61b \
|
||||
$INTEL_FAM6_SANDYBRIDGE_X,0x07,0x712
|
||||
do
|
||||
model=$(echo $tuple | cut -d, -f1)
|
||||
stepping=$(( $(echo $tuple | cut -d, -f2) ))
|
||||
model=$(echo "$tuple" | cut -d, -f1)
|
||||
stepping=$(( $(echo "$tuple" | cut -d, -f2) ))
|
||||
if [ "$cpu_model" = "$model" ] && [ "$cpu_stepping" = "$stepping" ]; then
|
||||
ucode=$(( $(echo $tuple | cut -d, -f3) ))
|
||||
ucode=$(( $(echo "$tuple" | cut -d, -f3) ))
|
||||
if [ "$cpu_ucode" = "$ucode" ]; then
|
||||
_debug "is_ucode_blacklisted: we have a match! ($cpu_model/$cpu_stepping/$cpu_ucode)"
|
||||
return 0
|
||||
@ -1678,11 +1718,11 @@ is_skylake_cpu()
|
||||
parse_cpu_details
|
||||
is_intel || return 1
|
||||
[ "$cpu_family" = 6 ] || return 1
|
||||
if [ "$cpu_model" = $INTEL_FAM6_SKYLAKE_MOBILE ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_SKYLAKE_DESKTOP ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_SKYLAKE_X ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_KABYLAKE_MOBILE ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_KABYLAKE_DESKTOP ]; then
|
||||
if [ "$cpu_model" = $INTEL_FAM6_SKYLAKE_L ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_SKYLAKE ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_SKYLAKE_X ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_KABYLAKE_L ] || \
|
||||
[ "$cpu_model" = $INTEL_FAM6_KABYLAKE ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@ -2138,7 +2178,7 @@ sys_interface_check()
|
||||
# Not affected
|
||||
status=OK
|
||||
pstatus green YES "$fullmsg"
|
||||
elif echo "$msg" | grep -qi '^mitigation'; then
|
||||
elif echo "$msg" | grep -qEi '^(kvm: )?mitigation'; then
|
||||
# Mitigation: PTI
|
||||
status=OK
|
||||
pstatus green YES "$fullmsg"
|
||||
@ -2709,6 +2749,7 @@ check_cpu()
|
||||
capabilities_rsba=-1
|
||||
capabilities_l1dflush_no=-1
|
||||
capabilities_ssb_no=-1
|
||||
capabilities_pschange_msc_no=-1
|
||||
if [ "$cpuid_arch_capabilities" = -1 ]; then
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$cpuid_arch_capabilities" != 1 ]; then
|
||||
@ -2719,6 +2760,7 @@ check_cpu()
|
||||
capabilities_rsba=0
|
||||
capabilities_l1dflush_no=0
|
||||
capabilities_ssb_no=0
|
||||
capabilities_pschange_msc_no=0
|
||||
pstatus yellow NO
|
||||
elif [ ! -e /dev/cpu/0/msr ] && [ ! -e /dev/cpuctl0 ]; then
|
||||
spec_ctrl_msr=-1
|
||||
@ -2752,6 +2794,7 @@ check_cpu()
|
||||
capabilities_rsba=0
|
||||
capabilities_l1dflush_no=0
|
||||
capabilities_ssb_no=0
|
||||
capabilities_pschange_msc_no=0
|
||||
if [ $val -eq 0 ]; then
|
||||
_debug "capabilities MSR is $capabilities (decimal)"
|
||||
[ $(( capabilities >> 0 & 1 )) -eq 1 ] && capabilities_rdcl_no=1
|
||||
@ -2760,8 +2803,9 @@ check_cpu()
|
||||
[ $(( capabilities >> 3 & 1 )) -eq 1 ] && capabilities_l1dflush_no=1
|
||||
[ $(( capabilities >> 4 & 1 )) -eq 1 ] && capabilities_ssb_no=1
|
||||
[ $(( capabilities >> 5 & 1 )) -eq 1 ] && capabilities_mds_no=1
|
||||
[ $(( capabilities >> 6 & 1 )) -eq 1 ] && capabilities_pschange_msc_no=1
|
||||
[ $(( capabilities >> 8 & 1 )) -eq 1 ] && capabilities_taa_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 taa_no=$capabilities_taa_no"
|
||||
_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 taa_no=$capabilities_taa_no pschange_msc_no=$capabilities_pschange_msc_no"
|
||||
if [ "$capabilities_ibrs_all" = 1 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
pstatus green YES
|
||||
@ -2827,7 +2871,7 @@ check_cpu()
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
_info_nol " * CPU explicitly indicates not being vulnerable to TSX Asynchrnonous Abort (TAA_NO): "
|
||||
_info_nol " * CPU explicitly indicates not being vulnerable to TSX Asynchronous Abort (TAA_NO): "
|
||||
if [ "$capabilities_taa_no" = -1 ]; then
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$capabilities_taa_no" = 1 ]; then
|
||||
@ -2835,6 +2879,15 @@ check_cpu()
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
_info_nol " * CPU explicitly indicates not being vulnerable to iTLB Multihit (PSCHANGE_MSC_NO): "
|
||||
if [ "$capabilities_pschange_msc_no" = -1 ]; then
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$capabilities_pschange_msc_no" = 1 ]; then
|
||||
pstatus green YES
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
fi
|
||||
|
||||
_info_nol " * CPU supports Software Guard Extensions (SGX): "
|
||||
@ -2918,6 +2971,52 @@ check_redhat_canonical_spectre()
|
||||
fi
|
||||
}
|
||||
|
||||
check_has_vmm()
|
||||
{
|
||||
_info_nol "* This system is a host running a hypervisor: "
|
||||
has_vmm=$opt_vmm
|
||||
if [ "$has_vmm" = -1 ] && [ "$opt_paranoid" = 1 ]; then
|
||||
# In paranoid mode, if --vmm was not specified on the command-line,
|
||||
# we want to be secure before everything else, so assume we're running
|
||||
# a hypervisor, as this requires more mitigations
|
||||
has_vmm=2
|
||||
elif [ "$has_vmm" = -1 ]; then
|
||||
# Here, we want to know if we are hosting a hypervisor, and running some VMs on it.
|
||||
# If we find no evidence that this is the case, assume we're not (to avoid scaring users),
|
||||
# this can always be overridden with --vmm in any case.
|
||||
has_vmm=0
|
||||
if command -v pgrep >/dev/null 2>&1; then
|
||||
# remove xenbus and xenwatch, also present inside domU
|
||||
# remove libvirtd as it can also be used to manage containers and not VMs
|
||||
if pgrep qemu >/dev/null || pgrep kvm >/dev/null || \
|
||||
pgrep xenstored >/dev/null || pgrep xenconsoled >/dev/null; then
|
||||
has_vmm=1
|
||||
fi
|
||||
else
|
||||
# ignore SC2009 as `ps ax` is actually used as a fallback if `pgrep` isn't installed
|
||||
# shellcheck disable=SC2009
|
||||
if ps ax | grep -vw grep | grep -q -e '\<qemu' -e '/qemu' -e '<\kvm' -e '/kvm' -e '/xenstored' -e '/xenconsoled'; then
|
||||
has_vmm=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$has_vmm" = 0 ]; then
|
||||
if [ "$opt_vmm" != -1 ]; then
|
||||
pstatus green NO "forced from command line"
|
||||
else
|
||||
pstatus green NO
|
||||
fi
|
||||
else
|
||||
if [ "$opt_vmm" != -1 ]; then
|
||||
pstatus blue YES "forced from command line"
|
||||
elif [ "$has_vmm" = 2 ]; then
|
||||
pstatus blue YES "paranoid mode"
|
||||
else
|
||||
pstatus blue YES
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
###################
|
||||
# SPECTRE 1 SECTION
|
||||
|
||||
@ -4210,7 +4309,7 @@ check_CVE_2018_3615()
|
||||
_info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m"
|
||||
|
||||
_info_nol "* CPU microcode mitigates the vulnerability: "
|
||||
if ( [ "$cpu_flush_cmd" = 1 ] || ( [ "$msr_locked_down" = 1 ] && [ "$cpuid_l1df" = 1 ] ) ) && [ "$cpuid_sgx" = 1 ]; then
|
||||
if { [ "$cpu_flush_cmd" = 1 ] || { [ "$msr_locked_down" = 1 ] && [ "$cpuid_l1df" = 1 ]; }; } && [ "$cpuid_sgx" = 1 ]; then
|
||||
# no easy way to detect a fixed SGX but we know that
|
||||
# microcodes that have the FLUSH_CMD MSR also have the
|
||||
# fixed SGX (for CPUs that support it), because Intel
|
||||
@ -4229,7 +4328,7 @@ check_CVE_2018_3615()
|
||||
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"
|
||||
elif [ "$cpu_flush_cmd" = 1 ] || ( [ "$msr_locked_down" = 1 ] && [ "$cpuid_l1df" = 1 ] ) ; then
|
||||
elif [ "$cpu_flush_cmd" = 1 ] || { [ "$msr_locked_down" = 1 ] && [ "$cpuid_l1df" = 1 ]; } ; then
|
||||
pvulnstatus $cve OK "your CPU microcode mitigates the vulnerability"
|
||||
else
|
||||
pvulnstatus $cve VULN "your CPU supports SGX and the microcode is not up to date"
|
||||
@ -4377,48 +4476,7 @@ check_CVE_2018_3646_linux()
|
||||
fi
|
||||
l1d_mode=-1
|
||||
if [ "$opt_sysfs_only" != 1 ]; then
|
||||
_info_nol "* This system is a host running a hypervisor: "
|
||||
has_vmm=$opt_vmm
|
||||
if [ "$has_vmm" = -1 ] && [ "$opt_paranoid" = 1 ]; then
|
||||
# In paranoid mode, if --vmm was not specified on the command-line,
|
||||
# we want to be secure before everything else, so assume we're running
|
||||
# a hypervisor, as this requires more mitigations
|
||||
has_vmm=2
|
||||
elif [ "$has_vmm" = -1 ]; then
|
||||
# Here, we want to know if we are hosting a hypervisor, and running some VMs on it.
|
||||
# If we find no evidence that this is the case, assume we're not (to avoid scaring users),
|
||||
# this can always be overridden with --vmm in any case.
|
||||
has_vmm=0
|
||||
if command -v pgrep >/dev/null 2>&1; then
|
||||
# remove xenbus and xenwatch, also present inside domU
|
||||
# remove libvirtd as it can also be used to manage containers and not VMs
|
||||
if pgrep qemu >/dev/null || pgrep kvm >/dev/null || \
|
||||
pgrep xenstored >/dev/null || pgrep xenconsoled >/dev/null; then
|
||||
has_vmm=1
|
||||
fi
|
||||
else
|
||||
# ignore SC2009 as `ps ax` is actually used as a fallback if `pgrep` isn't installed
|
||||
# shellcheck disable=SC2009
|
||||
if ps ax | grep -vw grep | grep -q -e '\<qemu' -e '/qemu' -e '<\kvm' -e '/kvm' -e '/xenstored' -e '/xenconsoled'; then
|
||||
has_vmm=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "$has_vmm" = 0 ]; then
|
||||
if [ "$opt_vmm" != -1 ]; then
|
||||
pstatus green NO "forced from command line"
|
||||
else
|
||||
pstatus green NO
|
||||
fi
|
||||
else
|
||||
if [ "$opt_vmm" != -1 ]; then
|
||||
pstatus blue YES "forced from command line"
|
||||
elif [ "$has_vmm" = 2 ]; then
|
||||
pstatus blue YES "paranoid mode"
|
||||
else
|
||||
pstatus blue YES
|
||||
fi
|
||||
fi
|
||||
check_has_vmm
|
||||
|
||||
_info "* Mitigation 1 (KVM)"
|
||||
_info_nol " * EPT is disabled: "
|
||||
@ -4978,6 +5036,95 @@ check_CVE_2019_11135_linux()
|
||||
fi
|
||||
}
|
||||
|
||||
#######################
|
||||
# iTLB Multihit section
|
||||
|
||||
check_CVE_2018_12207()
|
||||
{
|
||||
cve='CVE-2018-12207'
|
||||
_info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m"
|
||||
if [ "$os" = Linux ]; then
|
||||
check_CVE_2018_12207_linux
|
||||
#elif echo "$os" | grep -q BSD; then
|
||||
# check_CVE_2018_12207_bsd
|
||||
else
|
||||
_warn "Unsupported OS ($os)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_CVE_2018_12207_linux()
|
||||
{
|
||||
status=UNK
|
||||
sys_interface_available=0
|
||||
msg=''
|
||||
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/itlb_multihit"; then
|
||||
# this kernel has the /sys interface, trust it over everything
|
||||
sys_interface_available=1
|
||||
fi
|
||||
if [ "$opt_sysfs_only" != 1 ]; then
|
||||
check_has_vmm
|
||||
|
||||
_info_nol "* iTLB Multihit mitigation is supported by kernel: "
|
||||
kernel_itlbmh=''
|
||||
if [ -n "$kernel_err" ]; then
|
||||
kernel_itlbmh_err="$kernel_err"
|
||||
# commit 5219505fcbb640e273a0d51c19c38de0100ec5a9
|
||||
elif grep -q 'itlb_multihit' "$kernel"; then
|
||||
kernel_itlbmh="found itlb_multihit in kernel image"
|
||||
fi
|
||||
if [ -n "$kernel_itlbmh" ]; then
|
||||
pstatus green YES "$kernel_itlbmh"
|
||||
elif [ -n "$kernel_itlbmh_err" ]; then
|
||||
pstatus yellow UNKNOWN "$kernel_itlbmh_err"
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
_info_nol "* iTLB Multihit mitigation enabled and active: "
|
||||
if [ "$opt_live" = 1 ]; then
|
||||
if [ -n "$fullmsg" ]; then
|
||||
if echo "$fullmsg" | grep -qF 'Mitigation'; then
|
||||
pstatus green YES "$fullmsg"
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
else
|
||||
pstatus yellow NO "itlb_multihit not found in sysfs hierarchy"
|
||||
fi
|
||||
else
|
||||
pstatus blue N/A "not testable in offline mode"
|
||||
fi
|
||||
elif [ "$sys_interface_available" = 0 ]; then
|
||||
# we have no sysfs but were asked to use it only!
|
||||
msg="/sys vulnerability interface use forced, but it's not available!"
|
||||
status=UNK
|
||||
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"
|
||||
elif [ "$has_vmm" = 0 ]; then
|
||||
pvulnstatus "$cve" OK "this system is not running a hypervisor"
|
||||
elif [ -z "$msg" ]; then
|
||||
# if msg is empty, sysfs check didn't fill it, rely on our own test
|
||||
if [ "$opt_live" = 1 ]; then
|
||||
# if we're in live mode and $msg is empty, sysfs file is not there so kernel is too old
|
||||
pvulnstatus $cve VULN "Your kernel doesn't support iTLB Multihit mitigation, update it"
|
||||
else
|
||||
if [ -n "$kernel_itlbmh" ]; then
|
||||
pvulnstatus $cve OK "Your kernel supports iTLB Multihit mitigation"
|
||||
else
|
||||
pvulnstatus $cve VULN "Your kernel doesn't support iTLB Multihit mitigation, update it"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
pvulnstatus $cve "$status" "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
#######################
|
||||
# END OF VULNS SECTIONS
|
||||
|
||||
if [ "$opt_no_hw" = 0 ] && [ -z "$opt_arch_prefix" ]; then
|
||||
check_cpu
|
||||
check_cpu_vulnerabilities
|
||||
|
Loading…
Reference in New Issue
Block a user