mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2025-07-15 07:11:22 +02:00
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
21af561148 | |||
cb740397f3 | |||
84195689af | |||
b637681fa8 | |||
9316c30577 | |||
f9dd9d8cb9 | |||
0f0d103a89 | |||
b262c40541 | |||
cc2910fbbc | |||
30c4a1f6d2 | |||
cf06636a3f | |||
60077c8d12 | |||
c181978d7c | |||
9a6406a9a2 | |||
5962d20ba7 | |||
17a3488505 | |||
e54e8b3e84 | |||
39c778e3ac | |||
2cde6e4649 | |||
f4d51e7e53 | |||
85d46b2799 | |||
61e02abd0c | |||
114756fab7 | |||
ea75969eb7 | |||
ca391cbfc9 | |||
68af5c5f92 | |||
19be8f79eb | |||
f75cc0bb6f | |||
f33d65ff71 | |||
725eaa8bf5 | |||
c6ee0358d1 | |||
22d0b203da | |||
3062a8416a | |||
6a4318addf | |||
c19986188f | |||
7e4899bcb8 | |||
5cc77741af | |||
1c0f6d9580 | |||
4acd0f647a | |||
fb52dbe7bf |
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM alpine:3.7
|
||||
|
||||
RUN apk --update --no-cache add kmod binutils grep perl
|
||||
|
||||
COPY . /check
|
||||
|
||||
ENTRYPOINT ["/check/spectre-meltdown-checker.sh"]
|
28
README.md
28
README.md
@ -1,7 +1,12 @@
|
||||
Spectre & Meltdown Checker
|
||||
==========================
|
||||
|
||||
A shell script to tell if your system is vulnerable against the 3 "speculative execution" CVEs that were made public early 2018.
|
||||
A shell script to tell if your system is vulnerable against the several "speculative execution" CVEs that were made public in 2018.
|
||||
- CVE-2017-5753 aka Spectre Variant 1
|
||||
- CVE-2017-5715 aka Spectre Variant 2
|
||||
- CVE-2017-5754 aka Meltdown or Variant 3
|
||||
- CVE-2018-3640 aka Variant 3a
|
||||
- CVE-2018-3639 aka Variant 4
|
||||
|
||||
Supported operating systems:
|
||||
- Linux (all versions, flavors and distros)
|
||||
@ -39,6 +44,13 @@ chmod +x spectre-meltdown-checker.sh
|
||||
sudo ./spectre-meltdown-checker.sh
|
||||
```
|
||||
|
||||
### Run the script in a docker container
|
||||
|
||||
```shell
|
||||
docker build -t spectre-meltdown-checker .
|
||||
docker run --rm --privileged -v /boot:/boot:ro -v /lib/modules:/lib/modules:ro -v /dev/cpu:/dev/cpu:ro spectre-meltdown-checker
|
||||
```
|
||||
|
||||
## Example of script output
|
||||
|
||||
- Intel Haswell CPU running under Ubuntu 16.04 LTS
|
||||
@ -74,7 +86,19 @@ sudo ./spectre-meltdown-checker.sh
|
||||
- Mitigation: updated kernel (with PTI/KPTI patches), updating the kernel is enough
|
||||
- Performance impact of the mitigation: low to medium
|
||||
|
||||
## Disclaimer
|
||||
**CVE-2018-3640** rogue system register read (Variant 3a)
|
||||
|
||||
- Impact: 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: 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
|
||||
|
||||
This tool does its best to determine whether your system is immune (or has proper mitigations in place) for the collectively named "speculative execution" vulnerabilities. It doesn't attempt to run any kind of exploit, and can't guarantee that your system is secure, but rather helps you verifying whether your system has the known correct mitigations in place.
|
||||
However, some mitigations could also exist in your kernel that this script doesn't know (yet) how to detect, or it might falsely detect mitigations that in the end don't work as expected (for example, on backported or modified kernels).
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
# Stephane Lesimple
|
||||
#
|
||||
VERSION='0.37'
|
||||
VERSION='0.38'
|
||||
|
||||
trap 'exit_cleanup' EXIT
|
||||
trap '_warn "interrupted, cleaning up..."; exit_cleanup; exit 1' INT
|
||||
@ -50,7 +50,7 @@ show_usage()
|
||||
Options:
|
||||
--no-color don't use color codes
|
||||
--verbose, -v increase verbosity level, possibly several times
|
||||
--no-explain don't produce a human-readable explanation of actions to take to mitigate a vulnerability
|
||||
--explain produce an additional human-readable explanation of actions to take to mitigate a vulnerability
|
||||
--paranoid require IBPB to deem Variant 2 as mitigated
|
||||
|
||||
--no-sysfs don't use the /sys interface even if present [Linux]
|
||||
@ -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
|
||||
@ -124,6 +124,8 @@ opt_verbose=1
|
||||
opt_variant1=0
|
||||
opt_variant2=0
|
||||
opt_variant3=0
|
||||
opt_variant3a=0
|
||||
opt_variant4=0
|
||||
opt_allvariants=1
|
||||
opt_no_sysfs=0
|
||||
opt_sysfs_only=0
|
||||
@ -131,7 +133,7 @@ opt_coreos=0
|
||||
opt_arch_prefix=''
|
||||
opt_hw_only=0
|
||||
opt_no_hw=0
|
||||
opt_no_explain=0
|
||||
opt_explain=0
|
||||
opt_paranoid=0
|
||||
|
||||
global_critical=0
|
||||
@ -233,7 +235,7 @@ _debug()
|
||||
|
||||
explain()
|
||||
{
|
||||
if [ "$opt_no_explain" != 1 ] ; then
|
||||
if [ "$opt_explain" = 1 ] ; then
|
||||
_info ''
|
||||
_info "> \033[41m\033[30mHow to fix:\033[0m $*"
|
||||
fi
|
||||
@ -248,13 +250,17 @@ _is_cpu_vulnerable_cached()
|
||||
[ "$1" = 2 ] && return $variant2
|
||||
# shellcheck disable=SC2086
|
||||
[ "$1" = 3 ] && return $variant3
|
||||
# shellcheck disable=SC2086
|
||||
[ "$1" = 3a ] && return $variant3a
|
||||
# shellcheck disable=SC2086
|
||||
[ "$1" = 4 ] && return $variant4
|
||||
echo "$0: error: invalid variant '$1' passed to is_cpu_vulnerable()" >&2
|
||||
exit 255
|
||||
}
|
||||
|
||||
is_cpu_vulnerable()
|
||||
{
|
||||
# param: 1, 2 or 3 (variant)
|
||||
# param: 1, 2, 3, 3a or 4 (variant)
|
||||
# returns 0 if vulnerable, 1 if not vulnerable
|
||||
# (note that in shell, a return of 0 is success)
|
||||
# by default, everything is vulnerable, we work in a "whitelist" logic here.
|
||||
@ -267,11 +273,15 @@ is_cpu_vulnerable()
|
||||
variant1=''
|
||||
variant2=''
|
||||
variant3=''
|
||||
variant3a=''
|
||||
variant4=''
|
||||
|
||||
if is_cpu_specex_free; then
|
||||
variant1=immune
|
||||
variant2=immune
|
||||
variant3=immune
|
||||
variant3a=immune
|
||||
variant4=immune
|
||||
elif is_intel; then
|
||||
# Intel
|
||||
# https://github.com/crozone/SpectrePoC/issues/1 ^F E5200 => spectre 2 not vulnerable
|
||||
@ -289,12 +299,33 @@ is_cpu_vulnerable()
|
||||
variant3=immune
|
||||
_debug "is_cpu_vulnerable: RDCL_NO is set so not vuln to meltdown"
|
||||
fi
|
||||
if [ "$capabilities_ssb_no" = 1 ]; then
|
||||
# capability bit for future Intel processor that will explicitly state
|
||||
# that they're not vulnerable to Variant 4
|
||||
# this var is set in check_cpu()
|
||||
variant4=immune
|
||||
_debug "is_cpu_vulnerable: SSB_NO is set so not vuln to variant4"
|
||||
fi
|
||||
if is_cpu_ssb_free; then
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
|
||||
fi
|
||||
elif is_amd; then
|
||||
# AMD revised their statement about variant2 => vulnerable
|
||||
# https://www.amd.com/en/corporate/speculative-execution
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
[ -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
|
||||
if is_cpu_ssb_free; then
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "is_cpu_vulnerable: cpu not affected by speculative store bypass so not vuln to variant4"
|
||||
fi
|
||||
elif [ "$cpu_vendor" = CAVIUM ]; then
|
||||
variant3=immune
|
||||
variant3a=immune
|
||||
elif [ "$cpu_vendor" = ARM ]; then
|
||||
# ARM
|
||||
# reference: https://developer.arm.com/support/security-update
|
||||
@ -313,46 +344,83 @@ is_cpu_vulnerable()
|
||||
if [ -n "$cpupart" ] && [ -n "$cpuarch" ]; then
|
||||
# Cortex-R7 and Cortex-R8 are real-time and only used in medical devices or such
|
||||
# I can't find their CPU part number, but it's probably not that useful anyway
|
||||
# model R7 R8 A9 A15 A17 A57 A72 A73 A75
|
||||
# part ? ? 0xc09 0xc0f 0xc0e 0xd07 0xd08 0xd09 0xd0a
|
||||
# arch 7? 7? 7 7 7 8 8 8 8
|
||||
# model R7 R8 A8 A9 A12 A15 A17 A57 A72 A73 A75 A76
|
||||
# part ? ? c08 c09 c0d c0f c0e d07 d08 d09 d0a d0b?
|
||||
# arch 7? 7? 7 7 7 7 7 8 8 8 8 8
|
||||
#
|
||||
# variant 1 & variant 2
|
||||
if [ "$cpuarch" = 7 ] && echo "$cpupart" | grep -Eq '^0x(c09|c0f|c0e)$'; then
|
||||
# armv7 vulnerable chips
|
||||
_debug "checking cpu$i: this armv7 vulnerable to spectre 1 & 2"
|
||||
# Whitelist identified non-vulnerable processors, use vulnerability information from
|
||||
# https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability
|
||||
#
|
||||
# Maintain cumulative check of vulnerabilities -
|
||||
# if at least one of the cpu is vulnerable, then the system is vulnerable
|
||||
if [ "$cpuarch" = 7 ] && echo "$cpupart" | grep -q -w -e 0xc08 -e 0xc09 -e 0xc0d -e 0xc0e; then
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -Eq '^0x(d07|d08|d09|d0a)$'; then
|
||||
# armv8 vulnerable chips
|
||||
_debug "checking cpu$i: this armv8 vulnerable to spectre 1 & 2"
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
[ -z "$variant3a" ] && variant3a=immune
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "checking cpu$i: armv7 A8/A9/A12/A17 non vulnerable to variants 3, 3a & 4"
|
||||
elif [ "$cpuarch" = 7 ] && echo "$cpupart" | grep -q -w -e 0xc0f; then
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
else
|
||||
_debug "checking cpu$i: this arm non vulnerable to 1 & 2"
|
||||
# others are not vulnerable
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
variant3a=vuln
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "checking cpu$i: armv7 A15 non vulnerable to variants 3 & 4"
|
||||
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -q -w -e 0xd07 -e 0xd08; then
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
variant3a=vuln
|
||||
variant4=vuln
|
||||
_debug "checking cpu$i: armv8 A57/A72 non vulnerable to variants 3"
|
||||
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -q -w -e 0xd09; then
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
[ -z "$variant3a" ] && variant3a=immune
|
||||
variant4=vuln
|
||||
_debug "checking cpu$i: armv8 A73 non vulnerable to variants 3 & 3a"
|
||||
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -q -w -e 0xd0a; then
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
variant3=vuln
|
||||
[ -z "$variant3a" ] && variant3a=immune
|
||||
variant4=vuln
|
||||
_debug "checking cpu$i: armv8 A75 non vulnerable to variant 3a"
|
||||
elif [ "$cpuarch" = 8 ] && echo "$cpupart" | grep -q -w -e 0xd0b; then
|
||||
variant1=vuln
|
||||
[ -z "$variant2" ] && variant2=immune
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
[ -z "$variant3a" ] && variant3a=immune
|
||||
variant4=vuln
|
||||
_debug "checking cpu$i: armv8 A76 non vulnerable to variant 2, 3 & 3a"
|
||||
elif [ "$cpuarch" -le 7 ] || ( [ "$cpuarch" = 8 ] && [ $(( cpupart )) -lt $(( 0xd07 )) ] ) ; then
|
||||
[ -z "$variant1" ] && variant1=immune
|
||||
[ -z "$variant2" ] && variant2=immune
|
||||
fi
|
||||
|
||||
# for variant3, only A75 is vulnerable
|
||||
if [ "$cpuarch" = 8 ] && [ "$cpupart" = 0xd0a ]; then
|
||||
_debug "checking cpu$i: arm A75 vulnerable to meltdown"
|
||||
variant3=vuln
|
||||
else
|
||||
_debug "checking cpu$i: this arm non vulnerable to meltdown"
|
||||
[ -z "$variant3" ] && variant3=immune
|
||||
[ -z "$variant3a" ] && variant3a=immune
|
||||
[ -z "$variant4" ] && variant4=immune
|
||||
_debug "checking cpu$i: arm arch$cpuarch, all immune (v7 or v8 and model < 0xd07)"
|
||||
else
|
||||
variant1=vuln
|
||||
variant2=vuln
|
||||
variant3=vuln
|
||||
variant3a=vuln
|
||||
variant4=vuln
|
||||
_debug "checking cpu$i: arm unknown arch$cpuarch part$cpupart, considering vuln"
|
||||
fi
|
||||
fi
|
||||
_debug "is_cpu_vulnerable: for cpu$i and so far, we have <$variant1> <$variant2> <$variant3>"
|
||||
_debug "is_cpu_vulnerable: for cpu$i and so far, we have <$variant1> <$variant2> <$variant3> <$variant3a> <$variant4>"
|
||||
done
|
||||
fi
|
||||
_debug "is_cpu_vulnerable: temp results are <$variant1> <$variant2> <$variant3>"
|
||||
# if at least one of the cpu is vulnerable, then the system is vulnerable
|
||||
_debug "is_cpu_vulnerable: temp results are <$variant1> <$variant2> <$variant3> <$variant3a> <$variant4>"
|
||||
[ "$variant1" = "immune" ] && variant1=1 || variant1=0
|
||||
[ "$variant2" = "immune" ] && variant2=1 || variant2=0
|
||||
[ "$variant3" = "immune" ] && variant3=1 || variant3=0
|
||||
_debug "is_cpu_vulnerable: final results are <$variant1> <$variant2> <$variant3>"
|
||||
[ "$variant3a" = "immune" ] && variant3a=1 || variant3a=0
|
||||
[ "$variant4" = "immune" ] && variant4=1 || variant4=0
|
||||
_debug "is_cpu_vulnerable: final results are <$variant1> <$variant2> <$variant3> <$variant3a> <$variant4>"
|
||||
is_cpu_vulnerable_cached=1
|
||||
_is_cpu_vulnerable_cached "$1"
|
||||
return $?
|
||||
@ -390,6 +458,51 @@ is_cpu_specex_free()
|
||||
return 1
|
||||
}
|
||||
|
||||
is_cpu_ssb_free()
|
||||
{
|
||||
# return true (0) if the CPU isn't affected by speculative store bypass, false (1) if it does.
|
||||
# if it's not in the list we know, return false (1).
|
||||
# source1: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/common.c#n945
|
||||
# source2: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/tree/arch/x86/kernel/cpu/common.c
|
||||
# Only list CPUs that speculate but are immune, to avoid duplication of cpus listed in is_cpu_specex_free()
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_MERRIFIELD },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL },
|
||||
#{ X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM },
|
||||
#{ X86_VENDOR_AMD, 0x12, },
|
||||
#{ X86_VENDOR_AMD, 0x11, },
|
||||
#{ X86_VENDOR_AMD, 0x10, },
|
||||
#{ X86_VENDOR_AMD, 0xf, },
|
||||
parse_cpu_details
|
||||
if is_intel; then
|
||||
if [ "$cpu_family" = 6 ]; then
|
||||
if [ "$cpu_model" = "$INTEL_FAM6_ATOM_AIRMONT" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT1" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_SILVERMONT2" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_ATOM_MERRIFIELD" ]; then
|
||||
return 0
|
||||
elif [ "$cpu_model" = "$INTEL_FAM6_CORE_YONAH" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNL" ] || \
|
||||
[ "$cpu_model" = "$INTEL_FAM6_XEON_PHI_KNM" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if is_amd; then
|
||||
if [ "$cpu_family" = "18" ] || \
|
||||
[ "$cpu_family" = "17" ] || \
|
||||
[ "$cpu_family" = "16" ] || \
|
||||
[ "$cpu_family" = "15" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
[ "$cpu_family" = 4 ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
show_header()
|
||||
{
|
||||
_info "Spectre and Meltdown mitigation detection tool v$VERSION"
|
||||
@ -471,7 +584,11 @@ while [ -n "$1" ]; do
|
||||
opt_no_hw=1
|
||||
shift
|
||||
elif [ "$1" = "--no-explain" ]; then
|
||||
opt_no_explain=1
|
||||
# deprecated, kept for compatibility
|
||||
opt_explain=0
|
||||
shift
|
||||
elif [ "$1" = "--explain" ]; then
|
||||
opt_explain=1
|
||||
shift
|
||||
elif [ "$1" = "--batch" ]; then
|
||||
opt_batch=1
|
||||
@ -492,15 +609,17 @@ while [ -n "$1" ]; do
|
||||
shift
|
||||
elif [ "$1" = "--variant" ]; then
|
||||
if [ -z "$2" ]; then
|
||||
echo "$0: error: option --variant expects a parameter (1, 2 or 3)" >&2
|
||||
echo "$0: error: option --variant expects a parameter (1, 2, 3, 3a or 4)" >&2
|
||||
exit 255
|
||||
fi
|
||||
case "$2" in
|
||||
1) opt_variant1=1; opt_allvariants=0;;
|
||||
2) opt_variant2=1; opt_allvariants=0;;
|
||||
3) opt_variant3=1; opt_allvariants=0;;
|
||||
3a) opt_variant3a=1; opt_allvariants=0;;
|
||||
4) opt_variant4=1; opt_allvariants=0;;
|
||||
*)
|
||||
echo "$0: error: invalid parameter '$2' for --variant, expected either 1, 2 or 3" >&2;
|
||||
echo "$0: error: invalid parameter '$2' for --variant, expected either 1, 2, 3, 3a or 4" >&2;
|
||||
exit 255
|
||||
;;
|
||||
esac
|
||||
@ -567,6 +686,8 @@ pvulnstatus()
|
||||
CVE-2017-5753) aka="SPECTRE VARIANT 1";;
|
||||
CVE-2017-5715) aka="SPECTRE VARIANT 2";;
|
||||
CVE-2017-5754) aka="MELTDOWN";;
|
||||
CVE-2018-3640) aka="VARIANT 3A";;
|
||||
CVE-2018-3639) aka="VARIANT 4";;
|
||||
esac
|
||||
|
||||
case "$opt_batch_format" in
|
||||
@ -732,8 +853,12 @@ mount_debugfs()
|
||||
load_msr()
|
||||
{
|
||||
if [ "$os" = Linux ]; then
|
||||
if ! grep -e msr /proc/modules 2>/dev/null; then
|
||||
modprobe msr 2>/dev/null && insmod_msr=1
|
||||
_debug "attempted to load module msr, insmod_msr=$insmod_msr"
|
||||
else
|
||||
_debug "msr module already loaded"
|
||||
fi
|
||||
else
|
||||
if ! kldstat -q -m cpuctl; then
|
||||
kldload cpuctl 2>/dev/null && kldload_cpuctl=1
|
||||
@ -747,8 +872,12 @@ load_msr()
|
||||
load_cpuid()
|
||||
{
|
||||
if [ "$os" = Linux ]; then
|
||||
if ! grep -e cpuid /proc/modules 2>/dev/null; then
|
||||
modprobe cpuid 2>/dev/null && insmod_cpuid=1
|
||||
_debug "attempted to load module cpuid, insmod_cpuid=$insmod_cpuid"
|
||||
else
|
||||
_debug "cpuid module already loaded"
|
||||
fi
|
||||
else
|
||||
if ! kldstat -q -m cpuctl; then
|
||||
kldload cpuctl 2>/dev/null && kldload_cpuctl=1
|
||||
@ -787,7 +916,10 @@ read_cpuid()
|
||||
# Linux
|
||||
# we need _leaf to be converted to decimal for dd
|
||||
_leaf=$(( _leaf ))
|
||||
_cpuid=$(dd if=/dev/cpu/0/cpuid bs=16 skip="$_leaf" iflag=skip_bytes count=1 2>/dev/null | od -A n -t u4)
|
||||
# to avoid using iflag=skip_bytes, which doesn't exist on old versions of dd, seek to the closer multiple-of-16
|
||||
_ddskip=$(( _leaf / 16 ))
|
||||
_odskip=$(( _leaf - _ddskip * 16 ))
|
||||
_cpuid=$(dd if=/dev/cpu/0/cpuid bs=16 skip=$_ddskip count=$((_odskip + 1)) 2>/dev/null | od -j $((_odskip * 16)) -A n -t u4)
|
||||
elif [ -e /dev/cpuctl0 ]; then
|
||||
# BSD
|
||||
_cpuid=$(cpucontrol -i "$_leaf" /dev/cpuctl0 2>/dev/null | awk '{print $4,$5,$6,$7}')
|
||||
@ -867,6 +999,9 @@ parse_cpu_details()
|
||||
cpu_friendly_name="ARM"
|
||||
[ -n "$cpu_arch" ] && cpu_friendly_name="$cpu_friendly_name v$cpu_arch"
|
||||
[ -n "$cpu_part" ] && cpu_friendly_name="$cpu_friendly_name model $cpu_part"
|
||||
|
||||
elif grep -qi 'CPU implementer[[:space:]]*:[[:space:]]*0x43' "$procfs/cpuinfo"; then
|
||||
cpu_vendor='CAVIUM'
|
||||
fi
|
||||
|
||||
cpu_family=$( grep '^cpu family' "$procfs/cpuinfo" | awk '{print $4}' | grep -E '^[0-9]+$' | head -1)
|
||||
@ -880,6 +1015,7 @@ parse_cpu_details()
|
||||
# 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
|
||||
cpuid="$read_cpuid_value"
|
||||
#cpuid_hex=$(printf "%X" "$cpuid")
|
||||
fi
|
||||
|
||||
# under BSD, linprocfs often doesn't export ucode information, so fetch it ourselves the good old way
|
||||
@ -900,7 +1036,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
|
||||
@ -1189,6 +1325,8 @@ if [ "$opt_live" = 1 ]; then
|
||||
[ -e "/boot/vmlinuz" ] && opt_kernel="/boot/vmlinuz"
|
||||
# Arch:
|
||||
[ -e "/boot/vmlinuz-linux" ] && opt_kernel="/boot/vmlinuz-linux"
|
||||
# Arch aarch64:
|
||||
[ -e "/boot/Image" ] && opt_kernel="/boot/Image"
|
||||
# Linux-Libre:
|
||||
[ -e "/boot/vmlinuz-linux-libre" ] && opt_kernel="/boot/vmlinuz-linux-libre"
|
||||
# pine64
|
||||
@ -1403,7 +1541,6 @@ read_msr()
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
check_cpu()
|
||||
{
|
||||
_info "\033[1;34mHardware check\033[0m"
|
||||
@ -1619,6 +1756,46 @@ check_cpu()
|
||||
fi
|
||||
fi
|
||||
|
||||
# variant 4
|
||||
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
|
||||
_info " * Enhanced IBRS (IBRS_ALL)"
|
||||
_info_nol " * CPU indicates ARCH_CAPABILITIES MSR availability: "
|
||||
@ -1638,11 +1815,13 @@ check_cpu()
|
||||
_info_nol " * ARCH_CAPABILITIES MSR advertises IBRS_ALL capability: "
|
||||
capabilities_rdcl_no=-1
|
||||
capabilities_ibrs_all=-1
|
||||
capabilities_ssb_no=-1
|
||||
if [ "$cpuid_arch_capabilities" = -1 ]; then
|
||||
pstatus yellow UNKNOWN
|
||||
elif [ "$cpuid_arch_capabilities" != 1 ]; then
|
||||
capabilities_rdcl_no=0
|
||||
capabilities_ibrs_all=0
|
||||
capabilities_ssb_no=0
|
||||
pstatus yellow NO
|
||||
elif [ ! -e /dev/cpu/0/msr ] && [ ! -e /dev/cpuctl0 ]; then
|
||||
spec_ctrl_msr=-1
|
||||
@ -1672,15 +1851,17 @@ check_cpu()
|
||||
capabilities=$val_cap_msr
|
||||
capabilities_rdcl_no=0
|
||||
capabilities_ibrs_all=0
|
||||
capabilities_ssb_no=0
|
||||
if [ $val -eq 0 ]; then
|
||||
_debug "capabilities MSR lower byte is $capabilities (decimal)"
|
||||
[ $(( capabilities & 1 )) -eq 1 ] && capabilities_rdcl_no=1
|
||||
[ $(( capabilities & 2 )) -eq 2 ] && capabilities_ibrs_all=1
|
||||
_debug "capabilities says rdcl_no=$capabilities_rdcl_no ibrs_all=$capabilities_ibrs_all"
|
||||
[ $(( capabilities & 16 )) -eq 16 ] && capabilities_ssb_no=1
|
||||
_debug "capabilities says rdcl_no=$capabilities_rdcl_no ibrs_all=$capabilities_ibrs_all ssb_no=$capabilities_ssb_no"
|
||||
if [ "$capabilities_ibrs_all" = 1 ]; then
|
||||
if [ $cpu_mismatch -eq 0 ]; then
|
||||
pstatus green YES
|
||||
else:
|
||||
else
|
||||
pstatus green YES "But not in all CPUs"
|
||||
fi
|
||||
else
|
||||
@ -1703,6 +1884,15 @@ check_cpu()
|
||||
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 ] || [ "$amd_ssb_no" = 1 ]; then
|
||||
pstatus green YES
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
_info_nol " * CPU microcode is known to cause stability problems: "
|
||||
if is_ucode_blacklisted; then
|
||||
pstatus red YES "$ucode_found"
|
||||
@ -1719,8 +1909,8 @@ check_cpu()
|
||||
|
||||
check_cpu_vulnerabilities()
|
||||
{
|
||||
_info "* CPU vulnerability to the three speculative execution attack variants"
|
||||
for v in 1 2 3; do
|
||||
_info "* CPU vulnerability to the speculative execution attack variants"
|
||||
for v in 1 2 3 3a 4; do
|
||||
_info_nol " * Vulnerable to Variant $v: "
|
||||
if is_cpu_vulnerable $v; then
|
||||
pstatus yellow YES
|
||||
@ -1787,7 +1977,7 @@ check_variant1_linux()
|
||||
fi
|
||||
if [ "$opt_sysfs_only" != 1 ]; then
|
||||
# no /sys interface (or offline mode), fallback to our own ways
|
||||
_info_nol "* Kernel has array_index_mask_nospec (x86): "
|
||||
_info_nol "* Kernel has array_index_mask_nospec: "
|
||||
# vanilla: look for the Linus' mask aka array_index_mask_nospec()
|
||||
# that is inlined at least in raw_copy_from_user (__get_user_X symbols)
|
||||
#mov PER_CPU_VAR(current_task), %_ASM_DX
|
||||
@ -1799,6 +1989,22 @@ check_variant1_linux()
|
||||
#ASM_STAC
|
||||
# x86 64bits: jae(0x0f 0x83 0x?? 0x?? 0x?? 0x??) sbb(0x48 0x19 0xd2) and(0x48 0x21 0xd0)
|
||||
# x86 32bits: cmp(0x3b 0x82 0x?? 0x?? 0x00 0x00) jae(0x73 0x??) sbb(0x19 0xd2) and(0x21 0xd0)
|
||||
#
|
||||
# arm32
|
||||
##ifdef CONFIG_THUMB2_KERNEL
|
||||
##define CSDB ".inst.w 0xf3af8014"
|
||||
##else
|
||||
##define CSDB ".inst 0xe320f014" e320f014
|
||||
##endif
|
||||
#asm volatile(
|
||||
# "cmp %1, %2\n" e1500003
|
||||
#" sbc %0, %1, %1\n" e0c03000
|
||||
#CSDB
|
||||
#: "=r" (mask)
|
||||
#: "r" (idx), "Ir" (sz)
|
||||
#: "cc");
|
||||
#
|
||||
# http://git.arm.linux.org.uk/cgit/linux-arm.git/commit/?h=spectre&id=a78d156587931a2c3b354534aa772febf6c9e855
|
||||
if [ -n "$kernel_err" ]; then
|
||||
pstatus yellow UNKNOWN "couldn't check ($kernel_err)"
|
||||
elif ! which perl >/dev/null 2>&1; then
|
||||
@ -1806,18 +2012,24 @@ check_variant1_linux()
|
||||
else
|
||||
perl -ne '/\x0f\x83....\x48\x19\xd2\x48\x21\xd0/ and $found++; END { exit($found) }' "$kernel"; ret=$?
|
||||
if [ $ret -gt 0 ]; then
|
||||
pstatus green YES "$ret occurrence(s) found of 64 bits array_index_mask_nospec()"
|
||||
v1_mask_nospec="64 bits array_index_mask_nospec"
|
||||
pstatus green YES "$ret occurrence(s) found of x86 64 bits array_index_mask_nospec()"
|
||||
v1_mask_nospec="x86 64 bits array_index_mask_nospec"
|
||||
else
|
||||
perl -ne '/\x3b\x82..\x00\x00\x73.\x19\xd2\x21\xd0/ and $found++; END { exit($found) }' "$kernel"; ret=$?
|
||||
if [ $ret -gt 0 ]; then
|
||||
pstatus green YES "$ret occurrence(s) found of 32 bits array_index_mask_nospec()"
|
||||
v1_mask_nospec="32 bits array_index_mask_nospec"
|
||||
pstatus green YES "$ret occurrence(s) found of x86 32 bits array_index_mask_nospec()"
|
||||
v1_mask_nospec="x86 32 bits array_index_mask_nospec"
|
||||
else
|
||||
ret=$("${opt_arch_prefix}objdump" -d "$kernel" | grep -w -e f3af8014 -e e320f014 -B2 | grep -B1 -w sbc | grep -w -c cmp)
|
||||
if [ "$ret" -gt 0 ]; then
|
||||
pstatus green YES "$ret occurrence(s) found of arm 32 bits array_index_mask_nospec()"
|
||||
v1_mask_nospec="arm 32 bits array_index_mask_nospec"
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
_info_nol "* Kernel has the Red Hat/Ubuntu patch: "
|
||||
check_redhat_canonical_spectre
|
||||
@ -1833,7 +2045,7 @@ check_variant1_linux()
|
||||
pstatus yellow NO
|
||||
fi
|
||||
|
||||
_info_nol "* Kernel has mask_nospec64 (arm): "
|
||||
_info_nol "* Kernel has mask_nospec64 (arm64): "
|
||||
#.macro mask_nospec64, idx, limit, tmp
|
||||
#sub \tmp, \idx, \limit
|
||||
#bic \tmp, \tmp, \idx
|
||||
@ -1860,13 +2072,12 @@ check_variant1_linux()
|
||||
"${opt_arch_prefix}objdump" -d "$kernel" | perl -ne 'push @r, $_; /\s(hint|csdb)\s/ && $r[0]=~/\ssub\s+(x\d+)/ && $r[1]=~/\sbic\s+$1,\s+$1,/ && $r[2]=~/\sand\s/ && exit(9); shift @r if @r>3'; ret=$?
|
||||
if [ "$ret" -eq 9 ]; then
|
||||
pstatus green YES "mask_nospec64 macro is present and used"
|
||||
v1_mask_nospec="arm mask_nospec64"
|
||||
v1_mask_nospec="arm64 mask_nospec64"
|
||||
else
|
||||
pstatus yellow NO
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ "$opt_verbose" -ge 2 ] || ( [ -z "$v1_mask_nospec" ] && [ "$redhat_canonical_spectre" != 1 ] && [ "$redhat_canonical_spectre" != 2 ] ); then
|
||||
# this is a slow heuristic and we don't need it if we already know the kernel is patched
|
||||
# but still show it in verbose mode
|
||||
@ -2029,7 +2240,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
|
||||
@ -2041,7 +2252,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
|
||||
@ -2129,7 +2340,10 @@ check_variant2_linux()
|
||||
1) if [ "$ibrs_fw_enabled" = 1 ]; then pstatus green YES "for kernel space and firmware code"; else pstatus green YES "for kernel space"; fi;;
|
||||
2) if [ "$ibrs_fw_enabled" = 1 ]; then pstatus green YES "for kernel, user space, and firmware code" ; else pstatus green YES "for both kernel and user space"; fi;;
|
||||
3) if [ "$ibrs_fw_enabled" = 1 ]; then pstatus green YES "for kernel and firmware code"; else pstatus green YES; fi;;
|
||||
*) pstatus yellow UNKNOWN;;
|
||||
*) if [ "$cpuid_ibrs" != 'SPEC_CTRL' ] && [ "$cpuid_ibrs" != 'IBRS_SUPPORT' ] && [ "$cpuid_spec_ctrl" != -1 ];
|
||||
then pstatus yellow NO; _debug "ibrs: known cpu not supporting SPEC-CTRL or IBRS";
|
||||
else
|
||||
pstatus yellow UNKNOWN; fi;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
@ -2381,7 +2595,7 @@ check_variant2_linux()
|
||||
|
||||
# if we are in live mode, we can check for a lot more stuff and explain further
|
||||
if [ "$opt_live" = 1 ] && [ "$vulnstatus" != "OK" ]; then
|
||||
_explain_hypervisor="An updated CPU microcode will have IBRS/IBPB capabilities indicated in the Hardware Check section above. If you're running under an hypervisor (KVM, Xen, VirtualBox, VMware, ...), the hypervisor needs to be up to date to be able to export the new host CPU flags to the guest. You can run this script on the host to check if the host CPU is IBRS/IBPB. If it is, and it doesn't show up in the guest, upgrade the hypervisor."
|
||||
_explain_hypervisor="An updated CPU microcode will have IBRS/IBPB capabilities indicated in the Hardware Check section above. If you're running under an hypervisor (KVM, Xen, VirtualBox, VMware, ...), the hypervisor needs to be up to date to be able to export the new host CPU flags to the guest. You can run this script on the host to check if the host CPU is IBRS/IBPB. If it is, and it doesn't show up in the guest, upgrade the hypervisor. You may need to reconfigure your VM to use a CPU model that has IBRS capability; in Libvirt, such CPUs are listed with an IBRS suffix."
|
||||
# IBPB (amd & intel)
|
||||
if ( [ -z "$ibpb_enabled" ] || [ "$ibpb_enabled" = 0 ] ) && ( is_intel || is_amd ); then
|
||||
if [ -z "$cpuid_ibpb" ]; then
|
||||
@ -2806,6 +3020,102 @@ check_variant3_bsd()
|
||||
fi
|
||||
}
|
||||
|
||||
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 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
|
||||
}
|
||||
|
||||
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 "$status" "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$opt_no_hw" = 0 ] && [ -z "$opt_arch_prefix" ]; then
|
||||
check_cpu
|
||||
check_cpu_vulnerabilities
|
||||
@ -2825,10 +3135,22 @@ if [ "$opt_variant3" = 1 ] || [ "$opt_allvariants" = 1 ]; then
|
||||
check_variant3
|
||||
_info
|
||||
fi
|
||||
if [ "$opt_variant3a" = 1 ] || [ "$opt_allvariants" = 1 ]; then
|
||||
check_variant3a
|
||||
_info
|
||||
fi
|
||||
if [ "$opt_variant4" = 1 ] || [ "$opt_allvariants" = 1 ]; then
|
||||
check_variant4
|
||||
_info
|
||||
fi
|
||||
|
||||
_vars=$(set | grep -Ev '^[A-Z_[:space:]]' | sort | tr "\n" '|')
|
||||
_debug "variables at end of script: $_vars"
|
||||
|
||||
if [ "$opt_explain" = 0 ]; then
|
||||
_info "Need more detailed information about mitigation options? Use --explain"
|
||||
fi
|
||||
|
||||
_info "A false sense of security is worse than no security at all, see --disclaimer"
|
||||
|
||||
if [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "nrpe" ]; then
|
||||
@ -2846,7 +3168,7 @@ fi
|
||||
if [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "prometheus" ]; then
|
||||
echo "# TYPE specex_vuln_status untyped"
|
||||
echo "# HELP specex_vuln_status Exposure of system to speculative execution vulnerabilities"
|
||||
echo "$prometheus_output"
|
||||
printf "%b\n" "$prometheus_output"
|
||||
fi
|
||||
|
||||
# exit with the proper exit code
|
||||
|
Reference in New Issue
Block a user