21 Commits
v0.32 ... v0.33

Author SHA1 Message Date
42094c4f8b release: v0.33 2018-01-26 14:20:29 +01:00
03d2dfe008 feat: add blacklisted Intel ucode detection
Some Intel microcodes are known to cause instabilities
such as random reboots. Intel advises to revert to a
previous version if a newer one that fixes those issues
is not available. Detect such known bad microcodes.
2018-01-26 14:19:54 +01:00
9f00ffa5af fix: fallback to UNKNOWN when we get -EACCES
For detection of IBRS_ALL and RDCL_NO, fallback to
UNKNOWN when we were unable to read the CPUID or MSR.
2018-01-26 14:16:34 +01:00
7f0d80b305 xen: detect if the host is a Xen Dom0 or PV DomU (fixes #83) 2018-01-25 11:04:30 +01:00
d1c1f0f0f0 fix(batch): fix regression introduced by acf12a6
In batch mode, $echo_cmd was not initialized early
enough, and caused this error:
./spectre-meltdown-checker.sh: 899: ./spectre-meltdown-checker.sh: -ne: not found
Fix it by initing echo_cmd unconditionally at the start
2018-01-24 17:57:19 +01:00
acf12a6d2d feat(cpu) add STIBP, RDCL_NO, IBRS_ALL checks
Move all the CPU checks to their own section,
for clarity. We now check for IBRS, IBPB, STIBP,
RDCL_NO and IBRS_ALL. We also show whether the
system CPU is vulnerable to the three variants,
regardless of the fact that mitigations are in
place or not, which is determined in each vuln-
specific section.
2018-01-24 14:44:16 +01:00
b45e40bec8 feat(stibp): add STIBP cpuid feature check 2018-01-24 12:19:02 +01:00
3c1d452c99 fix(cpuid): fix off-by-one SPEC_CTRL bit check 2018-01-24 12:18:56 +01:00
53b9eda040 fix: don't make IBPB mandatory when it's not there
On some kernels there could be IBRS support but not
IBPB support, in that case, don't report VULN just
because IBPB is not enabled when IBRS is
2018-01-24 09:04:25 +01:00
3b0ec998b1 fix(cosmetic): tiny msg fixes 2018-01-24 09:04:25 +01:00
d55bafde19 fix(cpu): trust is_cpu_vulnerable even w/ debugfs
For variant3 under AMD, the debugfs vulnerabilities hierarchy
flags the system as Vulnerable, which is wrong. Trust our own
is_cpu_vulnerable() func in that case
2018-01-24 09:04:25 +01:00
147462c0ab fix(variant3): do our checks even if sysfs is here 2018-01-24 09:04:25 +01:00
ddc7197b86 fix(retpoline): retpoline-compiler detection
When kernel is not compiled with retpoline option, doesn't
have the sysfs vulnerability hierarchy and our heuristic to
detect a retpoline-aware compiler didn't match, change result
for retpoline-aware compiler detection from UNKNOWN to NO.
When CONFIG_RETPOLINE is not set, a retpoline-aware compiler
won't produce different asm than a standard one anyway.
2018-01-24 09:04:25 +01:00
e7aa3b9d16 feat(retpoline): check if retpoline is enabled
Before we would just check if retpoline was compiled
in, now we also check that it's enabled at runtime
(only in live mode)
2018-01-24 09:04:25 +01:00
ff5c92fa6f 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
2018-01-24 09:04:25 +01:00
443d9a2ae9 feat(ibpb): now also check for IBPB on variant 2
In addition to IBRS (and microcode support), IBPB
must be used to mitigate variant 2, if retpoline
support is not available. The vulnerability status
of a system will be defined as "non vulnerable"
if IBRS and IBPB are both enabled, or if IBPB
is enabled with a value of 2 for RedHat kernels,
see https://access.redhat.com/articles/3311301
2018-01-24 09:04:25 +01:00
3e454f1817 fix(offline): report unknown when too few info
In offline mode, in the worst case where an invalid
config file is given, and we have no vmlinux image
nor System.map, the script was reporting Variant 2
and Variant 3 as vulnerable in the global status.
Replace this by a proper pair of UNKNOWNs
2018-01-23 22:20:34 +01:00
c8a25c5d97 feat: detect invalid kconfig files 2018-01-23 21:48:19 +01:00
40381349ab fix(dmesg): detect when dmesg is truncated
To avoid false negatives when looking for a message
in dmesg, we were previously also grepping in known
on-disk archives of dmesg (dmesg.log, kern.log).
This in turn caused false positives because we have no
guarantee that we're grepping the dmesg of the current
running kernel. Hence we now only look in the live
`dmesg`, detect if it has been truncated, and report
it to the user.
2018-01-21 16:26:08 +01:00
0aa5857a76 fix(cpu): Pentium Exxxx series are not vulnerable
Pentium E series are not in the vulnerable list from
Intel, and Spectre2 PoC reportedly doesn't work on
an E5200
2018-01-21 16:13:17 +01:00
b3b7f634e6 fix(display): use text-mode compatible colors
in text-mode 80-cols TERM=linux terminals, colors
were not displaying properly, one had to use
--no-color to be able to read some parts of the
text.
2018-01-21 12:32:22 +01:00

View File

@ -8,7 +8,7 @@
#
# Stephane Lesimple
#
VERSION=0.32
VERSION=0.33
show_usage()
{
@ -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,20 +92,13 @@ opt_variant2=0
opt_variant3=0
opt_allvariants=1
opt_no_sysfs=0
opt_sysfs_only=0
opt_coreos=0
global_critical=0
global_unknown=0
nrpe_vuln=""
echo_cmd=''
__echo()
{
opt="$1"
shift
_msg="$@"
if [ -z "$echo_cmd" ]; then
# find a sane `echo` command
# we'll try to avoid using shell builtins that might not take options
if which echo >/dev/null 2>&1; then
@ -115,7 +109,11 @@ __echo()
fi
# still empty ? fallback to builtin
[ -z "$echo_cmd" ] && echo_cmd=echo
fi
__echo()
{
opt="$1"
shift
_msg="$@"
if [ "$opt_no_color" = 1 ] ; then
# strip ANSI color codes
@ -196,7 +194,9 @@ is_cpu_vulnerable()
variant2=''
variant3=''
# we also set a friendly name for the CPU to be used in the script if needed
cpu_friendly_name=$(grep '^model name' /proc/cpuinfo | cut -d: -f2- | head -1)
cpu_friendly_name=$(grep '^model name' /proc/cpuinfo | cut -d: -f2- | head -1 | sed -e 's/^ *//')
# variant 0 is just for us to fill the cpu_friendly_name var
[ "$1" = 0 ] && return 0
if grep -q GenuineIntel /proc/cpuinfo; then
# Intel
@ -205,11 +205,23 @@ is_cpu_vulnerable()
# model name : Genuine Intel(R) CPU N270 @ 1.60GHz
# model name : Intel(R) Atom(TM) CPU N270 @ 1.60GHz
# model name : Intel(R) Atom(TM) CPU 330 @ 1.60GHz
if grep -qE '^model name.+ Intel\(R\) (Atom\(TM\) CPU +(S|D|N|230|330)|CPU N[0-9]{3} )' /proc/cpuinfo; then
#
# https://github.com/crozone/SpectrePoC/issues/1 ^F E5200:
# model name : Pentium(R) Dual-Core CPU E5200 @ 2.50GHz
if grep -qE -e '^model name.+ Intel\(R\) (Atom\(TM\) CPU +(S|D|N|230|330)|CPU N[0-9]{3} )' \
-e '^model name.+ Pentium\(R\) Dual-Core[[:space:]]+CPU[[:space:]]+E[0-9]{4}K? ' \
/proc/cpuinfo; then
variant1=vuln
[ -z "$variant2" ] && variant2=immune
[ -z "$variant3" ] && variant3=immune
fi
if [ "$capabilities_rdcl_no" = 1 ]; then
# capability bit for future Intel processor that will explicitly state
# that they're not vulnerable to Meltdown
# this var is set in check_cpu()
[ -z "$variant3" ] && variant3=immune
_debug "is_cpu_vulnerable: RDCL_NO is set so not vuln to meltdown"
fi
elif grep -q AuthenticAMD /proc/cpuinfo; then
# AMD revised their statement about variant2 => vulnerable
# https://www.amd.com/en/corporate/speculative-execution
@ -338,6 +350,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
@ -399,6 +414,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()
{
@ -406,10 +426,10 @@ pstatus()
_info_nol "$2"
else
case "$1" in
red) col="\033[101m\033[30m";;
green) col="\033[102m\033[30m";;
yellow) col="\033[103m\033[30m";;
blue) col="\033[104m\033[30m";;
red) col="\033[41m\033[30m";;
green) col="\033[42m\033[30m";;
yellow) col="\033[43m\033[30m";;
blue) col="\033[44m\033[30m";;
*) col="";;
esac
_info_nol "$col $2 \033[0m"
@ -583,12 +603,93 @@ unload_cpuid()
fi
}
dmesg_grep()
{
# grep for something in dmesg, ensuring that the dmesg buffer
# has not been truncated
dmesg_grepped=''
if ! dmesg | grep -qE '(^|\] )Linux version [0-9]'; then
# dmesg truncated
return 2
fi
dmesg_grepped=$(dmesg | grep -E "$1" | head -1)
# not found:
[ -z "$dmesg_grepped" ] && return 1
# found, output is in $dmesg_grepped
return 0
}
is_coreos()
{
which coreos-install >/dev/null 2>&1 && which toolbox >/dev/null 2>&1 && return 0
return 1
}
is_ucode_blacklisted()
{
# if it's not an Intel, don't bother: it's not blacklisted
grep -q GenuineIntel /proc/cpuinfo || return 1
# it also needs to be family=6
grep -qE '^cpu family.+ 6$' /proc/cpuinfo || return 1
cpu_model=$( grep '^model' /proc/cpuinfo | awk '{print $3}' | grep -E '^[0-9]+$' | head -1)
cpu_stepping=$(grep '^stepping' /proc/cpuinfo | awk '{print $3}' | grep -E '^[0-9]+$' | head -1)
cpu_ucode=$(grep '^microcode' /proc/cpuinfo | awk '{print $3}' | head -1)
# now, check each known bad microcode
# source: http://lkml.iu.edu/hypermail/linux/kernel/1801.2/06349.html
INTEL_FAM6_KABYLAKE_DESKTOP=158
INTEL_FAM6_KABYLAKE_MOBILE=142
INTEL_FAM6_SKYLAKE_X=85
INTEL_FAM6_SKYLAKE_MOBILE=78
INTEL_FAM6_SKYLAKE_DESKTOP=94
INTEL_FAM6_BROADWELL_CORE=61
INTEL_FAM6_BROADWELL_GT3E=71
INTEL_FAM6_HASWELL_ULT=69
INTEL_FAM6_HASWELL_GT3E=70
INTEL_FAM6_HASWELL_CORE=60
INTEL_FAM6_IVYBRIDGE_X=62
INTEL_FAM6_HASWELL_X=63
INTEL_FAM6_BROADWELL_XEON_D=86
INTEL_FAM6_BROADWELL_GT3E=71
INTEL_FAM6_BROADWELL_X=79
# model,stepping,microcode
for tuple in \
$INTEL_FAM6_KABYLAKE_DESKTOP,0x0B,0x80 \
$INTEL_FAM6_KABYLAKE_MOBILE,0x0A,0x80 \
$INTEL_FAM6_KABYLAKE_MOBILE,0x09,0x80 \
$INTEL_FAM6_KABYLAKE_DESKTOP,0x09,0x80 \
$INTEL_FAM6_SKYLAKE_X,0x04,0x0200003C \
$INTEL_FAM6_SKYLAKE_MOBILE,0x03,0x000000C2 \
$INTEL_FAM6_SKYLAKE_DESKTOP,0x03,0x000000C2 \
$INTEL_FAM6_BROADWELL_CORE,0x04,0x28 \
$INTEL_FAM6_BROADWELL_GT3E,0x01,0x0000001B \
$INTEL_FAM6_HASWELL_ULT,0x01,0x21 \
$INTEL_FAM6_HASWELL_GT3E,0x01,0x18 \
$INTEL_FAM6_HASWELL_CORE,0x03,0x23 \
$INTEL_FAM6_IVYBRIDGE_X,0x04,0x42a \
$INTEL_FAM6_HASWELL_X,0x02,0x3b \
$INTEL_FAM6_HASWELL_X,0x04,0x10 \
$INTEL_FAM6_HASWELL_CORE,0x03,0x23 \
$INTEL_FAM6_BROADWELL_XEON_D,0x02,0x14 \
$INTEL_FAM6_BROADWELL_XEON_D,0x03,0x7000011 \
$INTEL_FAM6_BROADWELL_GT3E,0x01,0x0000001B \
$INTEL_FAM6_BROADWELL_X,0x01,0x0b000025 \
$INTEL_FAM6_KABYLAKE_DESKTOP,0x09,0x80 \
$INTEL_FAM6_SKYLAKE_X,0x03,0x100013e \
$INTEL_FAM6_SKYLAKE_X,0x04,0x200003c
do
model=$(echo $tuple | cut -d, -f1)
stepping=$(( $(echo $tuple | cut -d, -f2) ))
ucode=$(echo $tuple | cut -d, -f3)
if [ "$cpu_model" = "$model" ] && [ "$cpu_stepping" = "$stepping" ] && echo "$cpu_ucode" | grep -qi "^$ucode$"; then
_debug "is_ucode_blacklisted: we have a match! ($model/$stepping/$ucode)"
bad_ucode_found="Intel CPU Family 6 Model $model Stepping $stepping with microcode $ucode"
return 0
fi
done
_debug "is_ucode_blacklisted: no ($model/$stepping/$ucode)"
return 1
}
# check for mode selection inconsistency
if [ "$opt_live_explicit" = 1 ]; then
if [ -n "$opt_kernel" -o -n "$opt_config" -o -n "$opt_map" ]; then
@ -630,9 +731,10 @@ if [ "$opt_live" = 1 ]; then
_warn "To run it as root, you can try the following command: sudo $0"
_warn
fi
_info "Checking for vulnerabilities against running kernel \033[35m"$(uname -s) $(uname -r) $(uname -v) $(uname -m)"\033[0m"
_info "Checking for vulnerabilities on current system"
_info "Kernel is \033[35m"$(uname -s) $(uname -r) $(uname -v) $(uname -m)"\033[0m"
# call is_cpu_vulnerable to fill the cpu_friendly_name var
is_cpu_vulnerable 1
is_cpu_vulnerable 0
_info "CPU is \033[35m$cpu_friendly_name\033[0m"
# try to find the image of the current running kernel
@ -698,14 +800,22 @@ else
_verbose "Will use no vmlinux image (accuracy might be reduced)"
bad_accuracy=1
fi
if [ -n "$dumped_config" ]; then
_verbose "Will use kconfig \033[35m/proc/config.gz\033[0m"
if [ -n "$opt_config" ] && ! grep -q '^CONFIG_' "$opt_config"; then
# given file is invalid!
_warn "The kernel config file seems invalid, was expecting a plain-text file, ignoring it!"
opt_config=''
fi
if [ -n "$dumped_config" ] && [ -n "$opt_config" ]; then
_verbose "Will use kconfig \033[35m/proc/config.gz (decompressed)\033[0m"
elif [ -n "$opt_config" ]; then
_verbose "Will use kconfig \033[35m$opt_config\033[0m"
else
_verbose "Will use no kconfig (accuracy might be reduced)"
bad_accuracy=1
fi
if [ -n "$opt_map" ]; then
_verbose "Will use System.map file \033[35m$opt_map\033[0m"
else
@ -742,7 +852,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
@ -764,6 +874,252 @@ sys_interface_check()
return 0
}
check_cpu()
{
_info "\033[1;34mHardware check\033[0m"
_info "* Hardware support (CPU microcode) for mitigation techniques"
_info " * Indirect Branch Restricted Speculation (IBRS)"
_info_nol " * SPEC_CTRL MSR is available: "
if [ ! -e /dev/cpu/0/msr ]; then
# try to load the module ourselves (and remember it so we can rmmod it afterwards)
load_msr
fi
if [ ! -e /dev/cpu/0/msr ]; then
spec_ctrl_msr=-1
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/msr, is msr support enabled in your kernel?"
else
# the new MSR 'SPEC_CTRL' is at offset 0x48
# here we use dd, it's the same as using 'rdmsr 0x48' but without needing the rdmsr tool
# if we get a read error, the MSR is not there. bs has to be 8 for msr
# skip=9 because 8*9=72=0x48
dd if=/dev/cpu/0/msr of=/dev/null bs=8 count=1 skip=9 2>/dev/null
if [ $? -eq 0 ]; then
spec_ctrl_msr=1
pstatus green YES
else
spec_ctrl_msr=0
pstatus red NO
fi
fi
_info_nol " * CPU indicates IBRS capability: "
if [ ! -e /dev/cpu/0/cpuid ]; then
# try to load the module ourselves (and remember it so we can rmmod it afterwards)
load_cpuid
fi
if [ ! -e /dev/cpu/0/cpuid ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/cpuid, is cpuid support enabled in your kernel?"
else
# from kernel src: { X86_FEATURE_SPEC_CTRL, CPUID_EDX,26, 0x00000007, 0 },
if [ "$opt_verbose" -ge 3 ]; then
dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 >/dev/null 2>/dev/null
_debug "cpuid: reading leaf7 of cpuid on cpu0, ret=$?"
_debug "cpuid: leaf7 eax-ebx-ecx-edx: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | od -x -A n)
_debug "cpuid: leaf7 edx higher byte is: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -x -A n)
fi
# getting high byte of edx on leaf7 of cpuinfo in decimal
edx_hb=$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -t u -A n | awk '{print $1}')
_debug "cpuid: leaf7 edx higher byte: $edx_hb (decimal)"
edx_bit26=$(( edx_hb & 4 ))
_debug "cpuid: edx_bit26=$edx_bit26"
if [ "$edx_bit26" -eq 4 ]; then
pstatus green YES "SPEC_CTRL feature bit"
cpuid_spec_ctrl=1
else
pstatus red NO
fi
fi
# hardware support according to kernel
if [ "$opt_verbose" -ge 2 ]; then
# the spec_ctrl flag in cpuinfo is set if and only if the kernel sees
# that the spec_ctrl cpuinfo bit set. we already check that ourselves above
# but let's check it anyway (in verbose mode only)
_verbose_nol " * Kernel has set the spec_ctrl flag in cpuinfo: "
if [ "$opt_live" = 1 ]; then
if grep ^flags /proc/cpuinfo | grep -qw spec_ctrl; then
pstatus green YES
else
pstatus blue NO
fi
else
pstatus blue N/A "not testable in offline mode"
fi
fi
# IBPB
_info " * Indirect Branch Prediction Barrier (IBPB)"
_info_nol " * PRED_CMD MSR is available: "
if [ ! -e /dev/cpu/0/msr ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/msr, is msr support enabled in your kernel?"
else
# the new MSR 'PRED_CTRL' is at offset 0x49, write-only
# here we use dd, it's the same as using 'wrmsr 0x49 0' but without needing the wrmsr tool
# if we get a write error, the MSR is not there
$echo_cmd -ne "\0\0\0\0\0\0\0\0" | dd of=/dev/cpu/0/msr bs=8 count=1 seek=73 oflag=seek_bytes 2>/dev/null
if [ $? -eq 0 ]; then
pstatus green YES
else
pstatus red NO
fi
fi
_info_nol " * CPU indicates IBPB capability: "
if [ ! -e /dev/cpu/0/cpuid ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/cpuid, is cpuid support enabled in your kernel?"
else
# CPUID EAX=0x80000008, ECX=0x00 return EBX[12] indicates support for just IBPB.
if [ "$opt_verbose" -ge 3 ]; then
dd if=/dev/cpu/0/cpuid bs=16 skip=2147483656 iflag=skip_bytes count=1 >/dev/null 2>/dev/null
_debug "cpuid: reading leaf80000008 of cpuid on cpu0, ret=$?"
_debug "cpuid: leaf80000008 eax-ebx-ecx-edx: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=2147483656 iflag=skip_bytes count=1 2>/dev/null | od -x -A n)
_debug "cpuid: leaf80000008 ebx 3rd byte is: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=2147483656 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=5 count=1 2>/dev/null | od -x -A n)
fi
# getting high byte of edx on leaf7 of cpuinfo in decimal
ebx_b3=$(dd if=/dev/cpu/0/cpuid bs=16 skip=2147483656 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=5 count=1 2>/dev/null | od -t u -A n | awk '{print $1}')
_debug "cpuid: leaf80000008 ebx 3rd byte: $ebx_b3 (decimal)"
ebx_bit12=$(( ebx_b3 & 16 ))
_debug "cpuid: ebx_bit12=$ebx_bit12"
if [ "$ebx_bit12" -eq 16 ]; then
pstatus green YES "IBPB_SUPPORT feature bit"
cpuid_ibpb=1
elif [ "$cpuid_spec_ctrl" = 1 ]; then
pstatus green YES "SPEC_CTRL feature bit"
else
pstatus red NO
fi
fi
# STIBP
_info " * Single Thread Indirect Branch Predictors (STIBP)"
_info_nol " * SPEC_CTRL MSR is available: "
if [ "$spec_ctrl_msr" = 1 ]; then
pstatus green YES
elif [ "$spec_ctrl_msr" = 0 ]; then
pstatus red NO
else
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/msr, is msr support enabled in your kernel?"
fi
_info_nol " * CPU indicates STIBP capability: "
if [ ! -e /dev/cpu/0/cpuid ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/cpuid, is cpuid support enabled in your kernel?"
else
# A processor supports STIBP if it enumerates CPUID (EAX=7H,ECX=0):EDX[27] as 1
if [ "$opt_verbose" -ge 3 ]; then
dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 >/dev/null 2>/dev/null
_debug "cpuid: reading leaf7 of cpuid on cpu0, ret=$?"
_debug "cpuid: leaf7 eax-ebx-ecx-edx: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | od -x -A n)
_debug "cpuid: leaf7 edx higher byte is: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -x -A n)
fi
# getting high byte of edx on leaf7 of cpuinfo in decimal
edx_hb=$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -t u -A n | awk '{print $1}')
_debug "cpuid: leaf7 edx higher byte: $edx_hb (decimal)"
edx_bit27=$(( edx_hb & 8 ))
_debug "cpuid: edx_bit27=$edx_bit27"
if [ "$edx_bit27" -eq 8 ]; then
pstatus green YES
cpuid_stibp=1
else
pstatus red NO
fi
fi
_info " * Enhanced IBRS (IBRS_ALL)"
_info_nol " * CPU indicates ARCH_CAPABILITIES MSR availability: "
cpuid_arch_capabilities=-1
if [ ! -e /dev/cpu/0/cpuid ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/cpuid, is cpuid support enabled in your kernel?"
else
# A processor supports STIBP if it enumerates CPUID (EAX=7H,ECX=0):EDX[27] as 1
if [ "$opt_verbose" -ge 3 ]; then
dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 >/dev/null 2>/dev/null
_debug "cpuid: reading leaf7 of cpuid on cpu0, ret=$?"
_debug "cpuid: leaf7 eax-ebx-ecx-edx: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | od -x -A n)
_debug "cpuid: leaf7 edx higher byte is: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -x -A n)
fi
# getting high byte of edx on leaf7 of cpuinfo in decimal
edx_hb=$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -t u -A n | awk '{print $1}')
_debug "cpuid: leaf7 edx higher byte: $edx_hb (decimal)"
edx_bit29=$(( edx_hb & 32 ))
_debug "cpuid: edx_bit29=$edx_bit29"
if [ "$edx_bit27" -eq 32 ]; then
pstatus green YES
cpuid_arch_capabilities=1
else
pstatus red NO
cpuid_arch_capabilities=0
fi
fi
_info_nol " * ARCH_CAPABILITIES MSR advertises IBRS_ALL capability: "
capabilities_rdcl_no=-1
capabilities_ibrs_all=-1
if [ "$cpuid_arch_capabilities" = -1 ]; then
pstatus yellow UNKNOWN
elif [ "$cpuid_arch_capabilities" != 1 ]; then
pstatus red NO
elif [ ! -e /dev/cpu/0/msr ]; then
spec_ctrl_msr=-1
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/msr, is msr support enabled in your kernel?"
else
# the new MSR 'ARCH_CAPABILITIES' is at offset 0x10a
# here we use dd, it's the same as using 'rdmsr 0x10a' but without needing the rdmsr tool
# if we get a read error, the MSR is not there. bs has to be 8 for msr
capabilities=$(dd if=/dev/cpu/0/msr bs=8 count=1 skip=266 iflag=skip_bytes 2>/dev/null | od -t u1 -A n | awk '{print $8}')
if [ $? -eq 0 ]; then
_debug "capabilities MSR lower byte is $capabilities (decimal)"
capabilities_rdcl_no=0
capabilities_ibrs_all=0
[ $(( 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"
if [ "$capabilities_ibrs_all" = 1 ]; then
pstatus green YES
else
pstatus red NO
fi
else
pstatus yellow UNKNOWN
fi
fi
_info_nol " * CPU explicitly indicates not being vulnerable to Meltdown (RDCL_NO): "
if [ "$capabilities_rdcl_no" = -1 ]; then
pstatus yellow UNKNOWN
elif [ "$capabilities_rdcl_no" = 1 ]; then
pstatus green YES
else
pstatus blue NO
fi
_info_nol " * CPU microcode is known to cause stability problems: "
if is_ucode_blacklisted; then
pstatus red YES "$bad_ucode_found"
_warn
_warn "The microcode your CPU is running on is known to cause instability problems,"
_warn "such as intempestive reboots or random crashes."
_warn "You are advised to either revert to a previous microcode version (that might not have"
_warn "the mitigations for Spectre), or upgrade to a newer one if available."
_warn
else
pstatus green NO
fi
_info "* CPU vulnerability to the three speculative execution attacks variants"
for v in 1 2 3; do
_info_nol " * Vulnerable to Variant $v: "
if is_cpu_vulnerable $v; then
pstatus red YES
else
pstatus green NO
fi
done
_info
}
###################
# SPECTRE VARIANT 1
check_variant1()
@ -776,7 +1132,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
@ -806,10 +1162,13 @@ 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
if [ "$sys_interface_available" = 0 ] && ! is_cpu_vulnerable 1; then
if ! is_cpu_vulnerable 1; then
# override status & msg in case CPU is not vulnerable after all
msg="your CPU vendor reported your CPU model as not vulnerable"
status=OK
@ -831,92 +1190,39 @@ 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 (CPU microcode) support for mitigation"
_info_nol "* The SPEC_CTRL MSR is available: "
if [ ! -e /dev/cpu/0/msr ]; then
# try to load the module ourselves (and remember it so we can rmmod it afterwards)
load_msr
fi
if [ ! -e /dev/cpu/0/msr ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/msr, is msr support enabled in your kernel?"
else
# the new MSR 'SPEC_CTRL' is at offset 0x48
# here we use dd, it's the same as using 'rdmsr 0x48' but without needing the rdmsr tool
# if we get a read error, the MSR is not there
dd if=/dev/cpu/0/msr of=/dev/null bs=8 count=1 skip=9 2>/dev/null
if [ $? -eq 0 ]; then
pstatus green YES
else
pstatus red NO
fi
fi
_info_nol " * Kernel is compiled with IBRS/IBPB support: "
ibrs_can_tell=0
unload_msr
# CPUID test
_info_nol "* The SPEC_CTRL CPUID feature bit is set: "
if [ ! -e /dev/cpu/0/cpuid ]; then
# try to load the module ourselves (and remember it so we can rmmod it afterwards)
load_cpuid
fi
if [ ! -e /dev/cpu/0/cpuid ]; then
pstatus yellow UNKNOWN "couldn't read /dev/cpu/0/cpuidr, is cpuid support enabled in your kernel?"
else
# from kernel src: { X86_FEATURE_SPEC_CTRL, CPUID_EDX,26, 0x00000007, 0 },
if [ "$opt_verbose" -ge 3 ]; then
dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 >/dev/null 2>/dev/null
_debug "cpuid: reading leaf7 of cpuid on cpu0, ret=$?"
_debug "cpuid: leaf7 eax-ebx-ecd-edx: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | od -x -A n)
_debug "cpuid: leaf7 edx higher-half is: "$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -x -A n)
fi
# getting high byte of edx on leaf7 of cpuinfo in decimal
edx_hb=$(dd if=/dev/cpu/0/cpuid bs=16 skip=7 iflag=skip_bytes count=1 2>/dev/null | dd bs=1 skip=15 count=1 2>/dev/null | od -t u -A n | awk '{print $1}')
_debug "cpuid: leaf7 edx higher byte: $edx_hb (decimal)"
edx_bit26=$(( edx_hb & 8 ))
_debug "cpuid: edx_bit26=$edx_bit26"
if [ "$edx_bit26" -eq 8 ]; then
pstatus green YES
else
pstatus red NO
fi
fi
unload_cpuid
# hardware support according to kernel
if [ "$opt_verbose" -ge 2 ]; then
_verbose_nol "* The kernel has set the spec_ctrl flag in cpuinfo: "
if [ "$opt_live" = 1 ]; then
if grep ^flags /proc/cpuinfo | grep -qw spec_ctrl; then
pstatus green YES
else
pstatus red NO
fi
else
pstatus blue N/A "not testable in offline mode"
fi
fi
_info_nol "* Kernel support for IBRS: "
if [ "$opt_live" = 1 ]; then
ibrs_can_tell=1
mount_debugfs
for ibrs_file in \
/sys/kernel/debug/ibrs_enabled \
/sys/kernel/debug/x86/ibrs_enabled \
/proc/sys/kernel/ibrs_enabled; do
if [ -e "$ibrs_file" ]; then
for dir in \
/sys/kernel/debug \
/sys/kernel/debug/x86 \
/proc/sys/kernel; do
if [ -e "$dir/ibrs_enabled" ]; then
# if the file is there, we have IBRS compiled-in
# /sys/kernel/debug/ibrs_enabled: vanilla
# /sys/kernel/debug/x86/ibrs_enabled: RedHat (see https://access.redhat.com/articles/3311301)
# /proc/sys/kernel/ibrs_enabled: OpenSUSE tumbleweed
pstatus green YES
ibrs_knob_dir=$dir
ibrs_supported=1
ibrs_enabled=$(cat "$ibrs_file" 2>/dev/null)
_debug "ibrs: found $ibrs_file=$ibrs_enabled"
ibrs_enabled=$(cat "$dir/ibrs_enabled" 2>/dev/null)
_debug "ibrs: found $dir/ibrs_enabled=$ibrs_enabled"
if [ -e "$dir/ibpb_enabled" ]; then
ibpb_enabled=$(cat "$dir/ibpb_enabled" 2>/dev/null)
_debug "ibpb: found $dir/ibpb_enabled=$ibpb_enabled"
else
ibpb_enabled=-1
_debug "ibpb: no ibpb_enabled file in $dir"
fi
break
else
_debug "ibrs: file $ibrs_file doesn't exist"
_debug "ibrs: $dir/ibrs_enabled file doesn't exist"
fi
done
# on some newer kernels, the spec_ctrl_ibrs flag in /proc/cpuinfo
@ -929,10 +1235,12 @@ check_variant2()
ibrs_supported=1
# enabled=2 -> kernel & user
ibrs_enabled=2
# XXX and what about ibpb ?
fi
fi
fi
if [ "$ibrs_supported" != 1 -a -n "$opt_map" ]; then
ibrs_can_tell=1
if grep -q spec_ctrl "$opt_map"; then
pstatus green YES
ibrs_supported=1
@ -940,36 +1248,68 @@ check_variant2()
fi
fi
if [ "$ibrs_supported" != 1 ]; then
if [ "$ibrs_can_tell" = 1 ]; then
pstatus red NO
else
# if we're in offline mode without System.map, we can't really know
pstatus yellow UNKNOWN "in offline mode, we need System.map to be able to tell"
fi
fi
_info " * Currently enabled features"
_info_nol " * IBRS enabled for Kernel space: "
if [ "$opt_live" = 1 ]; then
if [ "$ibpb_enabled" = 2 ]; then
# if ibpb=2, ibrs is forcefully=0
pstatus blue NO "IBPB used instead of IBRS in all kernel entrypoints"
else
# 0 means disabled
# 1 is enabled only for kernel space
# 2 is enabled for kernel and user space
case "$ibrs_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;;
0) pstatus red NO;;
0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibrs_enabled";;
1 | 2) pstatus green YES;;
*) pstatus yellow UNKNOWN;;
esac
fi
else
pstatus blue N/A "not testable in offline mode"
fi
_info_nol " * IBRS enabled for User space: "
if [ "$opt_live" = 1 ]; then
if [ "$ibpb_enabled" = 2 ]; then
# if ibpb=2, ibrs is forcefully=0
pstatus blue NO "IBPB used instead of IBRS in all kernel entrypoints"
else
case "$ibrs_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;;
0 | 1) pstatus red NO;;
0 | 1) pstatus red NO "echo 2 > $ibrs_knob_dir/ibrs_enabled";;
2) pstatus green YES;;
*) pstatus yellow UNKNOWN;;
esac
fi
else
pstatus blue N/A "not testable in offline mode"
fi
_info_nol " * IBPB enabled: "
if [ "$opt_live" = 1 ]; then
case "$ibpb_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;;
0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibpb_enabled";;
1) pstatus green YES;;
2) pstatus green YES "IBPB used instead of IBRS in all kernel entrypoints";;
*) pstatus yellow UNKNOWN;;
esac
else
pstatus blue N/A "not testable in offline mode"
fi
unload_msr
unload_cpuid
_info "* Mitigation 2"
_info_nol " * Kernel compiled with retpoline option: "
# We check the RETPOLINE kernel options
@ -991,13 +1331,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
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO
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
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO
fi
elif [ -n "$vmlinux" ]; then
# look for the symbol
@ -1007,44 +1356,70 @@ check_variant2()
retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux symbols"
else
pstatus red NO
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO
fi
elif grep -q noretpoline_setup "$vmlinux"; then
# if we don't have nm, nevermind, the symbol name is long enough to not have
# any false positive using good old grep directly on the binary
retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux"
else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO
fi
else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN "couldn't find your kernel image or System.map" || pstatus red NO
fi
_info_nol " * Retpoline enabled: "
if [ "$opt_live" = 1 ]; then
# kernel adds this flag when retpoline is supported and enabled,
# regardless of the fact that it's minimal / full and generic / amd
if grep -qw retpoline /proc/cpuinfo; then
pstatus green YES
retpoline_enabled=1
else
pstatus red NO
fi
else
pstatus yellow UNKNOWN "couldn't find your kernel image or System.map"
pstatus blue N/A "can't check this in offline mode"
fi
elif [ "$sys_interface_available" = 0 ]; then
# we have no sysfs but were asked to use it only!
msg="/sys vulnerability interface use forced, but it's not available!"
status=UNK
fi
# if 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
cve='CVE-2017-5715'
if ! 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 ]; then
pvulnstatus CVE-2017-5715 OK "IBRS mitigates the vulnerability"
if [ "$ibrs_enabled" = 1 -o "$ibrs_enabled" = 2 ] && [ "$ibpb_enabled" = 1 ]; then
pvulnstatus $cve OK "IBRS/IBPB are mitigating the vulnerability"
elif [ "$ibrs_enabled" = 1 -o "$ibrs_enabled" = 2 ] && [ "$ibpb_enabled" = -1 ]; then
# IBPB doesn't seem here on this kernel
pvulnstatus $cve OK "IBRS is mitigating the vulnerability"
elif [ "$ibpb_enabled" = 2 ]; then
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 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 VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
else
pvulnstatus CVE-2017-5715 VULN "IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability"
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
}
@ -1060,7 +1435,8 @@ 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
fi
if [ "$opt_sysfs_only" != 1 ]; then
_info_nol "* Kernel supports Page Table Isolation (PTI): "
kpti_support=0
kpti_can_tell=0
@ -1120,24 +1496,25 @@ check_variant3()
# RedHat Backport creates a dedicated file, see https://access.redhat.com/articles/3311301
kpti_enabled=$(cat /sys/kernel/debug/x86/pti_enabled 2>/dev/null)
_debug "kpti_enabled: file /sys/kernel/debug/x86/pti_enabled exists and says: $kpti_enabled"
elif dmesg | grep -Eq "$dmesg_grep"; then
# if we can't find the flag, grep dmesg output
_debug "kpti_enabled: found hint in dmesg: "$(dmesg | grep -E "$dmesg_grep")
fi
if [ -z "$kpti_enabled" ]; then
dmesg_grep "$dmesg_grep"; ret=$?
if [ $ret -eq 0 ]; then
_debug "kpti_enabled: found hint in dmesg: $dmesg_grepped"
kpti_enabled=1
elif [ -r /var/log/dmesg ] && grep -Eq "$dmesg_grep" /var/log/dmesg; then
# if we can't find the flag in dmesg output, grep in /var/log/dmesg when readable
_debug "kpti_enabled: found hint in /var/log/dmesg: "$(grep -E "$dmesg_grep" /var/log/dmesg)
kpti_enabled=1
elif [ -r /var/log/kern.log ] && grep -Eq "$dmesg_grep" /var/log/kern.log; then
# if we can't find the flag in dmesg output, grep in /var/log/kern.log when readable
_debug "kpti_enabled: found hint in /var/log/kern.log: "$(grep -E "$dmesg_grep" /var/log/kern.log)
kpti_enabled=1
else
elif [ $ret -eq 2 ]; then
_debug "kpti_enabled: dmesg truncated"
kpti_enabled=-1
fi
fi
if [ -z "$kpti_enabled" ]; then
_debug "kpti_enabled: couldn't find any hint that PTI is enabled"
kpti_enabled=0
fi
if [ "$kpti_enabled" = 1 ]; then
pstatus green YES
elif [ "$kpti_enabled" = -1 ]; then
pstatus yellow UNKNOWN "dmesg truncated, please reboot and relaunch this script"
else
pstatus red NO
fi
@ -1166,33 +1543,41 @@ check_variant3()
pstatus blue NO 'no security impact but performance will be degraded with PTI'
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
# Test if the current host is a Xen PV Dom0 / DomU
if [ -d "/proc/xen" ]; then
# XXX do we have a better way that relying on dmesg?
dmesg_grep 'Booting paravirtualized kernel on Xen$'; ret=$?
if [ $ret -eq 2 ]; then
_warn "dmesg truncated, Xen detection will be unreliable. Please reboot and relaunch this script"
elif [ $ret -eq 0 ]; then
if [ -e /proc/xen/capabilities ] && grep -q "control_d" /proc/xen/capabilities; then
xen_pv_domo=1
else
xen_pv_domu=1
fi
fi
fi
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): "
if [ "$(uname -m)" = "x86_64" ]; then
# XXX do we have a better way that relying on dmesg?
if dmesg | grep -q 'Booting paravirtualized kernel on Xen$' ; then
pstatus green YES 'Xen PV is not vulnerable'
xen_pv=1
elif [ -r /var/log/dmesg ] && grep -q 'Booting paravirtualized kernel on Xen$' /var/log/dmesg; then
pstatus green YES 'Xen PV is not vulnerable'
xen_pv=1
elif [ -r /var/log/kern.log ] && grep -q 'Booting paravirtualized kernel on Xen$' /var/log/kern.log; then
pstatus green YES 'Xen PV is not vulnerable'
xen_pv=1
# checking whether we're running under Xen PV 64 bits. If yes, we are affected by variant3
# (unless we are a Dom0)
_info_nol "* Running as a Xen PV DomU: "
if [ "$xen_pv_domu" = 1 ]; then
pstatus red YES
else
pstatus blue NO
fi
else
pstatus blue NO
fi
pstatus green NO
fi
fi
# if we have the /sys interface, don't even check is_cpu_vulnerable ourselves, the kernel already does it
cve='CVE-2017-5754'
if [ "$sys_interface_available" = 0 ] && ! is_cpu_vulnerable 3; then
if ! is_cpu_vulnerable 3; 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" ]; then
@ -1200,23 +1585,46 @@ check_variant3()
if [ "$opt_live" = 1 ]; then
if [ "$kpti_enabled" = 1 ]; then
pvulnstatus $cve OK "PTI mitigates the vulnerability"
elif [ "$xen_pv" = 1 ]; then
pvulnstatus $cve OK "Xen PV 64 bits is not vulnerable"
elif [ "$xen_pv_domo" = 1 ]; then
pvulnstatus $cve OK "Xen Dom0s are safe and do not require PTI"
elif [ "$xen_pv_domu" = 1 ]; then
pvulnstatus $cve VULN "Xen PV DomUs are vulnerable and need to be run in HVM, PVHVM or PVH mode"
else
pvulnstatus $cve VULN "PTI is needed to mitigate the vulnerability"
fi
else
if [ "$kpti_support" = 1 ]; then
pvulnstatus $cve OK "offline mode: PTI will mitigate the vulnerability if enabled at runtime"
else
elif [ "$kpti_can_tell" = 1 ]; then
pvulnstatus $cve VULN "PTI is needed to mitigate the vulnerability"
else
pvulnstatus $cve UNK "offline mode: not enough information"
fi
fi
else
if [ "$xen_pv_domo" = 1 ]; then
msg="Xen Dom0s are safe and do not require PTI"
status="OK"
elif [ "$xen_pv_domu" = 1 ]; then
msg="Xen PV DomUs are vulnerable and need to be run in HVM, PVHVM or PVH mode"
status="VULN"
elif [ "$msg" = "Vulnerable" ]; then
msg="PTI is needed to mitigate the vulnerability"
fi
pvulnstatus $cve "$status" "$msg"
fi
# Warn the user about XSA-254 recommended mitigations
if [ "$xen_pv_domo" = 1 ]; then
_warn
_warn "This host is a Xen Dom0. Please make sure that you are running your DomUs"
_warn "in HVM, PVHVM or PVH mode to prevent any guest-to-host / host-to-guest attacks."
_warn
_warn "See https://blog.xenproject.org/2018/01/22/xen-project-spectre-meltdown-faq-jan-22-update/ and XSA-254 for details."
fi
}
check_cpu
# now run the checks the user asked for
if [ "$opt_variant1" = 1 -o "$opt_allvariants" = 1 ]; then
check_variant1
@ -1237,7 +1645,7 @@ _info "A false sense of security is worse than no security at all, see --disclai
umount_debugfs
# cleanup the temp decompressed config
[ -n "$dumped_config" ] && rm -f "$dumped_config"
[ -n "$dumped_config" ] && [ -f "$dumped_config" ] && rm -f "$dumped_config"
if [ "$opt_batch" = 1 -a "$opt_batch_format" = "nrpe" ]; then
if [ ! -z "$nrpe_vuln" ]; then