mirror of
				https://github.com/speed47/spectre-meltdown-checker.git
				synced 2025-10-31 12:40:57 +01:00 
			
		
		
		
	feat: add detection of iTLB Multihit vuln/mitigation (CVE-2018-12207)
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user