14 Commits
v0.41 ... v0.42

Author SHA1 Message Date
fcc4ff4de2 update MCEdb from v110 to v111, bump to v0.42 2019-05-24 22:49:45 +02:00
0bd38ddda0 enh: -v -v now implies --dump-mock-data 2019-05-24 11:36:39 +02:00
e83dc818cd feat(mds): implement FreeBSD mitigation detection 2019-05-24 11:17:04 +02:00
d69ea67101 feat(mock): add --dump-mock-data 2019-05-24 10:49:40 +02:00
dfe0d10f2a fix(mds): remove useless display of MD_CLEAR info in non-hw section 2019-05-24 10:20:48 +02:00
58a5acfdbb fix(bsd): read_msr returned data in an incorrect format 2019-05-24 09:33:56 +02:00
ccb4dbef7c enh(mock): avoid reading the sysfs interface outside sys_interface_check() for higher mocking coverage 2019-05-24 09:28:18 +02:00
afbb26277f feat(mock): add mocking functionality to help reproducing issues under specific CPUs 2019-05-24 09:28:18 +02:00
77b34d48c6 fix(mds): check MDS_NO bit in is_cpu_mds_free() 2019-05-24 09:28:18 +02:00
497efe6a82 fix(l1tf): RDCL_NO bit didn't take precedence for vulnerability check on some Intel CPUs 2019-05-24 09:28:18 +02:00
62b46df4e7 fix(l1tf): remove libvirtd from hypervisor detection (#278) 2019-05-18 14:22:42 +02:00
7d1f269bed fix(mds): AMD confirms they're not vulnerable 2019-05-16 11:31:28 +02:00
4f9ca803c8 Fix help text (#285)
* fix --help message

Commit 7b72c20f89 added help text for the
--cve switch, and the "can be specified multiple times" note got
associated with the --cve switch instead of staying with the --variant
switch.  Restore the line to belong to the --variant switch help
message.

* Add new variants to error message

Commit 8e870db4f5 added new variants but
did not add them to the error message that listed the allowable
variants.  Add them now.
2019-05-15 19:34:51 +02:00
5788cec18b fix(mds): ARM and CAVIUM are not thought to be vulnerable 2019-05-15 10:56:49 +02:00
2 changed files with 357 additions and 109 deletions

View File

@ -143,7 +143,7 @@ docker run --rm --privileged -v /boot:/boot:ro -v /dev/cpu:/dev/cpu:ro -v /lib/m
- Note: These 4 CVEs are similar and collectively named "MDS" vulnerabilities, the mitigation is identical for all - Note: These 4 CVEs are similar and collectively named "MDS" vulnerabilities, the mitigation is identical for all
- Impact: Kernel - Impact: Kernel
- Mitigation: microcode update + kernel update making possible to protect various CPU internal buffers from unprivileged speculative access to data - Mitigation: microcode update + kernel update making possible to protect various CPU internal buffers from unprivileged speculative access to data
- Performance impact of the mitigation: TBC - Performance impact of the mitigation: low to significant
## Understanding what this script does and doesn't ## Understanding what this script does and doesn't

View File

@ -11,7 +11,7 @@
# #
# Stephane Lesimple # Stephane Lesimple
# #
VERSION='0.41' VERSION='0.42'
trap 'exit_cleanup' EXIT trap 'exit_cleanup' EXIT
trap '_warn "interrupted, cleaning up..."; exit_cleanup; exit 1' INT trap '_warn "interrupted, cleaning up..."; exit_cleanup; exit 1' INT
@ -79,13 +79,14 @@ show_usage()
--variant VARIANT specify which variant you'd like to check, by default all variants are checked --variant VARIANT specify which variant you'd like to check, by default all variants are checked
VARIANT can be one of 1, 2, 3, 3a, 4, l1tf, msbds, mfbds, mlpds, mdsum VARIANT can be one of 1, 2, 3, 3a, 4, l1tf, msbds, mfbds, mlpds, mdsum
--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) can be specified multiple times (e.g. --variant 2 --variant 3)
--cve [cve1,cve2,...] specify which CVE you'd like to check, by default all supported CVEs are checked
--hw-only only check for CPU information, don't check for any variant --hw-only only check for CPU information, don't check for any variant
--no-hw skip CPU information and checks, if you're inspecting a kernel not to be run on this host --no-hw skip CPU information and checks, if you're inspecting a kernel not to be run on this host
--vmm [auto,yes,no] override the detection of the presence of a hypervisor (for CVE-2018-3646), default: auto --vmm [auto,yes,no] override the detection of the presence of a hypervisor (for CVE-2018-3646), default: auto
--update-mcedb update our local copy of the CPU microcodes versions database (from the awesome MCExtractor project) --update-mcedb update our local copy of the CPU microcodes versions database (from the awesome MCExtractor project)
--update-builtin-mcedb same as --update-mcedb but update builtin DB inside the script itself --update-builtin-mcedb same as --update-mcedb but update builtin DB inside the script itself
--dump-mock-data used to mimick a CPU on an other system, mainly used to help debugging this script
Return codes: Return codes:
0 (not vulnerable), 2 (vulnerable), 3 (unknown), 255 (error) 0 (not vulnerable), 2 (vulnerable), 3 (unknown), 255 (error)
@ -150,6 +151,7 @@ opt_no_hw=0
opt_vmm=-1 opt_vmm=-1
opt_explain=0 opt_explain=0
opt_paranoid=0 opt_paranoid=0
opt_mock=0
global_critical=0 global_critical=0
global_unknown=0 global_unknown=0
@ -325,6 +327,14 @@ is_cpu_vulnerable()
variant_mlpds='' variant_mlpds=''
variant_mdsum='' variant_mdsum=''
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
if is_cpu_specex_free; then if is_cpu_specex_free; then
variant1=immune variant1=immune
variant2=immune variant2=immune
@ -365,13 +375,6 @@ is_cpu_vulnerable()
[ -z "$variant4" ] && variant4=immune [ -z "$variant4" ] && variant4=immune
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4" _debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
fi 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 # variant 4a for xeon phi
if [ "$cpu_family" = 6 ]; then if [ "$cpu_family" = 6 ]; then
if [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ]; then if [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || [ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ]; then
@ -401,7 +404,7 @@ is_cpu_vulnerable()
[ -z "$variantl1tf" ] && variantl1tf=immune [ -z "$variantl1tf" ] && variantl1tf=immune
else else
_debug "is_cpu_vulnerable: intel family 6 is vuln" _debug "is_cpu_vulnerable: intel family 6 is vuln"
variantl1tf=vuln [ -z "$variantl1tf" ] && variantl1tf=vuln
fi fi
elif [ "$cpu_family" -lt 6 ]; then elif [ "$cpu_family" -lt 6 ]; then
_debug "is_cpu_vulnerable: intel family < 6 is immune" _debug "is_cpu_vulnerable: intel family < 6 is immune"
@ -420,13 +423,6 @@ is_cpu_vulnerable()
[ -z "$variant4" ] && variant4=immune [ -z "$variant4" ] && variant4=immune
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4" _debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
fi 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 variantl1tf=immune
elif [ "$cpu_vendor" = CAVIUM ]; then elif [ "$cpu_vendor" = CAVIUM ]; then
variant3=immune variant3=immune
@ -601,22 +597,23 @@ is_cpu_mds_free()
return 0 return 0
fi fi
fi fi
[ "$capabilities_mds_no" = 1 ] && return 0
fi fi
# official statement from AMD says none of their CPUs are vulnerable
# https://www.amd.com/en/corporate/product-security
# https://www.amd.com/system/files/documents/security-whitepaper.pdf
if is_amd; then if is_amd; then
if [ "$cpu_family" = "18" ] || \
[ "$cpu_family" = "17" ] || \
[ "$cpu_family" = "16" ] || \
[ "$cpu_family" = "15" ]; then
return 0 return 0
fi elif is_hygon; then
fi return 0
if is_hygon; then elif [ "$cpu_vendor" = CAVIUM ]; then
return 0
elif [ "$cpu_vendor" = ARM ]; then
return 0 return 0
fi fi
return 1 return 1
} }
is_cpu_ssb_free() is_cpu_ssb_free()
@ -821,6 +818,9 @@ while [ -n "$1" ]; do
elif [ "$1" = "--update-builtin-mcedb" ]; then elif [ "$1" = "--update-builtin-mcedb" ]; then
update_mcedb builtin update_mcedb builtin
exit $? exit $?
elif [ "$1" = "--dump-mock-data" ]; then
opt_mock=1
shift
elif [ "$1" = "--explain" ]; then elif [ "$1" = "--explain" ]; then
opt_explain=1 opt_explain=1
shift shift
@ -841,6 +841,7 @@ while [ -n "$1" ]; do
esac esac
elif [ "$1" = "-v" ] || [ "$1" = "--verbose" ]; then elif [ "$1" = "-v" ] || [ "$1" = "--verbose" ]; then
opt_verbose=$(( opt_verbose + 1 )) opt_verbose=$(( opt_verbose + 1 ))
[ "$opt_verbose" -ge 2 ] && opt_mock=1
shift shift
elif [ "$1" = "--cve" ]; then elif [ "$1" = "--cve" ]; then
if [ -z "$2" ]; then if [ -z "$2" ]; then
@ -885,7 +886,7 @@ while [ -n "$1" ]; do
mdsum) opt_cve_list="$opt_cve_list CVE-2019-11091"; 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;; 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; echo "$0: error: invalid parameter '$2' for --variant, expected either 1, 2, 3, 3a, 4, msbds, mfbds, mlpds, mdsum, or l1tf" >&2;
exit 255 exit 255
;; ;;
esac esac
@ -1216,6 +1217,14 @@ read_cpuid()
fi fi
_debug "cpuid: leaf$_leaf on cpu0, eax-ebx-ecx-edx: $_cpuid" _debug "cpuid: leaf$_leaf on cpu0, eax-ebx-ecx-edx: $_cpuid"
_mockvarname="SMC_MOCK_CPUID_${_leaf}"
if [ -n "$(eval echo \$$_mockvarname)" ]; then
_cpuid="$(eval echo \$$_mockvarname)"
_debug "read_cpuid: MOCKING enabled for leaf $_leaf, will return $_cpuid"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPUID_${_leaf}='$_cpuid'")
fi
[ -z "$_cpuid" ] && return 2 [ -z "$_cpuid" ] && return 2
# get the value of the register we want # get the value of the register we want
_reg=$(echo "$_cpuid" | awk '{print $'"$_register"'}') _reg=$(echo "$_cpuid" | awk '{print $'"$_register"'}')
@ -1299,6 +1308,42 @@ parse_cpu_details()
cpu_friendly_name=$(sysctl -n hw.model) cpu_friendly_name=$(sysctl -n hw.model)
fi fi
if [ -n "$SMC_MOCK_CPU_FRIENDLY_NAME" ]; then
cpu_friendly_name="$SMC_MOCK_CPU_FRIENDLY_NAME"
_debug "parse_cpu_details: MOCKING cpu friendly name to $cpu_friendly_name"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_FRIENDLY_NAME='$cpu_friendly_name'")
fi
if [ -n "$SMC_MOCK_CPU_VENDOR" ]; then
cpu_vendor="$SMC_MOCK_CPU_VENDOR"
_debug "parse_cpu_details: MOCKING cpu vendor to $cpu_vendor"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_VENDOR='$cpu_vendor'")
fi
if [ -n "$SMC_MOCK_CPU_FAMILY" ]; then
cpu_family="$SMC_MOCK_CPU_FAMILY"
_debug "parse_cpu_details: MOCKING cpu family to $cpu_family"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_FAMILY='$cpu_family'")
fi
if [ -n "$SMC_MOCK_CPU_MODEL" ]; then
cpu_model="$SMC_MOCK_CPU_MODEL"
_debug "parse_cpu_details: MOCKING cpu model to $cpu_model"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_MODEL='$cpu_model'")
fi
if [ -n "$SMC_MOCK_CPU_STEPPING" ]; then
cpu_stepping="$SMC_MOCK_CPU_STEPPING"
_debug "parse_cpu_details: MOCKING cpu stepping to $cpu_stepping"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_STEPPING='$cpu_stepping'")
fi
# get raw cpuid, it's always useful (referenced in the Intel doc for firmware updates for example) # get raw cpuid, it's always useful (referenced in the Intel doc for firmware updates for example)
if read_cpuid 0x1 $EAX 0 0xFFFFFFFF; then if read_cpuid 0x1 $EAX 0 0xFFFFFFFF; then
cpu_cpuid="$read_cpuid_value" cpu_cpuid="$read_cpuid_value"
@ -1326,6 +1371,14 @@ parse_cpu_details()
# if we got no cpu_ucode (e.g. we're in a vm), fall back to 0x0 # if we got no cpu_ucode (e.g. we're in a vm), fall back to 0x0
[ -z "$cpu_ucode" ] && cpu_ucode=0x0 [ -z "$cpu_ucode" ] && cpu_ucode=0x0
if [ -n "$SMC_MOCK_CPU_UCODE" ]; then
cpu_ucode="$SMC_MOCK_CPU_UCODE"
_debug "parse_cpu_details: MOCKING cpu ucode to $cpu_ucode"
mocked=1
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPU_UCODE='$cpu_ucode'")
fi
echo "$cpu_ucode" | grep -q ^0x && cpu_ucode=$(( cpu_ucode )) echo "$cpu_ucode" | grep -q ^0x && cpu_ucode=$(( cpu_ucode ))
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") 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")
@ -1877,12 +1930,41 @@ sys_interface_check()
file="$1" file="$1"
regex="$2" regex="$2"
mode="$3" mode="$3"
[ "$opt_live" = 1 ] && [ "$opt_no_sysfs" = 0 ] && [ -r "$file" ] || return 1 msg=''
fullmsg=''
if [ "$opt_live" = 1 ] && [ "$opt_no_sysfs" = 0 ] && [ -r "$file" ]; then
:
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_SYSFS_$(basename "$file")_RET=1")
return 1
fi
_mockvarname="SMC_MOCK_SYSFS_$(basename "$file")_RET"
# shellcheck disable=SC2086
if [ -n "$(eval echo \$$_mockvarname)" ]; then
_debug "sysfs: MOCKING enabled for $file func returns $(eval echo \$$_mockvarname)"
mocked=1
return "$(eval echo \$$_mockvarname)"
fi
[ -n "$regex" ] || regex='.*' [ -n "$regex" ] || regex='.*'
_mockvarname="SMC_MOCK_SYSFS_$(basename "$file")"
# shellcheck disable=SC2086
if [ -n "$(eval echo \$$_mockvarname)" ]; then
fullmsg="$(eval echo \$$_mockvarname)"
msg=$(echo "$fullmsg" | grep -Eo "$regex")
_debug "sysfs: MOCKING enabled for $file, will return $fullmsg"
mocked=1
else
fullmsg=$(cat "$file") fullmsg=$(cat "$file")
msg=$(grep -Eo "$regex" "$file") msg=$(grep -Eo "$regex" "$file")
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_SYSFS_$(basename "$file")='$fullmsg'")
fi
if [ "$mode" = silent ]; then if [ "$mode" = silent ]; then
_info "* Information from the /sys interface: $msg" return 0
elif [ "$mode" = quiet ]; then
_info "* Information from the /sys interface: $fullmsg"
return 0 return 0
fi fi
_info_nol "* Mitigated according to the /sys interface: " _info_nol "* Mitigated according to the /sys interface: "
@ -1919,90 +2001,128 @@ number_of_cpus()
return "$n" return "$n"
} }
# $1 - msr number # write_msr
# $2 - cpu index # param1 (mandatory): MSR, can be in hex or decimal.
# param2 (optional): CPU index, starting from 0. Default 0.
write_msr() write_msr()
{ {
# _msr must be in hex, in the form 0x1234: _msr_dec=$(( $1 ))
_msr="$1" _msr=$(printf "0x%x" "$_msr_dec")
# cpu index, starting from 0:
_cpu="$2" _cpu="$2"
[ -z "$_cpu" ] && _cpu=0
_mockvarname="SMC_MOCK_WRMSR_${_msr}_RET"
# shellcheck disable=SC2086
if [ -n "$(eval echo \$$_mockvarname)" ]; then
_debug "write_msr: MOCKING enabled for msr $_msr func returns $(eval echo \$$_mockvarname)"
mocked=1
return "$(eval echo \$$_mockvarname)"
fi
if [ "$os" != Linux ]; then if [ "$os" != Linux ]; then
cpucontrol -m "$_msr=0" "/dev/cpuctl$_cpu" >/dev/null 2>&1; ret=$? cpucontrol -m "$_msr=0" "/dev/cpuctl$_cpu" >/dev/null 2>&1; ret=$?
else else
# for Linux # for Linux
# convert to decimal # convert to decimal
_msr=$(( _msr ))
if [ ! -w /dev/cpu/"$_cpu"/msr ]; then if [ ! -w /dev/cpu/"$_cpu"/msr ]; then
ret=200 # permission error ret=200 # permission error
# if wrmsr is available, use it # if wrmsr is available, use it
elif command -v wrmsr >/dev/null 2>&1 && [ "$SMC_NO_WRMSR" != 1 ]; then elif command -v wrmsr >/dev/null 2>&1 && [ "$SMC_NO_WRMSR" != 1 ]; then
_debug "write_msr: using wrmsr" _debug "write_msr: using wrmsr"
wrmsr $_msr 0 2>/dev/null; ret=$? wrmsr $_msr_dec 0 2>/dev/null; ret=$?
# or if we have perl, use it, any 5.x version will work # or if we have perl, use it, any 5.x version will work
elif command -v perl >/dev/null 2>&1 && [ "$SMC_NO_PERL" != 1 ]; then elif command -v perl >/dev/null 2>&1 && [ "$SMC_NO_PERL" != 1 ]; then
_debug "write_msr: using perl" _debug "write_msr: using perl"
ret=1 ret=1
perl -e "open(M,'>','/dev/cpu/$_cpu/msr') and seek(M,$_msr,0) and exit(syswrite(M,pack('H16',0)))"; [ $? -eq 8 ] && ret=0 perl -e "open(M,'>','/dev/cpu/$_cpu/msr') and seek(M,$_msr_dec,0) and exit(syswrite(M,pack('H16',0)))"; [ $? -eq 8 ] && ret=0
# fallback to dd if it supports seek_bytes # fallback to dd if it supports seek_bytes
elif dd if=/dev/null of=/dev/null bs=8 count=1 seek="$_msr" oflag=seek_bytes 2>/dev/null; then elif dd if=/dev/null of=/dev/null bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>/dev/null; then
_debug "write_msr: using dd" _debug "write_msr: using dd"
dd if=/dev/zero of=/dev/cpu/"$_cpu"/msr bs=8 count=1 seek="$_msr" oflag=seek_bytes 2>/dev/null; ret=$? dd if=/dev/zero of=/dev/cpu/"$_cpu"/msr bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>/dev/null; ret=$?
else else
_debug "write_msr: got no wrmsr, perl or recent enough dd!" _debug "write_msr: got no wrmsr, perl or recent enough dd!"
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_WRMSR_${_msr}_RET=201")
return 201 # missing tool error return 201 # missing tool error
fi fi
fi fi
# normalize ret # normalize ret
[ "$ret" != 0 ] && ret=1 [ "$ret" != 0 ] && ret=1
_debug "write_msr: for cpu $_cpu on msr $_msr, ret=$ret" _debug "write_msr: for cpu $_cpu on msr $_msr, ret=$ret"
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_WRMSR_${_msr}_RET=$ret")
return $ret return $ret
} }
# read_msr
# param1 (mandatory): MSR, can be in hex or decimal.
# param2 (optional): CPU index, starting from 0. Default 0.
read_msr() read_msr()
{ {
# _msr must be in hex, in the form 0x1234: _msr_dec=$(( $1 ))
_msr="$1" _msr=$(printf "0x%x" "$_msr_dec")
# cpu index, starting from 0:
_cpu="$2" _cpu="$2"
[ -z "$_cpu" ] && _cpu=0
read_msr_value='' read_msr_value=''
_mockvarname="SMC_MOCK_RDMSR_${_msr}"
# shellcheck disable=SC2086
if [ -n "$(eval echo \$$_mockvarname)" ]; then
read_msr_value="$(eval echo \$$_mockvarname)"
_debug "read_msr: MOCKING enabled for msr $_msr, returning $read_msr_value"
mocked=1
return 0
else
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_RDMSR_${_msr}='$read_msr_value'")
fi
_mockvarname="SMC_MOCK_RDMSR_${_msr}_RET"
# shellcheck disable=SC2086
if [ -n "$(eval echo \$$_mockvarname)" ] && [ "$(eval echo \$$_mockvarname)" -ne 0 ]; then
_debug "read_msr: MOCKING enabled for msr $_msr func returns $(eval echo \$$_mockvarname)"
mocked=1
return "$(eval echo \$$_mockvarname)"
fi
if [ "$os" != Linux ]; then if [ "$os" != Linux ]; then
# for BSD
_msr=$(cpucontrol -m "$_msr" "/dev/cpuctl$_cpu" 2>/dev/null); ret=$? _msr=$(cpucontrol -m "$_msr" "/dev/cpuctl$_cpu" 2>/dev/null); ret=$?
[ $ret -ne 0 ] && return 1 if [ $ret -ne 0 ]; then
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_RDMSR_${_msr}_RET=1")
return 1
fi
# MSR 0x10: 0x000003e1 0xb106dded # MSR 0x10: 0x000003e1 0xb106dded
_msr_h=$(echo "$_msr" | awk '{print $3}'); _msr_h=$(echo "$_msr" | awk '{print $3}');
_msr_h="$(( _msr_h >> 24 & 0xFF )) $(( _msr_h >> 16 & 0xFF )) $(( _msr_h >> 8 & 0xFF )) $(( _msr_h & 0xFF ))"
_msr_l=$(echo "$_msr" | awk '{print $4}'); _msr_l=$(echo "$_msr" | awk '{print $4}');
_msr_l="$(( _msr_l >> 24 & 0xFF )) $(( _msr_l >> 16 & 0xFF )) $(( _msr_l >> 8 & 0xFF )) $(( _msr_l & 0xFF ))" read_msr_value=$(( _msr_h << 32 | _msr_l ))
read_msr_value="$_msr_h $_msr_l"
else else
# for Linux # for Linux
# convert to decimal
_msr=$(( _msr ))
if [ ! -r /dev/cpu/"$_cpu"/msr ]; then if [ ! -r /dev/cpu/"$_cpu"/msr ]; then
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_RDMSR_${_msr}_RET=200")
return 200 # permission error return 200 # permission error
# if rdmsr is available, use it # if rdmsr is available, use it
elif command -v rdmsr >/dev/null 2>&1 && [ "$SMC_NO_RDMSR" != 1 ]; then elif command -v rdmsr >/dev/null 2>&1 && [ "$SMC_NO_RDMSR" != 1 ]; then
_debug "read_msr: using rdmsr" _debug "read_msr: using rdmsr"
read_msr_value=$(rdmsr -r $_msr 2>/dev/null | od -t u8 -A n) read_msr_value=$(rdmsr -r $_msr_dec 2>/dev/null | od -t u8 -A n)
# or if we have perl, use it, any 5.x version will work # or if we have perl, use it, any 5.x version will work
elif command -v perl >/dev/null 2>&1 && [ "$SMC_NO_PERL" != 1 ]; then elif command -v perl >/dev/null 2>&1 && [ "$SMC_NO_PERL" != 1 ]; then
_debug "read_msr: using perl" _debug "read_msr: using perl"
read_msr_value=$(perl -e "open(M,'<','/dev/cpu/$_cpu/msr') and seek(M,$_msr,0) and read(M,\$_,8) and print" | od -t u8 -A n) read_msr_value=$(perl -e "open(M,'<','/dev/cpu/$_cpu/msr') and seek(M,$_msr_dec,0) and read(M,\$_,8) and print" | od -t u8 -A n)
# fallback to dd if it supports skip_bytes # fallback to dd if it supports skip_bytes
elif dd if=/dev/null of=/dev/null bs=8 count=1 skip="$_msr" iflag=skip_bytes 2>/dev/null; then elif dd if=/dev/null of=/dev/null bs=8 count=1 skip="$_msr_dec" iflag=skip_bytes 2>/dev/null; then
_debug "read_msr: using dd" _debug "read_msr: using dd"
read_msr_value=$(dd if=/dev/cpu/"$_cpu"/msr bs=8 count=1 skip="$_msr" iflag=skip_bytes 2>/dev/null | od -t u8 -A n) read_msr_value=$(dd if=/dev/cpu/"$_cpu"/msr bs=8 count=1 skip="$_msr_dec" iflag=skip_bytes 2>/dev/null | od -t u8 -A n)
else else
_debug "read_msr: got no rdmsr, perl or recent enough dd!" _debug "read_msr: got no rdmsr, perl or recent enough dd!"
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_RDMSR_${_msr}_RET=201")
return 201 # missing tool error return 201 # missing tool error
fi fi
if [ -z "$read_msr_value" ]; then if [ -z "$read_msr_value" ]; then
# MSR doesn't exist, don't check for $? because some versions of dd still return 0! # MSR doesn't exist, don't check for $? because some versions of dd still return 0!
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_RDMSR_${_msr}_RET=1")
return 1 return 1
fi fi
fi fi
_debug "read_msr: MSR=$1 value is $read_msr_value" _debug "read_msr: MSR=$_msr value is $read_msr_value"
return 0 return 0
} }
@ -2447,7 +2567,7 @@ check_cpu()
fi fi
fi fi
_info_nol " * CPU explicitly indicates not being vulnerable to Meltdown (RDCL_NO): " _info_nol " * CPU explicitly indicates not being vulnerable to Meltdown/L1TF (RDCL_NO): "
if [ "$capabilities_rdcl_no" = -1 ]; then if [ "$capabilities_rdcl_no" = -1 ]; then
pstatus yellow UNKNOWN pstatus yellow UNKNOWN
elif [ "$capabilities_rdcl_no" = 1 ]; then elif [ "$capabilities_rdcl_no" = 1 ]; then
@ -2483,7 +2603,7 @@ check_cpu()
pstatus blue NO pstatus blue NO
fi fi
_info_nol " * CPU explicitly indicates not being vulnerable to Microarchitectural Data Sampling (MDC_NO): " _info_nol " * CPU explicitly indicates not being vulnerable to Microarchitectural Data Sampling (MDS_NO): "
if [ "$capabilities_mds_no" = -1 ]; then if [ "$capabilities_mds_no" = -1 ]; then
pstatus yellow UNKNOWN pstatus yellow UNKNOWN
elif [ "$capabilities_mds_no" = 1 ]; then elif [ "$capabilities_mds_no" = 1 ]; then
@ -2865,21 +2985,21 @@ check_CVE_2017_5715_linux()
# XXX and what about ibpb ? # XXX and what about ibpb ?
fi fi
fi fi
if [ -e "/sys/devices/system/cpu/vulnerabilities/spectre_v2" ]; then if [ -n "$fullmsg" ]; then
# when IBPB is enabled on 4.15+, we can see it in sysfs # when IBPB is enabled on 4.15+, we can see it in sysfs
if grep -q 'IBPB' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then if echo "$fullmsg" | grep -q 'IBPB'; then
_debug "ibpb: found enabled in sysfs" _debug "ibpb: found enabled in sysfs"
[ -z "$ibpb_supported" ] && ibpb_supported='IBPB found enabled in sysfs' [ -z "$ibpb_supported" ] && ibpb_supported='IBPB found enabled in sysfs'
[ -z "$ibpb_enabled" ] && ibpb_enabled=1 [ -z "$ibpb_enabled" ] && ibpb_enabled=1
fi fi
# when IBRS_FW is enabled on 4.15+, we can see it in sysfs # when IBRS_FW is enabled on 4.15+, we can see it in sysfs
if grep -q ', IBRS_FW' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then if echo "$fullmsg" | grep -q ', IBRS_FW'; then
_debug "ibrs: found IBRS_FW in sysfs" _debug "ibrs: found IBRS_FW in sysfs"
[ -z "$ibrs_supported" ] && ibrs_supported='found IBRS_FW in sysfs' [ -z "$ibrs_supported" ] && ibrs_supported='found IBRS_FW in sysfs'
ibrs_fw_enabled=1 ibrs_fw_enabled=1
fi fi
# when IBRS is enabled on 4.15+, we can see it in sysfs # when IBRS is enabled on 4.15+, we can see it in sysfs
if grep -q -e '\<IBRS\>' -e 'Indirect Branch Restricted Speculation' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then if echo "$fullmsg" | grep -q -e '\<IBRS\>' -e 'Indirect Branch Restricted Speculation'; then
_debug "ibrs: found IBRS in sysfs" _debug "ibrs: found IBRS in sysfs"
[ -z "$ibrs_supported" ] && ibrs_supported='found IBRS in sysfs' [ -z "$ibrs_supported" ] && ibrs_supported='found IBRS in sysfs'
[ -z "$ibrs_enabled" ] && ibrs_enabled=3 [ -z "$ibrs_enabled" ] && ibrs_enabled=3
@ -3064,9 +3184,9 @@ check_CVE_2017_5715_linux()
# #
# if there is "retpoline" in the file and NOT "minimal", then it's full retpoline # if there is "retpoline" in the file and NOT "minimal", then it's full retpoline
# (works for vanilla and Red Hat variants) # (works for vanilla and Red Hat variants)
if [ "$opt_live" = 1 ] && [ -e "/sys/devices/system/cpu/vulnerabilities/spectre_v2" ]; then if [ "$opt_live" = 1 ] && [ -n "$fullmsg" ]; then
if grep -qwi retpoline /sys/devices/system/cpu/vulnerabilities/spectre_v2; then if echo "$fullmsg" | grep -qwi retpoline; then
if grep -qwi minimal /sys/devices/system/cpu/vulnerabilities/spectre_v2; then if echo "$fullmsg" | grep -qwi minimal; then
retpoline_compiler=0 retpoline_compiler=0
retpoline_compiler_reason="kernel reports minimal retpoline compilation" retpoline_compiler_reason="kernel reports minimal retpoline compilation"
else else
@ -3887,7 +4007,7 @@ check_CVE_2018_3620_linux()
status=UNK status=UNK
sys_interface_available=0 sys_interface_available=0
msg='' msg=''
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/l1tf" '^[^;]+'; then if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/l1tf"; then
# this kernel has the /sys interface, trust it over everything # this kernel has the /sys interface, trust it over everything
sys_interface_available=1 sys_interface_available=1
fi fi
@ -3908,8 +4028,8 @@ check_CVE_2018_3620_linux()
_info_nol "* PTE inversion enabled and active: " _info_nol "* PTE inversion enabled and active: "
if [ "$opt_live" = 1 ]; then if [ "$opt_live" = 1 ]; then
if [ "$sys_interface_available" = 1 ]; then if [ -n "$fullmsg" ]; then
if grep -q 'Mitigation: PTE Inversion' /sys/devices/system/cpu/vulnerabilities/l1tf; then if echo "$fullmsg" | grep -q 'Mitigation: PTE Inversion'; then
pstatus green YES pstatus green YES
pteinv_active=1 pteinv_active=1
else else
@ -3999,7 +4119,7 @@ check_CVE_2018_3646_linux()
status=UNK status=UNK
sys_interface_available=0 sys_interface_available=0
msg='' msg=''
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/l1tf" 'VMX:.*' silent; then if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/l1tf" '.*' quiet; then
# this kernel has the /sys interface, trust it over everything # this kernel has the /sys interface, trust it over everything
sys_interface_available=1 sys_interface_available=1
fi fi
@ -4019,14 +4139,15 @@ check_CVE_2018_3646_linux()
has_vmm=0 has_vmm=0
if command -v pgrep >/dev/null 2>&1; then if command -v pgrep >/dev/null 2>&1; then
# remove xenbus and xenwatch, also present inside domU # remove xenbus and xenwatch, also present inside domU
if pgrep qemu >/dev/null || pgrep kvm >/dev/null || pgrep libvirtd >/dev/null || \ # 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 pgrep xenstored >/dev/null || pgrep xenconsoled >/dev/null; then
has_vmm=1 has_vmm=1
fi fi
else else
# ignore SC2009 as `ps ax` is actually used as a fallback if `pgrep` isn't installed # ignore SC2009 as `ps ax` is actually used as a fallback if `pgrep` isn't installed
# shellcheck disable=SC2009 # shellcheck disable=SC2009
if ps ax | grep -vw grep | grep -q -e '\<qemu' -e '/qemu' -e '<\kvm' -e '/kvm' -e '/libvirtd' -e '/xenstored' -e '/xenconsoled'; then if ps ax | grep -vw grep | grep -q -e '\<qemu' -e '/qemu' -e '<\kvm' -e '/kvm' -e '/xenstored' -e '/xenconsoled'; then
has_vmm=1 has_vmm=1
fi fi
fi fi
@ -4087,18 +4208,19 @@ check_CVE_2018_3646_linux()
_info_nol " * L1D flush enabled: " _info_nol " * L1D flush enabled: "
if [ "$opt_live" = 1 ]; then if [ "$opt_live" = 1 ]; then
if [ -r "/sys/devices/system/cpu/vulnerabilities/l1tf" ]; then if [ -n "$fullmsg" ]; then
# vanilla: VMX: $l1dstatus, SMT $smtstatus # vanilla: VMX: $l1dstatus, SMT $smtstatus
# Red Hat: VMX: SMT $smtstatus, L1D $l1dstatus # Red Hat: VMX: SMT $smtstatus, L1D $l1dstatus
# $l1dstatus is one of (auto|vulnerable|conditional cache flushes|cache flushes|EPT disabled|flush not necessary) # $l1dstatus is one of (auto|vulnerable|conditional cache flushes|cache flushes|EPT disabled|flush not necessary)
# $smtstatus is one of (vulnerable|disabled) # $smtstatus is one of (vulnerable|disabled)
if grep -Eq '(VMX:|L1D) (EPT disabled|vulnerable|flush not necessary)' "/sys/devices/system/cpu/vulnerabilities/l1tf"; then # can also just be "Not affected"
if echo "$fullmsg" | grep -Eq -e 'Not affected' -e '(VMX:|L1D) (EPT disabled|vulnerable|flush not necessary)'; then
l1d_mode=0 l1d_mode=0
pstatus yellow NO pstatus yellow NO
elif grep -Eq '(VMX:|L1D) conditional cache flushes' "/sys/devices/system/cpu/vulnerabilities/l1tf"; then elif echo "$fullmsg" | grep -Eq '(VMX:|L1D) conditional cache flushes'; then
l1d_mode=1 l1d_mode=1
pstatus green YES "conditional flushes" pstatus green YES "conditional flushes"
elif grep -Eq '(VMX:|L1D) cache flushes' "/sys/devices/system/cpu/vulnerabilities/l1tf"; then elif echo "$fullmsg" | grep -Eq '(VMX:|L1D) cache flushes'; then
l1d_mode=2 l1d_mode=2
pstatus green YES "unconditional flushes" pstatus green YES "unconditional flushes"
else else
@ -4165,6 +4287,9 @@ check_CVE_2018_3646_linux()
if ! is_cpu_vulnerable "$cve"; then if ! is_cpu_vulnerable "$cve"; then
# override status & msg in case CPU is not vulnerable after all # override status & msg in case CPU is not vulnerable after all
pvulnstatus $cve OK "your CPU vendor reported your CPU model as not vulnerable" pvulnstatus $cve OK "your CPU vendor reported your CPU model as not vulnerable"
elif [ "$fullmsg" = "Not affected" ]; then
# just in case a very recent kernel knows better than we do
pvulnstatus $cve OK "your kernel reported your CPU model as not vulnerable"
elif [ "$has_vmm" = 0 ]; then elif [ "$has_vmm" = 0 ]; then
pvulnstatus $cve OK "this system is not running a hypervisor" pvulnstatus $cve OK "this system is not running a hypervisor"
else else
@ -4280,7 +4405,114 @@ check_mds()
{ {
cve=$1 cve=$1
_info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m" _info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m"
if [ "$os" = Linux ]; then
check_mds_linux "$cve"
elif echo "$os" | grep -q BSD; then
check_mds_bsd "$cve"
else
_warn "Unsupported OS ($os)"
fi
}
check_mds_bsd()
{
_info_nol "* Kernel supports using MD_CLEAR mitigation: "
if [ "$opt_live" = 1 ]; then
if sysctl hw.mds_disable >/dev/null 2>&1; then
pstatus green YES
kernel_md_clear=1
else
pstatus yellow NO
kernel_md_clear=0
fi
else
if command -v "strings" >/dev/null 2>&1; then
if strings /boot/kernel/kernel | grep -Fq hw.mds_disable; then
pstatus green YES
kernel_md_clear=1
else
kernel_md_clear=0
pstatus yellow NO
fi
else
pstatus yellow UNKNOWN
fi
fi
_info_nol "* CPU Hyper-Threading (SMT) is disabled: "
if sysctl machdep.hyperthreading_allowed >/dev/null 2>&1; then
kernel_smt_allowed=$(sysctl -n machdep.hyperthreading_allowed 2>/dev/null)
if [ "$kernel_smt_allowed" = 1 ]; then
pstatus yellow NO
else
pstatus green YES
fi
else
pstatus yellow UNKNOWN "sysctl machdep.hyperthreading_allowed doesn't exist"
fi
_info_nol "* Kernel mitigation is enabled: "
if [ "$kernel_md_clear" = 1 ]; then
kernel_mds_enabled=$(sysctl -n hw.mds_disable 2>/dev/null)
else
kernel_mds_enabled=0
fi
case "$kernel_mds_enabled" in
0) pstatus yellow NO;;
1) pstatus green YES "with microcode support";;
2) pstatus green YES "software-only support (SLOW)";;
3) pstatus green YES;;
*) pstatus yellow UNKNOWN "unknown value $kernel_mds_enabled"
esac
_info_nol "* Kernel mitigation is active: "
if [ "$kernel_md_clear" = 1 ]; then
kernel_mds_state=$(sysctl -n hw.mds_disable_state 2>/dev/null)
else
kernel_mds_state=inactive
fi
# https://github.com/freebsd/freebsd/blob/master/sys/x86/x86/cpu_machdep.c#L953
case "$kernel_mds_state" in
inactive) pstatus yellow NO;;
VERW) pstatus green YES "with microcode support";;
software*) pstatus green YES "software-only support (SLOW)";;
*) pstatus yellow UNKNOWN
esac
if ! is_cpu_vulnerable "$cve"; then
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not vulnerable"
else
if [ "$cpuid_md_clear" = 1 ]; then
if [ "$kernel_md_clear" = 1 ]; then
if [ "$opt_live" = 1 ]; then
# mitigation must also be enabled
if [ "$kernel_mds_enabled" -ge 1 ]; then
if [ "$opt_paranoid" != 1 ] || [ "$kernel_smt_allowed" = 0 ]; then
pvulnstatus "$cve" OK "Your microcode and kernel are both up to date for this mitigation, and mitigation is enabled"
else
pvulnstatus "$cve" VULN "Your microcode and kernel are both up to date for this mitigation, but your must disable SMT (Hyper-Threading) for a complete mitigation"
fi
else
pvulnstatus "$cve" VULN "Your microcode and kernel are both up to date for this mitigation, but the mitigation is not active"
fi
else
pvulnstatus "$cve" OK "Your microcode and kernel are both up to date for this mitigation"
fi
else
pvulnstatus "$cve" VULN "Your microcode supports mitigation, but your kernel doesn't, upgrade it to mitigate the vulnerability"
fi
else
if [ "$kernel_md_clear" = 1 ]; then
pvulnstatus "$cve" VULN "Your kernel supports mitigation, but your CPU microcode also needs to be updated to mitigate the vulnerability"
else
pvulnstatus "$cve" VULN "Neither your kernel or your microcode support mitigation, upgrade both to mitigate the vulnerability"
fi
fi
fi
}
check_mds_linux()
{
status=UNK status=UNK
sys_interface_available=0 sys_interface_available=0
msg='' msg=''
@ -4289,15 +4521,6 @@ check_mds()
sys_interface_available=1 sys_interface_available=1
fi fi
if [ "$opt_sysfs_only" != 1 ]; then if [ "$opt_sysfs_only" != 1 ]; then
_info_nol "* CPU supports the MD_CLEAR functionality: "
if [ "$cpuid_md_clear" = 1 ]; then
pstatus green YES
elif [ "$cpuid_md_clear" = 0 ]; then
pstatus yellow NO
else
pstatus yellow UNKNOWN "is cpuid module loaded?"
fi
_info_nol "* Kernel supports using MD_CLEAR mitigation: " _info_nol "* Kernel supports using MD_CLEAR mitigation: "
kernel_md_clear='' kernel_md_clear=''
kernel_md_clear_can_tell=1 kernel_md_clear_can_tell=1
@ -4326,7 +4549,7 @@ check_mds()
if [ "$opt_live" = 1 ] && [ "$sys_interface_available" = 1 ]; then if [ "$opt_live" = 1 ] && [ "$sys_interface_available" = 1 ]; then
_info_nol "* Kernel mitigation is enabled and active: " _info_nol "* Kernel mitigation is enabled and active: "
if grep -qi ^mitigation /sys/devices/system/cpu/vulnerabilities/mds; then if echo "$fullmsg" | grep -qi ^mitigation; then
mds_mitigated=1 mds_mitigated=1
pstatus green YES pstatus green YES
else else
@ -4334,7 +4557,7 @@ check_mds()
pstatus yellow NO pstatus yellow NO
fi fi
_info_nol "* SMT is either mitigated or disabled: " _info_nol "* SMT is either mitigated or disabled: "
if grep -Eq 'SMT (disabled|mitigated)' /sys/devices/system/cpu/vulnerabilities/mds; then if echo "$fullmsg" | grep -Eq 'SMT (disabled|mitigated)'; then
mds_smt_mitigated=1 mds_smt_mitigated=1
pstatus green YES pstatus green YES
else else
@ -4382,7 +4605,7 @@ check_mds()
else else
if [ "$opt_paranoid" = 1 ]; then if [ "$opt_paranoid" = 1 ]; then
# in paranoid mode, we don't only need microcode + kernel update, we also want SMT mitigation # in paranoid mode, we don't only need microcode + kernel update, we also want SMT mitigation
if grep -qF -e 'SMT mitigated' -e 'SMT disabled' /sys/devices/system/cpu/vulnerabilities/mds; then if echo "$fullmsg" | grep -qF -e 'SMT mitigated' -e 'SMT disabled'; then
pvulnstatus "$cve" OK "$fullmsg" pvulnstatus "$cve" OK "$fullmsg"
else else
pvulnstatus "$cve" VULN "Your kernel and microcode partially mitigate the vulnerability, but you must disable SMT (Hyper-Threading) for a complete mitigation" pvulnstatus "$cve" VULN "Your kernel and microcode partially mitigate the vulnerability, but you must disable SMT (Hyper-Threading) for a complete mitigation"
@ -4417,15 +4640,40 @@ if [ "$bad_accuracy" = 1 ]; then
_warn "We're missing some kernel info (see -v), accuracy might be reduced" _warn "We're missing some kernel info (see -v), accuracy might be reduced"
fi fi
_vars=$(set | grep -Ev '^[A-Z_[:space:]]' | sort | tr "\n" '|') _vars=$(set | grep -Ev '^[A-Z_[:space:]]' | grep -v -F 'mockme=' | sort | tr "\n" '|')
_debug "variables at end of script: $_vars" _debug "variables at end of script: $_vars"
if [ -n "$mockme" ] && [ "$opt_mock" = 1 ]; then
if command -v "gzip" >/dev/null 2>&1; then
# not a useless use of cat: gzipping cpuinfo directly doesn't work well
# shellcheck disable=SC2002
if command -v "base64" >/dev/null 2>&1; then
mock_cpuinfo="$(cat /proc/cpuinfo | gzip -c | base64 -w0)"
elif command -v "uuencode" >/dev/null 2>&1; then
mock_cpuinfo="$(cat /proc/cpuinfo | gzip -c | uuencode -m - | grep -Fv 'begin-base64' | grep -Fxv -- '====' | tr -d "\n")"
fi
fi
if [ -n "$mock_cpuinfo" ]; then
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_CPUINFO='$mock_cpuinfo'")
unset mock_cpuinfo
fi
_info ""
# shellcheck disable=SC2046
_warn "To mock this CPU, set those vars: "$(echo "$mockme" | sort -u)
fi
if [ "$opt_explain" = 0 ]; then if [ "$opt_explain" = 0 ]; then
_info "Need more detailed information about mitigation options? Use --explain" _info "Need more detailed information about mitigation options? Use --explain"
fi fi
_info "A false sense of security is worse than no security at all, see --disclaimer" _info "A false sense of security is worse than no security at all, see --disclaimer"
if [ "$mocked" = 1 ]; then
_info ""
_warn "One or several values have been mocked. This should only be done when debugging/testing this script."
_warn "The results do NOT reflect the actual status of the system we're running on."
fi
if [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "nrpe" ]; then if [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "nrpe" ]; then
if [ -n "$nrpe_vuln" ]; then if [ -n "$nrpe_vuln" ]; then
echo "Vulnerable:$nrpe_vuln" echo "Vulnerable:$nrpe_vuln"
@ -4460,7 +4708,7 @@ exit 0 # ok
# wget https://github.com/platomav/MCExtractor/raw/master/MCE.db # wget https://github.com/platomav/MCExtractor/raw/master/MCE.db
# sqlite3 MCE.db "select '%%% MCEDB v'||revision||' - '||strftime('%Y/%m/%d', date, 'unixepoch') from MCE; select '# I,0x'||cpuid||',0x'||version||','||max(yyyymmdd) from Intel group by cpuid order by cpuid asc; select '# A,0x'||cpuid||',0x'||version||','||max(yyyymmdd) from AMD group by cpuid order by cpuid asc" # sqlite3 MCE.db "select '%%% MCEDB v'||revision||' - '||strftime('%Y/%m/%d', date, 'unixepoch') from MCE; select '# I,0x'||cpuid||',0x'||version||','||max(yyyymmdd) from Intel group by cpuid order by cpuid asc; select '# A,0x'||cpuid||',0x'||version||','||max(yyyymmdd) from AMD group by cpuid order by cpuid asc"
# %%% MCEDB v110 - 2019/05/11 # %%% MCEDB v111 - 2019/05/18
# I,0x00000611,0x00000B27,19961218 # I,0x00000611,0x00000B27,19961218
# I,0x00000612,0x000000C6,19961210 # I,0x00000612,0x000000C6,19961210
# I,0x00000616,0x000000C6,19961210 # I,0x00000616,0x000000C6,19961210
@ -4639,8 +4887,8 @@ exit 0 # ok
# I,0x00030671,0x00000117,20130410 # I,0x00030671,0x00000117,20130410
# I,0x00030672,0x0000022E,20140401 # I,0x00030672,0x0000022E,20140401
# I,0x00030673,0x00000326,20180110 # I,0x00030673,0x00000326,20180110
# I,0x00030678,0x00000837,20180125 # I,0x00030678,0x00000838,20190422
# I,0x00030679,0x0000090A,20180110 # I,0x00030679,0x0000090C,20190423
# I,0x000306A0,0x00000007,20110407 # I,0x000306A0,0x00000007,20110407
# I,0x000306A2,0x0000000C,20110725 # I,0x000306A2,0x0000000C,20110725
# I,0x000306A4,0x00000007,20110908 # I,0x000306A4,0x00000007,20110908
@ -4678,8 +4926,8 @@ exit 0 # ok
# I,0x000406A9,0x0000081F,20140812 # I,0x000406A9,0x0000081F,20140812
# I,0x000406C1,0x0000010B,20140814 # I,0x000406C1,0x0000010B,20140814
# I,0x000406C2,0x00000221,20150218 # I,0x000406C2,0x00000221,20150218
# I,0x000406C3,0x00000367,20171225 # I,0x000406C3,0x00000368,20190423
# I,0x000406C4,0x00000410,20180104 # I,0x000406C4,0x00000411,20190423
# I,0x000406D0,0x0000000E,20130612 # I,0x000406D0,0x0000000E,20130612
# I,0x000406D8,0x0000012A,20180104 # I,0x000406D8,0x0000012A,20180104
# I,0x000406E1,0x00000020,20141111 # I,0x000406E1,0x00000020,20141111
@ -4694,8 +4942,8 @@ exit 0 # ok
# I,0x00050653,0x01000146,20180824 # I,0x00050653,0x01000146,20180824
# I,0x00050654,0x0200005E,20190402 # I,0x00050654,0x0200005E,20190402
# I,0x00050655,0x03000010,20181116 # I,0x00050655,0x03000010,20181116
# I,0x00050656,0x04000021,20190227 # I,0x00050656,0x04000024,20190407
# I,0x00050657,0x05000021,20190227 # I,0x00050657,0x05000024,20190407
# I,0x00050661,0xF1000008,20150130 # I,0x00050661,0xF1000008,20150130
# I,0x00050662,0x0000001A,20190323 # I,0x00050662,0x0000001A,20190323
# I,0x00050663,0x07000017,20190323 # I,0x00050663,0x07000017,20190323
@ -4715,7 +4963,7 @@ exit 0 # ok
# I,0x000506E3,0x000000CC,20190401 # I,0x000506E3,0x000000CC,20190401
# I,0x000506E8,0x00000034,20160710 # I,0x000506E8,0x00000034,20160710
# I,0x000506F0,0x00000010,20160607 # I,0x000506F0,0x00000010,20160607
# I,0x000506F1,0x0000002A,20190211 # I,0x000506F1,0x0000002E,20190321
# I,0x00060660,0x0000000C,20160821 # I,0x00060660,0x0000000C,20160821
# I,0x00060661,0x0000000E,20170128 # I,0x00060661,0x0000000E,20170128
# I,0x00060662,0x00000022,20171129 # I,0x00060662,0x00000022,20171129
@ -4730,8 +4978,8 @@ exit 0 # ok
# I,0x00080650,0x00000018,20180108 # I,0x00080650,0x00000018,20180108
# I,0x000806E9,0x000000B4,20190401 # I,0x000806E9,0x000000B4,20190401
# I,0x000806EA,0x000000B4,20190401 # I,0x000806EA,0x000000B4,20190401
# I,0x000806EB,0x000000AE,20190214 # I,0x000806EB,0x000000B8,20190330
# I,0x000806EC,0x000000B4,20190228 # I,0x000806EC,0x000000B8,20190330
# I,0x000906E9,0x000000B4,20190401 # I,0x000906E9,0x000000B4,20190401
# I,0x000906EA,0x000000B4,20190401 # I,0x000906EA,0x000000B4,20190401
# I,0x000906EB,0x000000B4,20190401 # I,0x000906EB,0x000000B4,20190401
@ -4808,10 +5056,10 @@ exit 0 # ok
# A,0x00800F12,0x08001230,20180804 # A,0x00800F12,0x08001230,20180804
# A,0x00800F82,0x0800820C,20190204 # A,0x00800F82,0x0800820C,20190204
# A,0x00810F00,0x08100004,20161120 # A,0x00810F00,0x08100004,20161120
# A,0x00810F10,0x08101013,20181129 # A,0x00810F10,0x08101014,20190307
# A,0x00810F11,0x08101102,20181106 # A,0x00810F11,0x08101102,20181106
# A,0x00810F80,0x08108002,20180605 # A,0x00810F80,0x08108002,20180605
# A,0x00810F81,0x08108102,20180813 # A,0x00810F81,0x08108102,20180813
# A,0x00820F00,0x08200002,20180214 # A,0x00820F00,0x08200002,20180214
# A,0x00870F00,0x08700004,20181206 # A,0x00870F00,0x08700004,20181206
# A,0x00870F10,0x0870100A,20190322 # A,0x00870F10,0x08701011,20190415