aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStéphane Lesimple <speed47_github@speed47.net>2018-01-21 18:02:11 +0100
committerStéphane Lesimple <speed47_github@speed47.net>2018-01-24 09:04:25 +0100
commitff5c92fa6fe3e5529600f6e712ca2c72c546c65b (patch)
treecb88c753a11a3958a5a4acc40eddf4dba1bef14e
parent443d9a2ae9819ac5c8219b2cc2bee7c70055bdae (diff)
downloadspectre-meltdown-checker-ff5c92fa6fe3e5529600f6e712ca2c72c546c65b.tar.lz
spectre-meltdown-checker-ff5c92fa6fe3e5529600f6e712ca2c72c546c65b.tar.xz
spectre-meltdown-checker-ff5c92fa6fe3e5529600f6e712ca2c72c546c65b.zip
feat(sysfs): print details even with sysfs
Before, when the /sys kernel vulnerability interface was available, we would bypass all our tests and just print the output of the vulnerability interface. Now, we still rely on it when available, but we run our checks anyway, except for variant 1 where the current method of mitigation detection doesn't add much value to the bare /sys check
-rwxr-xr-xspectre-meltdown-checker.sh71
1 files changed, 53 insertions, 18 deletions
diff --git a/spectre-meltdown-checker.sh b/spectre-meltdown-checker.sh
index 74514e2..904cfbb 100755
--- a/spectre-meltdown-checker.sh
+++ b/spectre-meltdown-checker.sh
@@ -34,6 +34,7 @@ show_usage()
--no-color Don't use color codes
--verbose, -v Increase verbosity level
--no-sysfs Don't use the /sys interface even if present
+ --sysfs-only Only use the /sys interface, don't run our own checks
--coreos Special mode for CoreOS (use an ephemeral toolbox to inspect kernel)
--batch text Produce machine readable output, this is the default if --batch is specified alone
--batch json Produce JSON output formatted for Puppet, Ansible, Chef...
@@ -91,6 +92,7 @@ opt_variant2=0
opt_variant3=0
opt_allvariants=1
opt_no_sysfs=0
+opt_sysfs_only=0
opt_coreos=0
global_critical=0
@@ -343,6 +345,9 @@ while [ -n "$1" ]; do
elif [ "$1" = "--no-sysfs" ]; then
opt_no_sysfs=1
shift
+ elif [ "$1" = "--sysfs-only" ]; then
+ opt_sysfs_only=1
+ shift
elif [ "$1" = "--coreos" ]; then
opt_coreos=1
shift
@@ -404,6 +409,11 @@ done
show_header
+if [ "$opt_no_sysfs" = 1 -a "$opt_sysfs_only" = 1 ]; then
+ _warn "Incompatible options specified (--no-sysfs and --sysfs-only), aborting"
+ exit 255
+fi
+
# print status function
pstatus()
{
@@ -771,7 +781,7 @@ _info
sys_interface_check()
{
[ "$opt_live" = 1 -a "$opt_no_sysfs" = 0 -a -r "$1" ] || return 1
- _info_nol "* Checking whether we're safe according to the /sys interface: "
+ _info_nol "* Mitigated according to the /sys interface: "
if grep -qi '^not affected' "$1"; then
# Not affected
status=OK
@@ -805,7 +815,7 @@ check_variant1()
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/spectre_v1"; then
# this kernel has the /sys interface, trust it over everything
sys_interface_available=1
- else
+ elif [ "$opt_sysfs_only" != 1 ]; then
# no /sys interface (or offline mode), fallback to our own ways
_info_nol "* Checking count of LFENCE opcodes in kernel: "
if [ -n "$vmlinux_err" ]; then
@@ -835,6 +845,10 @@ check_variant1()
fi
fi
fi
+ else
+ # we have no sysfs but were asked to use it only!
+ msg="/sys vulnerability interface use forced, but it's not available!"
+ status=UNK
fi
# if we have the /sys interface, don't even check is_cpu_vulnerable ourselves, the kernel already does it
@@ -860,7 +874,8 @@ check_variant2()
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/spectre_v2"; then
# this kernel has the /sys interface, trust it over everything
sys_interface_available=1
- else
+ fi
+ if [ "$opt_sysfs_only" != 1 ]; then
_info "* Mitigation 1"
_info " * Hardware support (CPU microcode)"
_info " * Indirect Branch Restricted Speculation (IBRS)"
@@ -1109,13 +1124,22 @@ check_variant2()
# See gcc commit https://github.com/hjl-tools/gcc/commit/23b517d4a67c02d3ef80b6109218f2aadad7bd79
# In latest retpoline LKML patches, the noretpoline_setup symbol exists only if CONFIG_RETPOLINE is set
# *AND* if the compiler is retpoline-compliant, so look for that symbol
- if [ -n "$opt_map" ]; then
+ if [ -e "/sys/devices/system/cpu/vulnerabilities/spectre_v2" ]; then
+ if grep -qw Minimal /sys/devices/system/cpu/vulnerabilities/spectre_v2; then
+ pstatus red NO "kernel reports minimal retpoline compilation"
+ elif grep -qw Full /sys/devices/system/cpu/vulnerabilities/spectre_v2; then
+ retpoline_compiler=1
+ pstatus green YES "kernel reports full retpoline compilation"
+ else
+ pstatus yellow UNKNOWN
+ fi
+ elif [ -n "$opt_map" ]; then
# look for the symbol
if grep -qw noretpoline_setup "$opt_map"; then
retpoline_compiler=1
pstatus green YES "noretpoline_setup symbol found in System.map"
else
- pstatus red NO
+ pstatus yellow UNKNOWN
fi
elif [ -n "$vmlinux" ]; then
# look for the symbol
@@ -1125,7 +1149,7 @@ check_variant2()
retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux symbols"
else
- pstatus red NO
+ pstatus yellow UNKNOWN
fi
elif grep -q noretpoline_setup "$vmlinux"; then
# if we don't have nm, nevermind, the symbol name is long enough to not have
@@ -1133,40 +1157,46 @@ check_variant2()
retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux"
else
- pstatus red NO
+ pstatus yellow UNKNOWN
fi
else
pstatus yellow UNKNOWN "couldn't find your kernel image or System.map"
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-2017-5715'
# if we have the /sys interface, don't even check is_cpu_vulnerable ourselves, the kernel already does it
if [ "$sys_interface_available" = 0 ] && ! is_cpu_vulnerable 2; then
# override status & msg in case CPU is not vulnerable after all
- pvulnstatus CVE-2017-5715 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 [ -z "$msg" ]; then
# if msg is empty, sysfs check didn't fill it, rely on our own test
if [ "$retpoline" = 1 -a "$retpoline_compiler" = 1 ]; then
- pvulnstatus CVE-2017-5715 OK "retpoline mitigate the vulnerability"
+ pvulnstatus $cve OK "retpoline mitigates the vulnerability"
elif [ "$opt_live" = 1 ]; then
if [ "$ibrs_enabled" = 1 -o "$ibrs_enabled" = 2 ] && [ "$ibpb_enabled" = 1 ]; then
- pvulnstatus CVE-2017-5715 OK "IBRS/IBPB are mitigating the vulnerability"
+ pvulnstatus $cve OK "IBRS/IBPB are mitigating the vulnerability"
elif [ "$ibpb_enabled" = 2 ]; then
- pvulnstatus CVE-2017-5715 OK "Full IBPB is mitigating the vulnerability"
+ pvulnstatus $cve OK "Full IBPB is mitigating the vulnerability"
else
- pvulnstatus CVE-2017-5715 VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
+ pvulnstatus $cve VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
fi
else
if [ "$ibrs_supported" = 1 ]; then
- pvulnstatus CVE-2017-5715 OK "offline mode: IBRS/IBPB will mitigate the vulnerability if enabled at runtime"
+ pvulnstatus $cve OK "offline mode: IBRS/IBPB will mitigate the vulnerability if enabled at runtime"
elif [ "$ibrs_can_tell" = 1 ]; then
- pvulnstatus CVE-2017-5715 VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
+ pvulnstatus $cve VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
else
- pvulnstatus CVE-2017-5715 UNK "offline mode: not enough information"
+ pvulnstatus $cve UNK "offline mode: not enough information"
fi
fi
else
- pvulnstatus CVE-2017-5715 "$status" "$msg"
+ [ "$msg" = "Vulnerable" ] && msg="IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
+ pvulnstatus $cve "$status" "$msg"
fi
}
@@ -1182,7 +1212,7 @@ check_variant3()
if sys_interface_check "/sys/devices/system/cpu/vulnerabilities/meltdown"; then
# this kernel has the /sys interface, trust it over everything
sys_interface_available=1
- else
+ elif [ "$opt_sysfs_only" != 1 ]; then
_info_nol "* Kernel supports Page Table Isolation (PTI): "
kpti_support=0
kpti_can_tell=0
@@ -1292,7 +1322,7 @@ check_variant3()
if [ "$opt_live" = 1 ]; then
# checking whether we're running under Xen PV 64 bits. If yes, we're not affected by variant3
- _info_nol "* Checking if we're running under Xen PV (64 bits): "
+ _info_nol "* Running under Xen PV (64 bits): "
if [ "$(uname -m)" = "x86_64" ]; then
# XXX do we have a better way that relying on dmesg?
dmesg_grep 'Booting paravirtualized kernel on Xen$'; ret=$?
@@ -1308,6 +1338,10 @@ check_variant3()
pstatus blue NO
fi
fi
+ elif [ "$sys_interface_available" = 0 ]; then
+ # we have no sysfs but were asked to use it only!
+ msg="/sys vulnerability interface use forced, but it's not available!"
+ status=UNK
fi
# if we have the /sys interface, don't even check is_cpu_vulnerable ourselves, the kernel already does it
@@ -1335,6 +1369,7 @@ check_variant3()
fi
fi
else
+ [ "$msg" = "Vulnerable" ] && msg="PTI is needed to mitigate the vulnerability"
pvulnstatus $cve "$status" "$msg"
fi
}