mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2024-12-26 20:10:31 +01:00
feat(bsd): add retpoline detection for BSD
This commit is contained in:
parent
f3883a37a0
commit
f5269a362a
@ -17,8 +17,8 @@ exit_cleanup()
|
|||||||
{
|
{
|
||||||
# cleanup the temp decompressed config & kernel image
|
# cleanup the temp decompressed config & kernel image
|
||||||
[ -n "$dumped_config" ] && [ -f "$dumped_config" ] && rm -f "$dumped_config"
|
[ -n "$dumped_config" ] && [ -f "$dumped_config" ] && rm -f "$dumped_config"
|
||||||
[ -n "$vmlinuxtmp" ] && [ -f "$vmlinuxtmp" ] && rm -f "$vmlinuxtmp"
|
[ -n "$kerneltmp" ] && [ -f "$kerneltmp" ] && rm -f "$kerneltmp"
|
||||||
[ -n "$vmlinuxtmp2" ] && [ -f "$vmlinuxtmp2" ] && rm -f "$vmlinuxtmp2"
|
[ -n "$kerneltmp2" ] && [ -f "$kerneltmp2" ] && rm -f "$kerneltmp2"
|
||||||
[ "$mounted_debugfs" = 1 ] && umount /sys/kernel/debug 2>/dev/null
|
[ "$mounted_debugfs" = 1 ] && umount /sys/kernel/debug 2>/dev/null
|
||||||
[ "$mounted_procfs" = 1 ] && umount "$procfs" 2>/dev/null
|
[ "$mounted_procfs" = 1 ] && umount "$procfs" 2>/dev/null
|
||||||
[ "$insmod_cpuid" = 1 ] && rmmod cpuid 2>/dev/null
|
[ "$insmod_cpuid" = 1 ] && rmmod cpuid 2>/dev/null
|
||||||
@ -32,7 +32,7 @@ show_usage()
|
|||||||
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 <kernel_file>] [--config <kernel_config>] [--map <kernel_map_file>]
|
||||||
|
|
||||||
Modes:
|
Modes:
|
||||||
Two modes are available.
|
Two modes are available.
|
||||||
@ -41,7 +41,7 @@ show_usage()
|
|||||||
To run under this mode, just start the script without any option (you can also use --live explicitly)
|
To run under this mode, just start the script without any option (you can also use --live explicitly)
|
||||||
|
|
||||||
Second mode is the "offline" mode, where you can inspect a non-running kernel.
|
Second mode is the "offline" mode, where you can inspect a non-running kernel.
|
||||||
You'll need to specify the location of the vmlinux file, config and System.map files:
|
You'll need to specify the location of the kernel file, config and System.map files:
|
||||||
|
|
||||||
--kernel kernel_file specify a (possibly compressed) Linux or BSD kernel file
|
--kernel kernel_file specify a (possibly compressed) Linux or BSD kernel file
|
||||||
--config kernel_config specify a kernel config file (Linux only)
|
--config kernel_config specify a kernel config file (Linux only)
|
||||||
@ -591,9 +591,9 @@ pvulnstatus()
|
|||||||
# Licensed under the GNU General Public License, version 2 (GPLv2).
|
# Licensed under the GNU General Public License, version 2 (GPLv2).
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
vmlinux=''
|
kernel=''
|
||||||
vmlinux_err=''
|
kernel_err=''
|
||||||
check_vmlinux()
|
check_kernel()
|
||||||
{
|
{
|
||||||
_file="$1"
|
_file="$1"
|
||||||
_desperate_mode="$2"
|
_desperate_mode="$2"
|
||||||
@ -601,25 +601,25 @@ check_vmlinux()
|
|||||||
# a damaged ELF file and validate it, check for stderr warnings too
|
# a damaged ELF file and validate it, check for stderr warnings too
|
||||||
_readelf_warnings=$("${opt_arch_prefix}readelf" -S "$_file" 2>&1 >/dev/null | tr "\n" "/"); ret=$?
|
_readelf_warnings=$("${opt_arch_prefix}readelf" -S "$_file" 2>&1 >/dev/null | tr "\n" "/"); ret=$?
|
||||||
_readelf_sections=$("${opt_arch_prefix}readelf" -S "$_file" 2>/dev/null | grep -c -e data -e text -e init)
|
_readelf_sections=$("${opt_arch_prefix}readelf" -S "$_file" 2>/dev/null | grep -c -e data -e text -e init)
|
||||||
_vmlinux_size=$(stat -c %s "$_file" 2>/dev/null || stat -f %z "$_file" 2>/dev/null || echo 10000)
|
_kernel_size=$(stat -c %s "$_file" 2>/dev/null || stat -f %z "$_file" 2>/dev/null || echo 10000)
|
||||||
_debug "check_vmlinux: ret=$? size=$_vmlinux_size sections=$_readelf_sections warnings=$_readelf_warnings"
|
_debug "check_kernel: ret=$? size=$_kernel_size sections=$_readelf_sections warnings=$_readelf_warnings"
|
||||||
if [ -n "$_desperate_mode" ]; then
|
if [ -n "$_desperate_mode" ]; then
|
||||||
if "${opt_arch_prefix}strings" "$_file" | grep -Eq '^Linux version '; then
|
if "${opt_arch_prefix}strings" "$_file" | grep -Eq '^Linux version '; then
|
||||||
_debug "check_vmlinux (desperate): ... matched!"
|
_debug "check_kernel (desperate): ... matched!"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
_debug "check_vmlinux (desperate): ... invalid"
|
_debug "check_kernel (desperate): ... invalid"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ $ret -eq 0 ] && [ -z "$_readelf_warnings" ] && [ "$_readelf_sections" -gt 0 ]; then
|
if [ $ret -eq 0 ] && [ -z "$_readelf_warnings" ] && [ "$_readelf_sections" -gt 0 ]; then
|
||||||
if [ "$_vmlinux_size" -ge 100000 ]; then
|
if [ "$_kernel_size" -ge 100000 ]; then
|
||||||
_debug "check_vmlinux: ... file is valid"
|
_debug "check_kernel: ... file is valid"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
_debug "check_vmlinux: ... file seems valid but is too small, ignoring"
|
_debug "check_kernel: ... file seems valid but is too small, ignoring"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_debug "check_vmlinux: ... file is invalid"
|
_debug "check_kernel: ... file is invalid"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@ -636,25 +636,25 @@ try_decompress()
|
|||||||
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
|
||||||
vmlinux_err="missing '$3' tool, please install it, usually it's in the '$5' package"
|
kernel_err="missing '$3' tool, please install it, usually it's in the '$5' package"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
pos=${pos%%:*}
|
pos=${pos%%:*}
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
tail -c+$pos "$6" 2>/dev/null | $3 $4 > "$vmlinuxtmp" 2>/dev/null; ret=$?
|
tail -c+$pos "$6" 2>/dev/null | $3 $4 > "$kerneltmp" 2>/dev/null; ret=$?
|
||||||
if [ ! -s "$vmlinuxtmp" ]; then
|
if [ ! -s "$kerneltmp" ]; then
|
||||||
# don't rely on $ret, sometimes it's != 0 but worked
|
# don't rely on $ret, sometimes it's != 0 but worked
|
||||||
# (e.g. gunzip ret=2 just means there was trailing garbage)
|
# (e.g. gunzip ret=2 just means there was trailing garbage)
|
||||||
_debug "try_decompress: decompression with $3 failed (err=$ret)"
|
_debug "try_decompress: decompression with $3 failed (err=$ret)"
|
||||||
elif check_vmlinux "$vmlinuxtmp" "$7"; then
|
elif check_kernel "$kerneltmp" "$7"; then
|
||||||
vmlinux="$vmlinuxtmp"
|
kernel="$kerneltmp"
|
||||||
_debug "try_decompress: decompressed with $3 successfully!"
|
_debug "try_decompress: decompressed with $3 successfully!"
|
||||||
return 0
|
return 0
|
||||||
elif [ "$3" != "cat" ]; then
|
elif [ "$3" != "cat" ]; then
|
||||||
_debug "try_decompress: decompression with $3 worked but result is not a kernel, trying with an offset"
|
_debug "try_decompress: decompression with $3 worked but result is not a kernel, trying with an offset"
|
||||||
[ -z "$vmlinuxtmp2" ] && vmlinuxtmp2=$(mktemp /tmp/vmlinux-XXXXXX)
|
[ -z "$kerneltmp2" ] && kerneltmp2=$(mktemp /tmp/kernel-XXXXXX)
|
||||||
cat "$vmlinuxtmp" > "$vmlinuxtmp2"
|
cat "$kerneltmp" > "$kerneltmp2"
|
||||||
try_decompress '\177ELF' xxy 'cat' '' cat "$vmlinuxtmp2" && return 0
|
try_decompress '\177ELF' xxy 'cat' '' cat "$kerneltmp2" && return 0
|
||||||
else
|
else
|
||||||
_debug "try_decompress: decompression with $3 worked but result is not a kernel"
|
_debug "try_decompress: decompression with $3 worked but result is not a kernel"
|
||||||
fi
|
fi
|
||||||
@ -662,16 +662,16 @@ try_decompress()
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_vmlinux()
|
extract_kernel()
|
||||||
{
|
{
|
||||||
[ -n "$1" ] || return 1
|
[ -n "$1" ] || return 1
|
||||||
# Prepare temp files:
|
# Prepare temp files:
|
||||||
vmlinuxtmp="$(mktemp /tmp/vmlinux-XXXXXX)"
|
kerneltmp="$(mktemp /tmp/kernel-XXXXXX)"
|
||||||
|
|
||||||
# Initial attempt for uncompressed images or objects:
|
# Initial attempt for uncompressed images or objects:
|
||||||
if check_vmlinux "$1"; then
|
if check_kernel "$1"; then
|
||||||
cat "$1" > "$vmlinuxtmp"
|
cat "$1" > "$kerneltmp"
|
||||||
vmlinux=$vmlinuxtmp
|
kernel=$kerneltmp
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1148,9 +1148,9 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$opt_kernel" ]; then
|
if [ -n "$opt_kernel" ]; then
|
||||||
_verbose "Will use vmlinux image \033[35m$opt_kernel\033[0m"
|
_verbose "Will use kernel image \033[35m$opt_kernel\033[0m"
|
||||||
else
|
else
|
||||||
_verbose "Will use no vmlinux image (accuracy might be reduced)"
|
_verbose "Will use no kernel image (accuracy might be reduced)"
|
||||||
bad_accuracy=1
|
bad_accuracy=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1185,39 +1185,39 @@ fi
|
|||||||
if [ -e "$opt_kernel" ]; then
|
if [ -e "$opt_kernel" ]; then
|
||||||
if ! which "${opt_arch_prefix}readelf" >/dev/null 2>&1; then
|
if ! which "${opt_arch_prefix}readelf" >/dev/null 2>&1; then
|
||||||
_debug "readelf not found"
|
_debug "readelf not found"
|
||||||
vmlinux_err="missing '${opt_arch_prefix}readelf' tool, please install it, usually it's in the 'binutils' package"
|
kernel_err="missing '${opt_arch_prefix}readelf' tool, please install it, usually it's in the 'binutils' package"
|
||||||
elif [ "$opt_sysfs_only" = 1 ]; then
|
elif [ "$opt_sysfs_only" = 1 ]; then
|
||||||
vmlinux_err='kernel image decompression skipped'
|
kernel_err='kernel image decompression skipped'
|
||||||
else
|
else
|
||||||
extract_vmlinux "$opt_kernel"
|
extract_kernel "$opt_kernel"
|
||||||
fi
|
fi
|
||||||
else
|
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"
|
kernel_err="couldn't find your kernel image in /boot, if you used netboot, this is normal"
|
||||||
fi
|
fi
|
||||||
if [ -z "$vmlinux" ] || [ ! -r "$vmlinux" ]; then
|
if [ -z "$kernel" ] || [ ! -r "$kernel" ]; then
|
||||||
[ -z "$vmlinux_err" ] && vmlinux_err="couldn't extract your kernel from $opt_kernel"
|
[ -z "$kernel_err" ] && kernel_err="couldn't extract your kernel from $opt_kernel"
|
||||||
else
|
else
|
||||||
# vanilla kernels have with ^Linux version
|
# vanilla kernels have with ^Linux version
|
||||||
# also try harder with some kernels (such as Red Hat) that don't have ^Linux version before their version string
|
# also try harder with some kernels (such as Red Hat) that don't have ^Linux version before their version string
|
||||||
# and check for FreeBSD
|
# and check for FreeBSD
|
||||||
vmlinux_version=$("${opt_arch_prefix}strings" "$vmlinux" 2>/dev/null | grep -E \
|
kernel_version=$("${opt_arch_prefix}strings" "$kernel" 2>/dev/null | grep -E \
|
||||||
-e '^Linux version ' \
|
-e '^Linux version ' \
|
||||||
-e '^[[:alnum:]][^[:space:]]+ \([^[:space:]]+\) #[0-9]+ .+ (19|20)[0-9][0-9]$' \
|
-e '^[[:alnum:]][^[:space:]]+ \([^[:space:]]+\) #[0-9]+ .+ (19|20)[0-9][0-9]$' \
|
||||||
-e '^FreeBSD [0-9]' | head -1)
|
-e '^FreeBSD [0-9]' | head -1)
|
||||||
if [ -z "$vmlinux_version" ]; then
|
if [ -z "$kernel_version" ]; then
|
||||||
# try even harder with some kernels (such as ARM) that split the release (uname -r) and version (uname -v) in 2 adjacent strings
|
# try even harder with some kernels (such as ARM) that split the release (uname -r) and version (uname -v) in 2 adjacent strings
|
||||||
vmlinux_version=$("${opt_arch_prefix}strings" "$vmlinux" 2>/dev/null | grep -E -B1 '^#[0-9]+ .+ (19|20)[0-9][0-9]$' | tr "\n" " ")
|
kernel_version=$("${opt_arch_prefix}strings" "$kernel" 2>/dev/null | grep -E -B1 '^#[0-9]+ .+ (19|20)[0-9][0-9]$' | tr "\n" " ")
|
||||||
fi
|
fi
|
||||||
if [ -n "$vmlinux_version" ]; then
|
if [ -n "$kernel_version" ]; then
|
||||||
# in live mode, check if the img we found is the correct one
|
# in live mode, check if the img we found is the correct one
|
||||||
if [ "$opt_live" = 1 ]; then
|
if [ "$opt_live" = 1 ]; then
|
||||||
_verbose "Kernel image is \033[35m$vmlinux_version"
|
_verbose "Kernel image is \033[35m$kernel_version"
|
||||||
if ! echo "$vmlinux_version" | grep -qF "$(uname -r)"; then
|
if ! echo "$kernel_version" | grep -qF "$(uname -r)"; then
|
||||||
_warn "Possible disrepancy between your running kernel '$(uname -r)' and the image '$vmlinux_version' we found ($opt_kernel), results might be incorrect"
|
_warn "Possible disrepancy between your running kernel '$(uname -r)' and the image '$kernel_version' we found ($opt_kernel), results might be incorrect"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_info "Kernel image is \033[35m$vmlinux_version"
|
_info "Kernel image is \033[35m$kernel_version"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
_verbose "Kernel image version is unknown"
|
_verbose "Kernel image version is unknown"
|
||||||
@ -1594,17 +1594,17 @@ check_redhat_canonical_spectre()
|
|||||||
|
|
||||||
if ! which "${opt_arch_prefix}strings" >/dev/null 2>&1; then
|
if ! which "${opt_arch_prefix}strings" >/dev/null 2>&1; then
|
||||||
redhat_canonical_spectre=-1
|
redhat_canonical_spectre=-1
|
||||||
elif [ -n "$vmlinux_err" ]; then
|
elif [ -n "$kernel_err" ]; then
|
||||||
redhat_canonical_spectre=-2
|
redhat_canonical_spectre=-2
|
||||||
else
|
else
|
||||||
# Red Hat / Ubuntu specific variant1 patch is difficult to detect,
|
# Red Hat / Ubuntu specific variant1 patch is difficult to detect,
|
||||||
# let's use the two same tricks than the official Red Hat detection script uses:
|
# let's use the two same tricks than the official Red Hat detection script uses:
|
||||||
if "${opt_arch_prefix}strings" "$vmlinux" | grep -qw noibrs && "${opt_arch_prefix}strings" "$vmlinux" | grep -qw noibpb; then
|
if "${opt_arch_prefix}strings" "$kernel" | grep -qw noibrs && "${opt_arch_prefix}strings" "$kernel" | grep -qw noibpb; then
|
||||||
# 1) detect their specific variant2 patch. If it's present, it means
|
# 1) detect their specific variant2 patch. If it's present, it means
|
||||||
# that the variant1 patch is also present (both were merged at the same time)
|
# that the variant1 patch is also present (both were merged at the same time)
|
||||||
_debug "found redhat/canonical version of the variant2 patch (implies variant1)"
|
_debug "found redhat/canonical version of the variant2 patch (implies variant1)"
|
||||||
redhat_canonical_spectre=1
|
redhat_canonical_spectre=1
|
||||||
elif "${opt_arch_prefix}strings" "$vmlinux" | grep -q 'x86/pti:'; then
|
elif "${opt_arch_prefix}strings" "$kernel" | grep -q 'x86/pti:'; then
|
||||||
# 2) detect their specific variant3 patch. If it's present, but the variant2
|
# 2) detect their specific variant3 patch. If it's present, but the variant2
|
||||||
# is not, it means that only variant1 is present in addition to variant3
|
# is not, it means that only variant1 is present in addition to variant3
|
||||||
_debug "found redhat/canonical version of the variant3 patch (implies variant1 but not variant2)"
|
_debug "found redhat/canonical version of the variant3 patch (implies variant1 but not variant2)"
|
||||||
@ -1656,17 +1656,17 @@ check_variant1_linux()
|
|||||||
#ASM_STAC
|
#ASM_STAC
|
||||||
# x86 64bits: jae(0x0f 0x83 0x?? 0x?? 0x?? 0x??) sbb(0x48 0x19 0xd2) and(0x48 0x21 0xd0)
|
# 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)
|
# x86 32bits: cmp(0x3b 0x82 0x?? 0x?? 0x00 0x00) jae(0x73 0x??) sbb(0x19 0xd2) and(0x21 0xd0)
|
||||||
if [ -n "$vmlinux_err" ]; then
|
if [ -n "$kernel_err" ]; then
|
||||||
pstatus yellow UNKNOWN "couldn't check ($vmlinux_err)"
|
pstatus yellow UNKNOWN "couldn't check ($kernel_err)"
|
||||||
elif ! which perl >/dev/null 2>&1; then
|
elif ! which perl >/dev/null 2>&1; then
|
||||||
pstatus yellow UNKNOWN "missing 'perl' binary, please install it"
|
pstatus yellow UNKNOWN "missing 'perl' binary, please install it"
|
||||||
else
|
else
|
||||||
perl -ne '/\x0f\x83....\x48\x19\xd2\x48\x21\xd0/ and $found++; END { exit($found) }' "$vmlinux"; ret=$?
|
perl -ne '/\x0f\x83....\x48\x19\xd2\x48\x21\xd0/ and $found++; END { exit($found) }' "$kernel"; ret=$?
|
||||||
if [ $ret -gt 0 ]; then
|
if [ $ret -gt 0 ]; then
|
||||||
pstatus green YES "$ret occurence(s) found of 64 bits array_index_mask_nospec()"
|
pstatus green YES "$ret occurence(s) found of 64 bits array_index_mask_nospec()"
|
||||||
v1_mask_nospec=1
|
v1_mask_nospec=1
|
||||||
else
|
else
|
||||||
perl -ne '/\x3b\x82..\x00\x00\x73.\x19\xd2\x21\xd0/ and $found++; END { exit($found) }' "$vmlinux"; ret=$?
|
perl -ne '/\x3b\x82..\x00\x00\x73.\x19\xd2\x21\xd0/ and $found++; END { exit($found) }' "$kernel"; ret=$?
|
||||||
if [ $ret -gt 0 ]; then
|
if [ $ret -gt 0 ]; then
|
||||||
pstatus green YES "$ret occurence(s) found of 32 bits array_index_mask_nospec()"
|
pstatus green YES "$ret occurence(s) found of 32 bits array_index_mask_nospec()"
|
||||||
v1_mask_nospec=1
|
v1_mask_nospec=1
|
||||||
@ -1681,7 +1681,7 @@ check_variant1_linux()
|
|||||||
if [ "$redhat_canonical_spectre" = -1 ]; then
|
if [ "$redhat_canonical_spectre" = -1 ]; then
|
||||||
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}strings' tool, please install it, usually it's in the binutils package"
|
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}strings' tool, please install it, usually it's in the binutils package"
|
||||||
elif [ "$redhat_canonical_spectre" = -2 ]; then
|
elif [ "$redhat_canonical_spectre" = -2 ]; then
|
||||||
pstatus yellow UNKNOWN "couldn't check ($vmlinux_err)"
|
pstatus yellow UNKNOWN "couldn't check ($kernel_err)"
|
||||||
elif [ "$redhat_canonical_spectre" = 1 ]; then
|
elif [ "$redhat_canonical_spectre" = 1 ]; then
|
||||||
pstatus green YES
|
pstatus green YES
|
||||||
elif [ "$redhat_canonical_spectre" = 2 ]; then
|
elif [ "$redhat_canonical_spectre" = 2 ]; then
|
||||||
@ -1694,8 +1694,8 @@ check_variant1_linux()
|
|||||||
# this is a slow heuristic and we don't need it if we already know the kernel is patched
|
# 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
|
# but still show it in verbose mode
|
||||||
_info_nol "* Checking count of LFENCE instructions following a jump in kernel... "
|
_info_nol "* Checking count of LFENCE instructions following a jump in kernel... "
|
||||||
if [ -n "$vmlinux_err" ]; then
|
if [ -n "$kernel_err" ]; then
|
||||||
pstatus yellow UNKNOWN "couldn't check ($vmlinux_err)"
|
pstatus yellow UNKNOWN "couldn't check ($kernel_err)"
|
||||||
else
|
else
|
||||||
if ! which "${opt_arch_prefix}objdump" >/dev/null 2>&1; then
|
if ! which "${opt_arch_prefix}objdump" >/dev/null 2>&1; then
|
||||||
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}objdump' tool, please install it, usually it's in the binutils package"
|
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}objdump' tool, please install it, usually it's in the binutils package"
|
||||||
@ -1707,7 +1707,7 @@ check_variant1_linux()
|
|||||||
# so let's push the threshold to 70.
|
# so let's push the threshold to 70.
|
||||||
# v0.33+: now only count lfence opcodes after a jump, way less error-prone
|
# v0.33+: now only count lfence opcodes after a jump, way less error-prone
|
||||||
# non patched kernel have between 0 and 20 matches, patched ones have at least 40-45
|
# non patched kernel have between 0 and 20 matches, patched ones have at least 40-45
|
||||||
nb_lfence=$("${opt_arch_prefix}objdump" -d "$vmlinux" 2>/dev/null | grep -w -B1 lfence | grep -Ewc 'jmp|jne|je')
|
nb_lfence=$("${opt_arch_prefix}objdump" -d "$kernel" 2>/dev/null | grep -w -B1 lfence | grep -Ewc 'jmp|jne|je')
|
||||||
if [ "$nb_lfence" -lt 30 ]; then
|
if [ "$nb_lfence" -lt 30 ]; then
|
||||||
pstatus yellow NO "only $nb_lfence jump-then-lfence instructions found, should be >= 30 (heuristic)"
|
pstatus yellow NO "only $nb_lfence jump-then-lfence instructions found, should be >= 30 (heuristic)"
|
||||||
else
|
else
|
||||||
@ -1737,7 +1737,7 @@ check_variant1_linux()
|
|||||||
pvulnstatus $cve OK "Kernel source has been patched to mitigate the vulnerability (Red Hat/Ubuntu patch)"
|
pvulnstatus $cve OK "Kernel source has been patched to mitigate the vulnerability (Red Hat/Ubuntu patch)"
|
||||||
elif [ "$v1_lfence" = 1 ]; then
|
elif [ "$v1_lfence" = 1 ]; then
|
||||||
pvulnstatus $cve OK "Kernel source has PROBABLY been patched to mitigate the vulnerability (jump-then-lfence instructions heuristic)"
|
pvulnstatus $cve OK "Kernel source has PROBABLY been patched to mitigate the vulnerability (jump-then-lfence instructions heuristic)"
|
||||||
elif [ "$vmlinux_err" ]; then
|
elif [ "$kernel_err" ]; then
|
||||||
pvulnstatus $cve UNK "Couldn't find kernel image or tools missing to execute the checks"
|
pvulnstatus $cve UNK "Couldn't find kernel image or tools missing to execute the checks"
|
||||||
else
|
else
|
||||||
pvulnstatus $cve VULN "Kernel source needs to be patched to mitigate the vulnerability"
|
pvulnstatus $cve VULN "Kernel source needs to be patched to mitigate the vulnerability"
|
||||||
@ -1984,13 +1984,13 @@ check_variant2_linux()
|
|||||||
pstatus yellow NO
|
pstatus yellow NO
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
elif [ -n "$vmlinux" ]; then
|
elif [ -n "$kernel" ]; then
|
||||||
# look for the symbol
|
# look for the symbol
|
||||||
if which "${opt_arch_prefix}nm" >/dev/null 2>&1; then
|
if which "${opt_arch_prefix}nm" >/dev/null 2>&1; then
|
||||||
# the proper way: use nm and look for the symbol
|
# the proper way: use nm and look for the symbol
|
||||||
if "${opt_arch_prefix}nm" "$vmlinux" 2>/dev/null | grep -qw 'noretpoline_setup'; then
|
if "${opt_arch_prefix}nm" "$kernel" 2>/dev/null | grep -qw 'noretpoline_setup'; then
|
||||||
retpoline_compiler=1
|
retpoline_compiler=1
|
||||||
pstatus green YES "noretpoline_setup found in vmlinux symbols"
|
pstatus green YES "noretpoline_setup found in kernel symbols"
|
||||||
else
|
else
|
||||||
if [ "$retpoline" = 1 ]; then
|
if [ "$retpoline" = 1 ]; then
|
||||||
pstatus yellow UNKNOWN
|
pstatus yellow UNKNOWN
|
||||||
@ -1998,11 +1998,11 @@ check_variant2_linux()
|
|||||||
pstatus yellow NO
|
pstatus yellow NO
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
elif grep -q noretpoline_setup "$vmlinux"; then
|
elif grep -q noretpoline_setup "$kernel"; 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
|
||||||
# any false positive using good old grep directly on the binary
|
# any false positive using good old grep directly on the binary
|
||||||
retpoline_compiler=1
|
retpoline_compiler=1
|
||||||
pstatus green YES "noretpoline_setup found in vmlinux"
|
pstatus green YES "noretpoline_setup found in kernel"
|
||||||
else
|
else
|
||||||
if [ "$retpoline" = 1 ]; then
|
if [ "$retpoline" = 1 ]; then
|
||||||
pstatus yellow UNKNOWN
|
pstatus yellow UNKNOWN
|
||||||
@ -2061,6 +2061,7 @@ check_variant2_linux()
|
|||||||
|
|
||||||
check_variant2_bsd()
|
check_variant2_bsd()
|
||||||
{
|
{
|
||||||
|
_info "* Mitigation 1"
|
||||||
_info_nol " * Kernel supports IBRS: "
|
_info_nol " * Kernel supports IBRS: "
|
||||||
ibrs_disabled=$(sysctl -n hw.ibrs_disable 2>/dev/null)
|
ibrs_disabled=$(sysctl -n hw.ibrs_disable 2>/dev/null)
|
||||||
if [ -z "$ibrs_disabled" ]; then
|
if [ -z "$ibrs_disabled" ]; then
|
||||||
@ -2077,10 +2078,30 @@ check_variant2_bsd()
|
|||||||
pstatus yellow NO
|
pstatus yellow NO
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_info "* Mitigation 2"
|
||||||
|
_info_nol " * Kernel compiled with RETPOLINE: "
|
||||||
|
if [ -n "$kernel_err" ]; then
|
||||||
|
pstatus yellow UNKNOWN "couldn't check ($kernel_err)"
|
||||||
|
else
|
||||||
|
if ! which "${opt_arch_prefix}readelf" >/dev/null 2>&1; then
|
||||||
|
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}readelf' tool, please install it, usually it's in the binutils package"
|
||||||
|
else
|
||||||
|
nb_thunks=$("${opt_arch_prefix}readelf" -s "$kernel" | grep -c -e __llvm_retpoline_ -e __llvm_external_retpoline_ -e __x86_indirect_thunk_)
|
||||||
|
if [ "$nb_thunks" -gt 0 ]; then
|
||||||
|
retpoline=1
|
||||||
|
pstatus green YES "found $nb_thunks thunk(s)"
|
||||||
|
else
|
||||||
|
pstatus yellow NO
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cve='CVE-2017-5715'
|
cve='CVE-2017-5715'
|
||||||
if ! is_cpu_vulnerable 2; then
|
if ! is_cpu_vulnerable 2; then
|
||||||
# override status & msg in case CPU is not vulnerable after all
|
# override status & msg in case CPU is not vulnerable after all
|
||||||
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 [ "$retpoline" = 1 ]; then
|
||||||
|
pvulnstatus $cve OK "Retpoline mitigates the vulnerability"
|
||||||
elif [ "$ibrs_active" = 1 ]; then
|
elif [ "$ibrs_active" = 1 ]; then
|
||||||
pvulnstatus $cve OK "IBRS mitigates the vulnerability"
|
pvulnstatus $cve OK "IBRS mitigates the vulnerability"
|
||||||
elif [ "$ibrs_disabled" = 0 ]; then
|
elif [ "$ibrs_disabled" = 0 ]; then
|
||||||
@ -2136,15 +2157,15 @@ check_variant3_linux()
|
|||||||
kpti_support=1
|
kpti_support=1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$kpti_support" = 0 ] && [ -n "$vmlinux" ]; then
|
if [ "$kpti_support" = 0 ] && [ -n "$kernel" ]; 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 kernel, 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
|
||||||
if ! which "${opt_arch_prefix}strings" >/dev/null 2>&1; then
|
if ! which "${opt_arch_prefix}strings" >/dev/null 2>&1; then
|
||||||
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}strings' tool, please install it, usually it's in the binutils package"
|
pstatus yellow UNKNOWN "missing '${opt_arch_prefix}strings' tool, please install it, usually it's in the binutils package"
|
||||||
else
|
else
|
||||||
if "${opt_arch_prefix}strings" "$vmlinux" | grep -qw nopti; then
|
if "${opt_arch_prefix}strings" "$kernel" | grep -qw nopti; then
|
||||||
_debug "kpti_support: found nopti string in $vmlinux"
|
_debug "kpti_support: found nopti string in $kernel"
|
||||||
kpti_support=1
|
kpti_support=1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user