Merge pull request #4 from speed47/master

merge
This commit is contained in:
Rob Gill 2018-05-24 11:18:35 +10:00 committed by GitHub
commit 17b6e182d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 26 deletions

View File

@ -86,13 +86,13 @@ sudo ./spectre-meltdown-checker.sh
**CVE-2018-3640** rogue system register read (Variant 3a)
- Impact: TBC
- Mitigation: TBC
- Mitigation: microcode update only
- Performance impact of the mitigation: negligible
**CVE-2018-3639** speculative store bypass (Variant 4)
- Impact: software using JIT (no known exploitation against kernel)
- Mitigation: TBC
- Mitigation: microcode update + kernel update making possible for affected software to protect itself
- Performance impact of the mitigation: low to medium
## Understanding what this script does and doesn't

View File

@ -64,7 +64,7 @@ show_usage()
--batch nrpe produce machine readable output formatted for NRPE
--batch prometheus produce output for consumption by prometheus-node-exporter
--variant [1,2,3] specify which variant you'd like to check, by default all variants are checked,
--variant [1,2,3,3a,4] specify which variant you'd like to check, by default all variants are checked,
can be specified multiple times (e.g. --variant 2 --variant 3)
--hw-only only check for CPU information, don't check for any variant
--no-hw skip CPU information and checks, if you're inspecting a kernel not to be run on this host
@ -309,7 +309,10 @@ is_cpu_vulnerable()
# https://www.amd.com/en/corporate/speculative-execution
variant1=vuln
variant2=vuln
[ -z "$variant3" ] && variant3=immune
[ -z "$variant3" ] && variant3=immune
# https://www.amd.com/en/corporate/security-updates
# "We have not identified any AMD x86 products susceptible to the Variant 3a vulnerability in our analysis to-date."
[ -z "$variant3a" ] && variant3a=immune
elif [ "$cpu_vendor" = ARM ]; then
# ARM
# reference: https://developer.arm.com/support/security-update
@ -950,7 +953,7 @@ parse_cpu_details()
fi
echo "$cpu_ucode" | grep -q ^0x && cpu_ucode_decimal=$(( cpu_ucode ))
ucode_found="model $cpu_model stepping $cpu_stepping ucode $cpu_ucode cpuid "$(printf "0x%x" "$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" "$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
@ -1669,16 +1672,43 @@ check_cpu()
fi
# variant 4
_info " * Speculative Store Bypass Disable (SSBD)"
_info_nol " * CPU indicates SSBD capability: "
read_cpuid 0x7 $EDX 31 1 1; ret=$?
if [ $ret -eq 0 ]; then
#cpuid_ng1=1
pstatus green YES "SSBD feature bit"
elif [ $ret -eq 1 ]; then
pstatus yellow NO
else
if is_intel; then
_info " * Speculative Store Bypass Disable (SSBD)"
_info_nol " * CPU indicates SSBD capability: "
read_cpuid 0x7 $EDX 31 1 1; ret=$?
if [ $ret -eq 0 ]; then
cpuid_ssbd='Intel SSBD'
fi
elif is_amd; then
_info " * Speculative Store Bypass Disable (SSBD)"
_info_nol " * CPU indicates SSBD capability: "
read_cpuid 0x80000008 $EBX 24 1 1; ret24=$?
read_cpuid 0x80000008 $EBX 25 1 1; ret25=$?
if [ $ret24 -eq 0 ]; then
cpuid_ssbd='AMD SSBD in SPEC_CTRL'
#cpuid_ssbd_spec_ctrl=1
elif [ $ret25 -eq 0 ]; then
cpuid_ssbd='AMD SSBD in VIRT_SPEC_CTRL'
#cpuid_ssbd_virt_spec_ctrl=1
elif [ "$cpu_family" -ge 21 ] && [ "$cpu_family" -le 23 ]; then
cpuid_ssbd='AMD non-architectural MSR'
fi
fi
if [ -n "$cpuid_ssbd" ]; then
pstatus green YES "$cpuid_ssbd"
elif [ "$ret24" = 2 ] && [ "$ret25" = 2 ]; then
pstatus yellow UNKNOWN "is cpuid kernel module available?"
else
pstatus yellow NO
fi
if is_amd; then
# similar to SSB_NO for intel
read_cpuid 0x80000008 $EBX 26 1 1; ret=$?
if [ $ret -eq 0 ]; then
amd_ssb_no=1
fi
fi
if is_intel; then
@ -1765,15 +1795,15 @@ check_cpu()
else
pstatus yellow NO
fi
fi
_info_nol " * CPU explicitly indicates not being vulnerable to Variant 4 (SSB_NO): "
if [ "$capabilities_ssb_no" = -1 ]; then
pstatus yellow UNKNOWN
elif [ "$capabilities_ssb_no" = 1 ]; then
pstatus green YES
else
pstatus yellow NO
fi
_info_nol " * CPU explicitly indicates not being vulnerable to Variant 4 (SSB_NO): "
if [ "$capabilities_ssb_no" = -1 ]; then
pstatus yellow UNKNOWN
elif [ "$capabilities_ssb_no" = 1 ] || [ "$amd_ssb_no" = 1 ]; then
pstatus green YES
else
pstatus yellow NO
fi
_info_nol " * CPU microcode is known to cause stability problems: "
@ -2102,7 +2132,7 @@ check_variant2_linux()
fi
if [ -e "/sys/devices/system/cpu/vulnerabilities/spectre_v2" ]; then
# 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 grep -q 'IBPB' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then
_debug "ibpb: found enabled in sysfs"
[ -z "$ibpb_supported" ] && ibpb_supported='IBPB found enabled in sysfs'
[ -z "$ibpb_enabled" ] && ibpb_enabled=1
@ -2114,7 +2144,7 @@ check_variant2_linux()
ibrs_fw_enabled=1
fi
# when IBRS is enabled on 4.15+, we can see it in sysfs
if grep -q 'Indirect Branch Restricted Speculation' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then
if grep -q -e 'IBRS' -e 'Indirect Branch Restricted Speculation' "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then
_debug "ibrs: found IBRS in sysfs"
[ -z "$ibrs_supported" ] && ibrs_supported='found IBRS in sysfs'
[ -z "$ibrs_enabled" ] && ibrs_enabled=3
@ -2886,12 +2916,28 @@ check_variant3a()
{
_info "\033[1;34mCVE-2018-3640 [rogue system register read] aka 'Variant 3a'\033[0m"
status=UNK
sys_interface_available=0
msg=''
_info_nol " * CPU microcode mitigates the vulnerability: "
if [ -n "$cpuid_ssbd" ]; then
# microcodes that ship with SSBD are known to also fix variant3a
# there is no specific cpuid bit as far as we know
pstatus green YES
else
pstatus yellow NO
fi
cve='CVE-2018-3640'
if ! is_cpu_vulnerable 3a; 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 [ -n "$cpuid_ssbd" ]; then
pvulnstatus $cve OK "your CPU microcode mitigates the vulnerability"
else
pvulnstatus $cve UNK "new vulnerability, script will be updated when more technical information is available in the next hours/days"
pvulnstatus $cve VULN "an up-to-date CPU microcode is needed to mitigate this vulnerability"
explain "The microcode of your CPU needs to be upgraded to mitigate this vulnerability. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section). The microcode update is enough, there is no additional OS, kernel or software change needed."
fi
}
@ -2899,12 +2945,66 @@ check_variant4()
{
_info "\033[1;34mCVE-2018-3639 [speculative store bypass] aka 'Variant 4'\033[0m"
status=UNK
sys_interface_available=0
msg=''
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/spec_store_bypass"; then
# this kernel has the /sys interface, trust it over everything
sys_interface_available=1
fi
if [ "$opt_sysfs_only" != 1 ]; then
_info_nol " * Kernel supports speculation store bypass: "
if [ "$opt_live" = 1 ]; then
if grep -Eq 'Speculation.?Store.?Bypass:' /proc/self/status 2>/dev/null; then
kernel_ssb='found in /proc/self/status'
_debug "found Speculation.Store.Bypass: in /proc/self/status"
fi
fi
if [ -z "$kernel_ssb" ] && [ -n "$kernel" ]; then
kernel_ssb=$("${opt_arch_prefix}strings" "$kernel" | grep spec_store_bypass | head -n1);
[ -n "$kernel_ssb" ] && _debug "found $kernel_ssb in kernel"
fi
if [ -z "$kernel_ssb" ] && [ -n "$opt_map" ]; then
kernel_ssb=$(grep spec_store_bypass "$opt_map" | head -n1)
[ -n "$kernel_ssb" ] && _debug "found $kernel_ssb in System.map"
fi
if [ -n "$kernel_ssb" ]; then
pstatus green YES "$kernel_ssb"
else
pstatus yellow NO
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
cve='CVE-2018-3639'
if ! is_cpu_vulnerable 4; 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 [ -z "$msg" ] || [ "$msg" = "Vulnerable" ]; then
# if msg is empty, sysfs check didn't fill it, rely on our own test
if [ -n "$cpuid_ssbd" ]; then
if [ -n "$kernel_ssb" ]; then
pvulnstatus $cve OK "your system provides the necessary tools for software mitigation"
else
pvulnstatus $cve VULN "your kernel needs to be updated"
explain "You have a recent-enough CPU microcode but your kernel is too old to use the new features exported by your CPU's microcode. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources."
fi
else
if [ -n "$kernel_ssb" ]; then
pvulnstatus $cve VULN "Your CPU doesn't support SSBD"
explain "Your kernel is recent enough to use the CPU microcode features for mitigation, but your CPU microcode doesn't actually provide the necessary features for the kernel to use. The microcode of your CPU hence needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)."
else
pvulnstatus $cve VULN "Neither your CPU nor your kernel support SSBD"
explain "Both your CPU microcode and your kernel are lacking support for mitigation. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources. The microcode of your CPU also needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)."
fi
fi
else
pvulnstatus $cve UNK "new vulnerability, script will be updated when more technical information is available in the next hours/days"
pvulnstatus $cve "$status" "$msg"
fi
}