@ -163,7 +163,7 @@ global_critical=0
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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 = $(( 0 x0E )) #
INTEL_FAM6_CORE2_MEROM = $(( 0 x0F )) #
INTEL_FAM6_CORE2_MEROM_L = $(( 0 x16 )) #
INTEL_FAM6_CORE2_PENRYN = $(( 0 x17 )) #
INTEL_FAM6_CORE2_DUNNINGTON = $(( 0 x1D )) #
INTEL_FAM6_NEHALEM = $(( 0 x1E )) #
INTEL_FAM6_NEHALEM_G = $(( 0 x1F )) # /* Auburndale / Havendale */
INTEL_FAM6_NEHALEM_EP = $(( 0 x1A )) #
INTEL_FAM6_NEHALEM_EX = $(( 0 x2E )) #
INTEL_FAM6_WESTMERE = $(( 0 x25 )) #
INTEL_FAM6_WESTMERE_EP = $(( 0 x2C )) #
INTEL_FAM6_WESTMERE_EX = $(( 0 x2F )) #
INTEL_FAM6_SANDYBRIDGE = $(( 0 x2A )) #
INTEL_FAM6_SANDYBRIDGE_X = $(( 0 x2D )) #
INTEL_FAM6_IVYBRIDGE = $(( 0 x3A )) #
INTEL_FAM6_IVYBRIDGE_X = $(( 0 x3E )) #
INTEL_FAM6_HASWELL = $(( 0 x3C )) #
INTEL_FAM6_HASWELL_X = $(( 0 x3F )) #
INTEL_FAM6_HASWELL_L = $(( 0 x45 )) #
INTEL_FAM6_HASWELL_G = $(( 0 x46 )) #
INTEL_FAM6_BROADWELL = $(( 0 x3D )) #
INTEL_FAM6_BROADWELL_G = $(( 0 x47 )) #
INTEL_FAM6_BROADWELL_X = $(( 0 x4F )) #
INTEL_FAM6_BROADWELL_D = $(( 0 x56 )) #
INTEL_FAM6_SKYLAKE_L = $(( 0 x4E )) #
INTEL_FAM6_SKYLAKE = $(( 0 x5E )) #
INTEL_FAM6_SKYLAKE_X = $(( 0 x55 )) #
INTEL_FAM6_KABYLAKE_L = $(( 0 x8E )) #
INTEL_FAM6_KABYLAKE = $(( 0 x9E )) #
INTEL_FAM6_CANNONLAKE_L = $(( 0 x66 )) #
INTEL_FAM6_ICELAKE_X = $(( 0 x6A )) #
INTEL_FAM6_ICELAKE_D = $(( 0 x6C )) #
INTEL_FAM6_ICELAKE = $(( 0 x7D )) #
INTEL_FAM6_ICELAKE_L = $(( 0 x7E )) #
INTEL_FAM6_ICELAKE_NNPI = $(( 0 x9D )) #
INTEL_FAM6_TIGERLAKE_L = $(( 0 x8C )) #
INTEL_FAM6_TIGERLAKE = $(( 0 x8D )) #
INTEL_FAM6_COMETLAKE = $(( 0 xA5 )) #
INTEL_FAM6_COMETLAKE_L = $(( 0 xA6 )) #
INTEL_FAM6_ATOM_BONNELL = $(( 0 x1C )) # /* Diamondville, Pineview */
INTEL_FAM6_ATOM_BONNELL_MID = $(( 0 x26 )) # /* Silverthorne, Lincroft */
INTEL_FAM6_ATOM_SALTWELL = $(( 0 x36 )) # /* Cedarview */
INTEL_FAM6_ATOM_SALTWELL_MID = $(( 0 x27 )) # /* Penwell */
INTEL_FAM6_ATOM_SALTWELL_TABLET = $(( 0 x35 )) # /* Cloverview */
INTEL_FAM6_ATOM_SILVERMONT = $(( 0 x37 )) # /* Bay Trail, Valleyview */
INTEL_FAM6_ATOM_SILVERMONT_D = $(( 0 x4D )) # /* Avaton, Rangely */
INTEL_FAM6_ATOM_SILVERMONT_MID = $(( 0 x4A )) # /* Merriefield */
INTEL_FAM6_ATOM_AIRMONT = $(( 0 x4C )) # /* Cherry Trail, Braswell */
INTEL_FAM6_ATOM_AIRMONT_MID = $(( 0 x5A )) # /* Moorefield */
INTEL_FAM6_ATOM_AIRMONT_NP = $(( 0 x75 )) # /* Lightning Mountain */
INTEL_FAM6_ATOM_GOLDMONT = $(( 0 x5C )) # /* Apollo Lake */
INTEL_FAM6_ATOM_GOLDMONT_D = $(( 0 x5F )) # /* Denverton */
INTEL_FAM6_ATOM_GOLDMONT_PLUS = $(( 0 x7A )) # /* Gemini Lake */
INTEL_FAM6_ATOM_TREMONT_D = $(( 0 x86 )) # /* Jacobsville */
INTEL_FAM6_ATOM_TREMONT = $(( 0 x96 )) # /* Elkhart Lake */
INTEL_FAM6_XEON_PHI_KNL = $(( 0 x57 )) # /* Knights Landing */
INTEL_FAM6_XEON_PHI_KNM = $(( 0 x85 )) # /* Knights Mill */
INTEL_FAM6_CORE_YONAH = $(( 0 x0E ))
INTEL_FAM6_CORE2_MEROM = $(( 0 x0F ))
INTEL_FAM6_CORE2_MEROM_L = $(( 0 x16 ))
INTEL_FAM6_CORE2_PENRYN = $(( 0 x17 ))
INTEL_FAM6_CORE2_DUNNINGTON = $(( 0 x1D ))
INTEL_FAM6_NEHALEM = $(( 0 x1E ))
INTEL_FAM6_NEHALEM_G = $(( 0 x1F ))
INTEL_FAM6_NEHALEM_EP = $(( 0 x1A ))
INTEL_FAM6_NEHALEM_EX = $(( 0 x2E ))
INTEL_FAM6_WESTMERE = $(( 0 x25 ))
INTEL_FAM6_WESTMERE_EP = $(( 0 x2C ))
INTEL_FAM6_WESTMERE_EX = $(( 0 x2F ))
INTEL_FAM6_SANDYBRIDGE = $(( 0 x2A ))
INTEL_FAM6_SANDYBRIDGE_X = $(( 0 x2D ))
INTEL_FAM6_IVYBRIDGE = $(( 0 x3A ))
INTEL_FAM6_IVYBRIDGE_X = $(( 0 x3E ))
INTEL_FAM6_HASWELL_CORE = $(( 0 x3C ))
INTEL_FAM6_HASWELL_X = $(( 0 x3F ))
INTEL_FAM6_HASWELL_ULT = $(( 0 x45 ))
INTEL_FAM6_HASWELL_GT3E = $(( 0 x46 ))
INTEL_FAM6_BROADWELL_CORE = $(( 0 x3D ))
INTEL_FAM6_BROADWELL_GT3E = $(( 0 x47 ))
INTEL_FAM6_BROADWELL_X = $(( 0 x4F ))
INTEL_FAM6_BROADWELL_XEON_D = $(( 0 x56 ))
INTEL_FAM6_SKYLAKE_MOBILE = $(( 0 x4E ))
INTEL_FAM6_SKYLAKE_DESKTOP = $(( 0 x5E ))
INTEL_FAM6_SKYLAKE_X = $(( 0 x55 ))
INTEL_FAM6_KABYLAKE_MOBILE = $(( 0 x8E ))
INTEL_FAM6_KABYLAKE_DESKTOP = $(( 0 x9E ))
# /* "Small Core" Processors (Atom) */
INTEL_FAM6_ATOM_BONNELL = $(( 0 x1C ))
INTEL_FAM6_ATOM_BONNELL_MID = $(( 0 x26 ))
INTEL_FAM6_ATOM_SALTWELL_MID = $(( 0 x27 ))
INTEL_FAM6_ATOM_SALTWELL_TABLET = $(( 0 x35 ))
INTEL_FAM6_ATOM_SALTWELL = $(( 0 x36 ))
INTEL_FAM6_ATOM_SILVERMONT = $(( 0 x37 ))
INTEL_FAM6_ATOM_SILVERMONT_MID = $(( 0 x4A ))
INTEL_FAM6_ATOM_SILVERMONT_X = $(( 0 x4D ))
INTEL_FAM6_ATOM_AIRMONT = $(( 0 x4C ))
INTEL_FAM6_ATOM_AIRMONT_MID = $(( 0 x5A ))
INTEL_FAM6_ATOM_GOLDMONT = $(( 0 x5C ))
INTEL_FAM6_ATOM_GOLDMONT_X = $(( 0 x5F ))
INTEL_FAM6_ATOM_GOLDMONT_PLUS = $(( 0 x7A ))
# /* Xeon Phi */
INTEL_FAM6_XEON_PHI_KNL = $(( 0 x57 ))
INTEL_FAM6_XEON_PHI_KNM = $(( 0 x85 ))
}
parse_cpu_details_done = 1
}
@ -1639,7 +1679,7 @@ is_ucode_blacklisted()
@@ -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_U LT ,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()
@@ -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()
@@ -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_MOBI LE ] || \
[ " $cpu_model " = $INTEL_FAM6_SKYLAKE_DESKTOP ] || \
[ " $cpu_model " = $INTEL_FAM6_SKYLAKE_X ] || \
[ " $cpu_model " = $INTEL_FAM6_KABYLAKE_MOBI LE ] || \
[ " $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()
@@ -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 -qE i '^(kvm: )? mitigation' ; then
# Mitigation: PTI
status = OK
pstatus green YES " $fullmsg "
@ -2709,6 +2749,7 @@ check_cpu()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -2827,7 +2871,7 @@ check_cpu()
pstatus yellow NO
fi
_info_nol " * CPU explicitly indicates not being vulnerable to TSX Asynchrn onous 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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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()
@@ -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