1
0
mirror of https://github.com/speed47/spectre-meltdown-checker synced 2024-12-22 12:23:36 +01:00

refacto: fix shellcheck warnings for better compat

Now `shellcheck -s sh` no longer shows any warnings.
This should improve compatibility with exotic shells
as long as they're POSIX compliant.
This commit is contained in:
Stéphane Lesimple 2018-01-29 10:29:48 +01:00
parent 7404929661
commit 9b53635eda

View File

@ -12,10 +12,11 @@ VERSION=0.33
show_usage() show_usage()
{ {
# shellcheck disable=SC2086
cat <<EOF cat <<EOF
Usage: Usage:
Live mode: `basename $0` [options] [--live] Live mode: $(basename $0) [options] [--live]
Offline mode: `basename $0` [options] [--kernel <vmlinux_file>] [--config <kernel_config>] [--map <kernel_map_file>] Offline mode: $(basename $0) [options] [--kernel <vmlinux_file>] [--config <kernel_config>] [--map <kernel_map_file>]
Modes: Modes:
Two modes are available. Two modes are available.
@ -102,7 +103,7 @@ nrpe_vuln=""
# find a sane `echo` command # find a sane `echo` command
# we'll try to avoid using shell builtins that might not take options # we'll try to avoid using shell builtins that might not take options
if which echo >/dev/null 2>&1; then if which echo >/dev/null 2>&1; then
echo_cmd=`which echo` echo_cmd=$(which echo)
else else
[ -x /bin/echo ] && echo_cmd=/bin/echo [ -x /bin/echo ] && echo_cmd=/bin/echo
[ -x /system/bin/echo ] && echo_cmd=/system/bin/echo [ -x /system/bin/echo ] && echo_cmd=/system/bin/echo
@ -113,66 +114,70 @@ __echo()
{ {
opt="$1" opt="$1"
shift shift
_msg="$@" _msg="$*"
if [ "$opt_no_color" = 1 ] ; then if [ "$opt_no_color" = 1 ] ; then
# strip ANSI color codes # strip ANSI color codes
_msg=$($echo_cmd -e "$_msg" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g") _msg=$($echo_cmd -e "$_msg" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")
fi fi
# shellcheck disable=SC2086
$echo_cmd $opt -e "$_msg" $echo_cmd $opt -e "$_msg"
} }
_echo() _echo()
{ {
if [ $opt_verbose -ge $1 ]; then if [ "$opt_verbose" -ge "$1" ]; then
shift shift
__echo '' "$@" __echo '' "$*"
fi fi
} }
_echo_nol() _echo_nol()
{ {
if [ $opt_verbose -ge $1 ]; then if [ "$opt_verbose" -ge "$1" ]; then
shift shift
__echo -n "$@" __echo -n "$*"
fi fi
} }
_warn() _warn()
{ {
_echo 0 "\033[31m${@}\033[0m" >&2 _echo 0 "\033[31m$*\033[0m" >&2
} }
_info() _info()
{ {
_echo 1 "$@" _echo 1 "$*"
} }
_info_nol() _info_nol()
{ {
_echo_nol 1 "$@" _echo_nol 1 "$*"
} }
_verbose() _verbose()
{ {
_echo 2 "$@" _echo 2 "$*"
} }
_verbose_nol() _verbose_nol()
{ {
_echo_nol 2 "$@" _echo_nol 2 "$*"
} }
_debug() _debug()
{ {
_echo 3 "\033[34m(debug) $@\033[0m" _echo 3 "\033[34m(debug) $*\033[0m"
} }
is_cpu_vulnerable_cached=0 is_cpu_vulnerable_cached=0
_is_cpu_vulnerable_cached() _is_cpu_vulnerable_cached()
{ {
# shellcheck disable=SC2086
[ "$1" = 1 ] && return $variant1 [ "$1" = 1 ] && return $variant1
# shellcheck disable=SC2086
[ "$1" = 2 ] && return $variant2 [ "$1" = 2 ] && return $variant2
# shellcheck disable=SC2086
[ "$1" = 3 ] && return $variant3 [ "$1" = 3 ] && return $variant3
echo "$0: error: invalid variant '$1' passed to is_cpu_vulnerable()" >&2 echo "$0: error: invalid variant '$1' passed to is_cpu_vulnerable()" >&2
exit 255 exit 255
@ -239,11 +244,11 @@ is_cpu_vulnerable()
for cpupart in $cpupart_list for cpupart in $cpupart_list
do do
i=$(( i + 1 )) i=$(( i + 1 ))
cpuarch=$(echo $cpuarch_list | awk '{ print $'$i' }') cpuarch=$(echo "$cpuarch_list" | awk '{ print $'$i' }')
_debug "checking cpu$i: <$cpupart> <$cpuarch>" _debug "checking cpu$i: <$cpupart> <$cpuarch>"
# some kernels report AArch64 instead of 8 # some kernels report AArch64 instead of 8
[ "$cpuarch" = "AArch64" ] && cpuarch=8 [ "$cpuarch" = "AArch64" ] && cpuarch=8
if [ -n "$cpupart" -a -n "$cpuarch" ]; then if [ -n "$cpupart" ] && [ -n "$cpuarch" ]; then
cpu_friendly_name="ARM v$cpuarch model $cpupart" cpu_friendly_name="ARM v$cpuarch model $cpupart"
# Cortex-R7 and Cortex-R8 are real-time and only used in medical devices or such # 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 # I can't find their CPU part number, but it's probably not that useful anyway
@ -270,7 +275,7 @@ is_cpu_vulnerable()
fi fi
# for variant3, only A75 is vulnerable # for variant3, only A75 is vulnerable
if [ "$cpuarch" = 8 -a "$cpupart" = 0xd0a ]; then if [ "$cpuarch" = 8 ] && [ "$cpupart" = 0xd0a ]; then
_debug "checking cpu$i: arm A75 vulnerable to meltdown" _debug "checking cpu$i: arm A75 vulnerable to meltdown"
variant3=vuln variant3=vuln
else else
@ -327,18 +332,18 @@ parse_opt_file()
while [ -n "$1" ]; do while [ -n "$1" ]; do
if [ "$1" = "--kernel" ]; then if [ "$1" = "--kernel" ]; then
opt_kernel=$(parse_opt_file kernel "$2") opt_kernel=$(parse_opt_file kernel "$2"); ret=$?
[ $? -ne 0 ] && exit 255 [ $ret -ne 0 ] && exit 255
shift 2 shift 2
opt_live=0 opt_live=0
elif [ "$1" = "--config" ]; then elif [ "$1" = "--config" ]; then
opt_config=$(parse_opt_file config "$2") opt_config=$(parse_opt_file config "$2"); ret=$?
[ $? -ne 0 ] && exit 255 [ $ret -ne 0 ] && exit 255
shift 2 shift 2
opt_live=0 opt_live=0
elif [ "$1" = "--map" ]; then elif [ "$1" = "--map" ]; then
opt_map=$(parse_opt_file map "$2") opt_map=$(parse_opt_file map "$2"); ret=$?
[ $? -ne 0 ] && exit 255 [ $ret -ne 0 ] && exit 255
shift 2 shift 2
opt_live=0 opt_live=0
elif [ "$1" = "--live" ]; then elif [ "$1" = "--live" ]; then
@ -374,8 +379,8 @@ while [ -n "$1" ]; do
exit 255 exit 255
;; ;;
esac esac
elif [ "$1" = "-v" -o "$1" = "--verbose" ]; then elif [ "$1" = "-v" ] || [ "$1" = "--verbose" ]; then
opt_verbose=$(expr $opt_verbose + 1) opt_verbose=$(( opt_verbose + 1 ))
shift shift
elif [ "$1" = "--variant" ]; then elif [ "$1" = "--variant" ]; then
if [ -z "$2" ]; then if [ -z "$2" ]; then
@ -392,7 +397,7 @@ while [ -n "$1" ]; do
;; ;;
esac esac
shift 2 shift 2
elif [ "$1" = "-h" -o "$1" = "--help" ]; then elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_header show_header
show_usage show_usage
exit 0 exit 0
@ -414,7 +419,7 @@ done
show_header show_header
if [ "$opt_no_sysfs" = 1 -a "$opt_sysfs_only" = 1 ]; then if [ "$opt_no_sysfs" = 1 ] && [ "$opt_sysfs_only" = 1 ]; then
_warn "Incompatible options specified (--no-sysfs and --sysfs-only), aborting" _warn "Incompatible options specified (--no-sysfs and --sysfs-only), aborting"
exit 255 exit 255
fi fi
@ -456,7 +461,7 @@ pvulnstatus()
VULN) is_vuln="true";; VULN) is_vuln="true";;
OK) is_vuln="false";; OK) is_vuln="false";;
esac esac
json_output="${json_output:-[}{\"NAME\":\""$aka"\",\"CVE\":\""$1"\",\"VULNERABLE\":$is_vuln,\"INFOS\":\""$3"\"}," json_output="${json_output:-[}{\"NAME\":\"$aka\",\"CVE\":\"$1\",\"VULNERABLE\":$is_vuln,\"INFOS\":\"$3\"},"
;; ;;
nrpe) [ "$2" = VULN ] && nrpe_vuln="$nrpe_vuln $1";; nrpe) [ "$2" = VULN ] && nrpe_vuln="$nrpe_vuln $1";;
@ -511,7 +516,7 @@ try_decompress()
# "grep" that report the byte offset of the line instead of the pattern. # "grep" that report the byte offset of the line instead of the pattern.
# Try to find the header ($1) and decompress from here # Try to find the header ($1) and decompress from here
for pos in `tr "$1\n$2" "\n$2=" < "$6" | grep -abo "^$2"` for pos in $(tr "$1\n$2" "\n$2=" < "$6" | grep -abo "^$2")
do do
_debug "try_decompress: magic for $3 found at offset $pos" _debug "try_decompress: magic for $3 found at offset $pos"
if ! which "$3" >/dev/null 2>&1; then if ! which "$3" >/dev/null 2>&1; then
@ -519,7 +524,8 @@ try_decompress()
return 0 return 0
fi fi
pos=${pos%%:*} pos=${pos%%:*}
tail -c+$pos "$6" 2>/dev/null | $3 $4 > $vmlinuxtmp 2>/dev/null # shellcheck disable=SC2086
tail -c+$pos "$6" 2>/dev/null | $3 $4 > "$vmlinuxtmp" 2>/dev/null
if check_vmlinux "$vmlinuxtmp"; then if check_vmlinux "$vmlinuxtmp"; then
vmlinux="$vmlinuxtmp" vmlinux="$vmlinuxtmp"
_debug "try_decompress: decompressed with $3 successfully!" _debug "try_decompress: decompressed with $3 successfully!"
@ -536,7 +542,8 @@ extract_vmlinux()
[ -n "$1" ] || return 1 [ -n "$1" ] || return 1
# Prepare temp files: # Prepare temp files:
vmlinuxtmp="$(mktemp /tmp/vmlinux-XXXXXX)" vmlinuxtmp="$(mktemp /tmp/vmlinux-XXXXXX)"
trap "rm -f $vmlinuxtmp" EXIT # single quotes in trap cmd: will be expanded when signalled
trap 'rm -f $vmlinuxtmp' EXIT INT
# Initial attempt for uncompressed images or objects: # Initial attempt for uncompressed images or objects:
if check_vmlinux "$1"; then if check_vmlinux "$1"; then
@ -692,7 +699,7 @@ is_ucode_blacklisted()
# check for mode selection inconsistency # check for mode selection inconsistency
if [ "$opt_live_explicit" = 1 ]; then if [ "$opt_live_explicit" = 1 ]; then
if [ -n "$opt_kernel" -o -n "$opt_config" -o -n "$opt_map" ]; then if [ -n "$opt_kernel" ] || [ -n "$opt_config" ] || [ -n "$opt_map" ]; then
show_usage show_usage
echo "$0: error: incompatible modes specified, use either --live or --kernel/--config/--map" >&2 echo "$0: error: incompatible modes specified, use either --live or --kernel/--config/--map" >&2
exit 255 exit 255
@ -709,7 +716,7 @@ if [ "$opt_coreos" = 1 ]; then
load_msr load_msr
load_cpuid load_cpuid
mount_debugfs mount_debugfs
toolbox --ephemeral --bind-ro /dev/cpu:/dev/cpu -- sh -c "dnf install -y binutils which && /media/root$PWD/$0 $@ --coreos-within-toolbox" toolbox --ephemeral --bind-ro /dev/cpu:/dev/cpu -- sh -c "dnf install -y binutils which && /media/root$PWD/$0 $* --coreos-within-toolbox"
exitcode=$? exitcode=$?
mount_debugfs mount_debugfs
unload_cpuid unload_cpuid
@ -732,7 +739,7 @@ if [ "$opt_live" = 1 ]; then
_warn _warn
fi fi
_info "Checking for vulnerabilities on current system" _info "Checking for vulnerabilities on current system"
_info "Kernel is \033[35m"$(uname -s) $(uname -r) $(uname -v) $(uname -m)"\033[0m" _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 # call is_cpu_vulnerable to fill the cpu_friendly_name var
is_cpu_vulnerable 0 is_cpu_vulnerable 0
_info "CPU is \033[35m$cpu_friendly_name\033[0m" _info "CPU is \033[35m$cpu_friendly_name\033[0m"
@ -753,42 +760,42 @@ if [ "$opt_live" = 1 ]; then
# if we didn't find a kernel, default to guessing # if we didn't find a kernel, default to guessing
if [ ! -e "$opt_kernel" ]; then if [ ! -e "$opt_kernel" ]; then
# Fedora: # Fedora:
[ -e /lib/modules/$(uname -r)/vmlinuz ] && opt_kernel=/lib/modules/$(uname -r)/vmlinuz [ -e "/lib/modules/$(uname -r)/vmlinuz" ] && opt_kernel="/lib/modules/$(uname -r)/vmlinuz"
# Slackare: # Slackare:
[ -e /boot/vmlinuz ] && opt_kernel=/boot/vmlinuz [ -e "/boot/vmlinuz" ] && opt_kernel="/boot/vmlinuz"
# Arch: # Arch:
[ -e /boot/vmlinuz-linux ] && opt_kernel=/boot/vmlinuz-linux [ -e "/boot/vmlinuz-linux" ] && opt_kernel="/boot/vmlinuz-linux"
# Linux-Libre: # Linux-Libre:
[ -e /boot/vmlinuz-linux-libre ] && opt_kernel=/boot/vmlinuz-linux-libre [ -e "/boot/vmlinuz-linux-libre" ] && opt_kernel="/boot/vmlinuz-linux-libre"
# generic: # generic:
[ -e /boot/vmlinuz-$(uname -r) ] && opt_kernel=/boot/vmlinuz-$(uname -r) [ -e "/boot/vmlinuz-$(uname -r)" ] && opt_kernel="/boot/vmlinuz-$(uname -r)"
[ -e /boot/kernel-$( uname -r) ] && opt_kernel=/boot/kernel-$( uname -r) [ -e "/boot/kernel-$( uname -r)" ] && opt_kernel="/boot/kernel-$( uname -r)"
[ -e /boot/bzImage-$(uname -r) ] && opt_kernel=/boot/bzImage-$(uname -r) [ -e "/boot/bzImage-$(uname -r)" ] && opt_kernel="/boot/bzImage-$(uname -r)"
# Gentoo: # Gentoo:
[ -e /boot/kernel-genkernel-$(uname -m)-$(uname -r) ] && opt_kernel=/boot/kernel-genkernel-$(uname -m)-$(uname -r) [ -e "/boot/kernel-genkernel-$(uname -m)-$(uname -r)" ] && opt_kernel="/boot/kernel-genkernel-$(uname -m)-$(uname -r)"
# NixOS: # NixOS:
[ -e /run/booted-system/kernel ] && opt_kernel=/run/booted-system/kernel [ -e "/run/booted-system/kernel" ] && opt_kernel="/run/booted-system/kernel"
fi fi
# system.map # system.map
if [ -e /proc/kallsyms ] ; then if [ -e /proc/kallsyms ] ; then
opt_map="/proc/kallsyms" opt_map=/proc/kallsyms
elif [ -e /lib/modules/$(uname -r)/System.map ] ; then elif [ -e "/lib/modules/$(uname -r)/System.map" ] ; then
opt_map=/lib/modules/$(uname -r)/System.map opt_map="/lib/modules/$(uname -r)/System.map"
elif [ -e /boot/System.map-$(uname -r) ] ; then elif [ -e "/boot/System.map-$(uname -r)" ] ; then
opt_map=/boot/System.map-$(uname -r) opt_map="/boot/System.map-$(uname -r)"
fi fi
# config # config
if [ -e /proc/config.gz ] ; then if [ -e /proc/config.gz ] ; then
dumped_config="$(mktemp /tmp/config-XXXXXX)" dumped_config="$(mktemp /tmp/config-XXXXXX)"
gunzip -c /proc/config.gz > $dumped_config gunzip -c /proc/config.gz > "$dumped_config"
# dumped_config will be deleted at the end of the script # dumped_config will be deleted at the end of the script
opt_config=$dumped_config opt_config="$dumped_config"
elif [ -e /lib/modules/$(uname -r)/config ]; then elif [ -e "/lib/modules/$(uname -r)/config" ]; then
opt_config=/lib/modules/$(uname -r)/config opt_config="/lib/modules/$(uname -r)/config"
elif [ -e /boot/config-$(uname -r) ]; then elif [ -e "/boot/config-$(uname -r)" ]; then
opt_config=/boot/config-$(uname -r) opt_config="/boot/config-$(uname -r)"
fi fi
else else
_info "Checking for vulnerabilities against specified kernel" _info "Checking for vulnerabilities against specified kernel"
@ -838,7 +845,7 @@ else
_debug "no opt_kernel defined" _debug "no opt_kernel defined"
vmlinux_err="couldn't find your kernel image in /boot, if you used netboot, this is normal" vmlinux_err="couldn't find your kernel image in /boot, if you used netboot, this is normal"
fi fi
if [ -z "$vmlinux" -o ! -r "$vmlinux" ]; then if [ -z "$vmlinux" ] || [ ! -r "$vmlinux" ]; then
[ -z "$vmlinux_err" ] && vmlinux_err="couldn't extract your kernel from $opt_kernel" [ -z "$vmlinux_err" ] && vmlinux_err="couldn't extract your kernel from $opt_kernel"
fi fi
@ -851,7 +858,7 @@ _info
sys_interface_check() sys_interface_check()
{ {
[ "$opt_live" = 1 -a "$opt_no_sysfs" = 0 -a -r "$1" ] || return 1 [ "$opt_live" = 1 ] && [ "$opt_no_sysfs" = 0 ] && [ -r "$1" ] || return 1
_info_nol "* Mitigated according to the /sys interface: " _info_nol "* Mitigated according to the /sys interface: "
if grep -qi '^not affected' "$1"; then if grep -qi '^not affected' "$1"; then
# Not affected # Not affected
@ -893,8 +900,8 @@ check_cpu()
# here we use dd, it's the same as using 'rdmsr 0x48' but without needing the rdmsr tool # 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 # 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 # 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 dd if=/dev/cpu/0/msr of=/dev/null bs=8 count=1 skip=9 2>/dev/null; ret=$?
if [ $? -eq 0 ]; then if [ $ret -eq 0 ]; then
spec_ctrl_msr=1 spec_ctrl_msr=1
pstatus green YES pstatus green YES
else else
@ -915,8 +922,8 @@ check_cpu()
if [ "$opt_verbose" -ge 3 ]; then 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 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: 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 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) _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 fi
# getting high byte of edx on leaf7 of cpuinfo in decimal # 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}') 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}')
@ -957,8 +964,8 @@ check_cpu()
# the new MSR 'PRED_CTRL' is at offset 0x49, write-only # 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 # 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 # 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 $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; ret=$?
if [ $? -eq 0 ]; then if [ $ret -eq 0 ]; then
pstatus green YES pstatus green YES
else else
pstatus red NO pstatus red NO
@ -973,8 +980,8 @@ check_cpu()
if [ "$opt_verbose" -ge 3 ]; then 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 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: 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 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) _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 fi
# getting high byte of edx on leaf7 of cpuinfo in decimal # 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}') 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}')
@ -983,7 +990,6 @@ check_cpu()
_debug "cpuid: ebx_bit12=$ebx_bit12" _debug "cpuid: ebx_bit12=$ebx_bit12"
if [ "$ebx_bit12" -eq 16 ]; then if [ "$ebx_bit12" -eq 16 ]; then
pstatus green YES "IBPB_SUPPORT feature bit" pstatus green YES "IBPB_SUPPORT feature bit"
cpuid_ibpb=1
elif [ "$cpuid_spec_ctrl" = 1 ]; then elif [ "$cpuid_spec_ctrl" = 1 ]; then
pstatus green YES "SPEC_CTRL feature bit" pstatus green YES "SPEC_CTRL feature bit"
else else
@ -1010,8 +1016,8 @@ check_cpu()
if [ "$opt_verbose" -ge 3 ]; then 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 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: 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 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) _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 fi
# getting high byte of edx on leaf7 of cpuinfo in decimal # 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}') 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}')
@ -1020,7 +1026,6 @@ check_cpu()
_debug "cpuid: edx_bit27=$edx_bit27" _debug "cpuid: edx_bit27=$edx_bit27"
if [ "$edx_bit27" -eq 8 ]; then if [ "$edx_bit27" -eq 8 ]; then
pstatus green YES pstatus green YES
cpuid_stibp=1
else else
pstatus red NO pstatus red NO
fi fi
@ -1036,8 +1041,8 @@ check_cpu()
if [ "$opt_verbose" -ge 3 ]; then 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 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: 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 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) _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 fi
# getting high byte of edx on leaf7 of cpuinfo in decimal # 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}') 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}')
@ -1069,10 +1074,10 @@ check_cpu()
# the new MSR 'ARCH_CAPABILITIES' is at offset 0x10a # 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 # 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 # 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}') 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}'); ret=$?
capabilities_rdcl_no=0 capabilities_rdcl_no=0
capabilities_ibrs_all=0 capabilities_ibrs_all=0
if [ $? -eq 0 ]; then if [ $ret -eq 0 ]; then
_debug "capabilities MSR lower byte is $capabilities (decimal)" _debug "capabilities MSR lower byte is $capabilities (decimal)"
[ $(( capabilities & 1 )) -eq 1 ] && capabilities_rdcl_no=1 [ $(( capabilities & 1 )) -eq 1 ] && capabilities_rdcl_no=1
[ $(( capabilities & 2 )) -eq 2 ] && capabilities_ibrs_all=1 [ $(( capabilities & 2 )) -eq 2 ] && capabilities_ibrs_all=1
@ -1241,7 +1246,7 @@ check_variant2()
fi fi
fi fi
fi fi
if [ "$ibrs_supported" != 1 -a -n "$opt_map" ]; then if [ "$ibrs_supported" != 1 ] && [ -n "$opt_map" ]; then
ibrs_can_tell=1 ibrs_can_tell=1
if grep -q spec_ctrl "$opt_map"; then if grep -q spec_ctrl "$opt_map"; then
pstatus green YES pstatus green YES
@ -1269,7 +1274,13 @@ check_variant2()
# 1 is enabled only for kernel space # 1 is enabled only for kernel space
# 2 is enabled for kernel and user space # 2 is enabled for kernel and user space
case "$ibrs_enabled" in case "$ibrs_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;; "")
if [ "$ibrs_supported" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
;;
0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibrs_enabled";; 0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibrs_enabled";;
1 | 2) pstatus green YES;; 1 | 2) pstatus green YES;;
*) pstatus yellow UNKNOWN;; *) pstatus yellow UNKNOWN;;
@ -1286,7 +1297,13 @@ check_variant2()
pstatus blue NO "IBPB used instead of IBRS in all kernel entrypoints" pstatus blue NO "IBPB used instead of IBRS in all kernel entrypoints"
else else
case "$ibrs_enabled" in case "$ibrs_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;; "")
if [ "$ibrs_supported" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
;;
0 | 1) pstatus red NO "echo 2 > $ibrs_knob_dir/ibrs_enabled";; 0 | 1) pstatus red NO "echo 2 > $ibrs_knob_dir/ibrs_enabled";;
2) pstatus green YES;; 2) pstatus green YES;;
*) pstatus yellow UNKNOWN;; *) pstatus yellow UNKNOWN;;
@ -1299,7 +1316,13 @@ check_variant2()
_info_nol " * IBPB enabled: " _info_nol " * IBPB enabled: "
if [ "$opt_live" = 1 ]; then if [ "$opt_live" = 1 ]; then
case "$ibpb_enabled" in case "$ibpb_enabled" in
"") [ "$ibrs_supported" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO;; "")
if [ "$ibrs_supported" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
;;
0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibpb_enabled";; 0) pstatus red NO "echo 1 > $ibrs_knob_dir/ibpb_enabled";;
1) pstatus green YES;; 1) pstatus green YES;;
2) pstatus green YES "IBPB used instead of IBRS in all kernel entrypoints";; 2) pstatus green YES "IBPB used instead of IBRS in all kernel entrypoints";;
@ -1319,7 +1342,8 @@ check_variant2()
if grep -q '^CONFIG_RETPOLINE=y' "$opt_config"; then if grep -q '^CONFIG_RETPOLINE=y' "$opt_config"; then
pstatus green YES pstatus green YES
retpoline=1 retpoline=1
_debug "retpoline: found "$(grep '^CONFIG_RETPOLINE' "$opt_config")" in $opt_config" # shellcheck disable=SC2046
_debug 'retpoline: found '$(grep '^CONFIG_RETPOLINE' "$opt_config")" in $opt_config"
else else
pstatus red NO pstatus red NO
fi fi
@ -1340,7 +1364,11 @@ check_variant2()
retpoline_compiler=1 retpoline_compiler=1
pstatus green YES "kernel reports full retpoline compilation" pstatus green YES "kernel reports full retpoline compilation"
else else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO if [ "$retpoline" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
fi fi
elif [ -n "$opt_map" ]; then elif [ -n "$opt_map" ]; then
# look for the symbol # look for the symbol
@ -1348,7 +1376,11 @@ check_variant2()
retpoline_compiler=1 retpoline_compiler=1
pstatus green YES "noretpoline_setup symbol found in System.map" pstatus green YES "noretpoline_setup symbol found in System.map"
else else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO if [ "$retpoline" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
fi fi
elif [ -n "$vmlinux" ]; then elif [ -n "$vmlinux" ]; then
# look for the symbol # look for the symbol
@ -1358,7 +1390,11 @@ check_variant2()
retpoline_compiler=1 retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux symbols" pstatus green YES "noretpoline_setup found in vmlinux symbols"
else else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO if [ "$retpoline" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
fi fi
elif grep -q noretpoline_setup "$vmlinux"; then elif grep -q noretpoline_setup "$vmlinux"; then
# if we don't have nm, nevermind, the symbol name is long enough to not have # if we don't have nm, nevermind, the symbol name is long enough to not have
@ -1366,10 +1402,18 @@ check_variant2()
retpoline_compiler=1 retpoline_compiler=1
pstatus green YES "noretpoline_setup found in vmlinux" pstatus green YES "noretpoline_setup found in vmlinux"
else else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN || pstatus red NO if [ "$retpoline" = 1 ]; then
pstatus yellow UNKNOWN
else
pstatus red NO
fi
fi fi
else else
[ "$retpoline" = 1 ] && pstatus yellow UNKNOWN "couldn't find your kernel image or System.map" || pstatus red NO if [ "$retpoline" = 1 ]; then
pstatus yellow UNKNOWN "couldn't find your kernel image or System.map"
else
pstatus red NO
fi
fi fi
_info_nol " * Retpoline enabled: " _info_nol " * Retpoline enabled: "
@ -1378,7 +1422,6 @@ check_variant2()
# regardless of the fact that it's minimal / full and generic / amd # regardless of the fact that it's minimal / full and generic / amd
if grep -qw retpoline /proc/cpuinfo; then if grep -qw retpoline /proc/cpuinfo; then
pstatus green YES pstatus green YES
retpoline_enabled=1
else else
pstatus red NO pstatus red NO
fi fi
@ -1397,12 +1440,12 @@ check_variant2()
pvulnstatus $cve OK "your CPU vendor reported your CPU model as not vulnerable" pvulnstatus $cve OK "your CPU vendor reported your CPU model as not vulnerable"
elif [ -z "$msg" ]; then elif [ -z "$msg" ]; then
# if msg is empty, sysfs check didn't fill it, rely on our own test # if msg is empty, sysfs check didn't fill it, rely on our own test
if [ "$retpoline" = 1 -a "$retpoline_compiler" = 1 ]; then if [ "$retpoline" = 1 ] && [ "$retpoline_compiler" = 1 ]; then
pvulnstatus $cve OK "retpoline mitigates the vulnerability" pvulnstatus $cve OK "retpoline mitigates the vulnerability"
elif [ "$opt_live" = 1 ]; then elif [ "$opt_live" = 1 ]; then
if [ "$ibrs_enabled" = 1 -o "$ibrs_enabled" = 2 ] && [ "$ibpb_enabled" = 1 ]; then if ( [ "$ibrs_enabled" = 1 ] || [ "$ibrs_enabled" = 2 ] ) && [ "$ibpb_enabled" = 1 ]; then
pvulnstatus $cve OK "IBRS/IBPB are mitigating the vulnerability" pvulnstatus $cve OK "IBRS/IBPB are mitigating the vulnerability"
elif [ "$ibrs_enabled" = 1 -o "$ibrs_enabled" = 2 ] && [ "$ibpb_enabled" = -1 ]; then elif ( [ "$ibrs_enabled" = 1 ] || [ "$ibrs_enabled" = 2 ] ) && [ "$ibpb_enabled" = -1 ]; then
# IBPB doesn't seem here on this kernel # IBPB doesn't seem here on this kernel
pvulnstatus $cve OK "IBRS is mitigating the vulnerability" pvulnstatus $cve OK "IBRS is mitigating the vulnerability"
elif [ "$ibpb_enabled" = 2 ]; then elif [ "$ibpb_enabled" = 2 ]; then
@ -1445,11 +1488,12 @@ check_variant3()
if [ -n "$opt_config" ]; then if [ -n "$opt_config" ]; then
kpti_can_tell=1 kpti_can_tell=1
if grep -Eq '^(CONFIG_PAGE_TABLE_ISOLATION|CONFIG_KAISER)=y' "$opt_config"; then if grep -Eq '^(CONFIG_PAGE_TABLE_ISOLATION|CONFIG_KAISER)=y' "$opt_config"; then
_debug "kpti_support: found option "$(grep -E '^(CONFIG_PAGE_TABLE_ISOLATION|CONFIG_KAISER)=y' "$opt_config")" in $opt_config" # shellcheck disable=SC2046
_debug 'kpti_support: found option '$(grep -E '^(CONFIG_PAGE_TABLE_ISOLATION|CONFIG_KAISER)=y' "$opt_config")" in $opt_config"
kpti_support=1 kpti_support=1
fi fi
fi fi
if [ "$kpti_support" = 0 -a -n "$opt_map" ]; then if [ "$kpti_support" = 0 ] && [ -n "$opt_map" ]; then
# it's not an elif: some backports don't have the PTI config but still include the patch # it's not an elif: some backports don't have the PTI config but still include the patch
# so we try to find an exported symbol that is part of the PTI patch in System.map # so we try to find an exported symbol that is part of the PTI patch in System.map
kpti_can_tell=1 kpti_can_tell=1
@ -1458,7 +1502,7 @@ check_variant3()
kpti_support=1 kpti_support=1
fi fi
fi fi
if [ "$kpti_support" = 0 -a -n "$vmlinux" ]; then if [ "$kpti_support" = 0 ] && [ -n "$vmlinux" ]; then
# same as above but in case we don't have System.map and only vmlinux, look for the # same as above but in case we don't have System.map and only vmlinux, look for the
# nopti option that is part of the patch (kernel command line option) # nopti option that is part of the patch (kernel command line option)
kpti_can_tell=1 kpti_can_tell=1
@ -1628,15 +1672,15 @@ check_variant3()
check_cpu check_cpu
# now run the checks the user asked for # now run the checks the user asked for
if [ "$opt_variant1" = 1 -o "$opt_allvariants" = 1 ]; then if [ "$opt_variant1" = 1 ] || [ "$opt_allvariants" = 1 ]; then
check_variant1 check_variant1
_info _info
fi fi
if [ "$opt_variant2" = 1 -o "$opt_allvariants" = 1 ]; then if [ "$opt_variant2" = 1 ] || [ "$opt_allvariants" = 1 ]; then
check_variant2 check_variant2
_info _info
fi fi
if [ "$opt_variant3" = 1 -o "$opt_allvariants" = 1 ]; then if [ "$opt_variant3" = 1 ] || [ "$opt_allvariants" = 1 ]; then
check_variant3 check_variant3
_info _info
fi fi
@ -1649,7 +1693,7 @@ umount_debugfs
# cleanup the temp decompressed config # cleanup the temp decompressed config
[ -n "$dumped_config" ] && [ -f "$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 [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "nrpe" ]; then
if [ ! -z "$nrpe_vuln" ]; then if [ ! -z "$nrpe_vuln" ]; then
echo "Vulnerable:$nrpe_vuln" echo "Vulnerable:$nrpe_vuln"
else else
@ -1657,8 +1701,8 @@ if [ "$opt_batch" = 1 -a "$opt_batch_format" = "nrpe" ]; then
fi fi
fi fi
if [ "$opt_batch" = 1 -a "$opt_batch_format" = "json" ]; then if [ "$opt_batch" = 1 ] && [ "$opt_batch_format" = "json" ]; then
_echo 0 ${json_output%?}']' _echo 0 "${json_output%?}]"
fi fi
# exit with the proper exit code # exit with the proper exit code