mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-04-07 09:13:20 +02:00
186 lines
10 KiB
Bash
186 lines
10 KiB
Bash
# vim: set ts=4 sw=4 sts=4 et:
|
|
###############################
|
|
# CVE-2018-3639, Variant 4, SSB, Speculative Store Bypass
|
|
|
|
check_CVE_2018_3639() {
|
|
check_cve 'CVE-2018-3639'
|
|
}
|
|
|
|
check_CVE_2018_3639_linux() {
|
|
local status sys_interface_available msg kernel_ssb kernel_ssbd_enabled mitigated_processes
|
|
status=UNK
|
|
sys_interface_available=0
|
|
msg=''
|
|
if sys_interface_check "$VULN_SYSFS_BASE/spec_store_bypass"; then
|
|
# this kernel has the /sys interface, trust it over everything
|
|
sys_interface_available=1
|
|
status=$ret_sys_interface_check_status
|
|
fi
|
|
if [ "$opt_sysfs_only" != 1 ]; then
|
|
pr_info_nol "* Kernel supports disabling speculative store bypass (SSB): "
|
|
if [ "$opt_live" = 1 ]; then
|
|
if grep -Eq 'Speculation.?Store.?Bypass:' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssb="found in $g_procfs/self/status"
|
|
pr_debug "found Speculation.Store.Bypass: in $g_procfs/self/status"
|
|
fi
|
|
fi
|
|
# arm64 kernels can have cpu_show_spec_store_bypass with ARM64_SSBD, so exclude them
|
|
if [ -z "$kernel_ssb" ] && [ -n "$g_kernel" ] && ! grep -q 'arm64_sys_' "$g_kernel"; then
|
|
kernel_ssb=$("${opt_arch_prefix}strings" "$g_kernel" | grep spec_store_bypass | head -n1)
|
|
[ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in kernel"
|
|
fi
|
|
# arm64 kernels can have cpu_show_spec_store_bypass with ARM64_SSBD, so exclude them
|
|
if [ -z "$kernel_ssb" ] && [ -n "$opt_map" ] && ! grep -q 'arm64_sys_' "$opt_map"; then
|
|
kernel_ssb=$(grep spec_store_bypass "$opt_map" | awk '{print $3}' | head -n1)
|
|
[ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in System.map"
|
|
fi
|
|
# arm64 only:
|
|
if [ -z "$kernel_ssb" ] && [ -n "$opt_map" ]; then
|
|
kernel_ssb=$(grep -w cpu_enable_ssbs "$opt_map" | awk '{print $3}' | head -n1)
|
|
[ -n "$kernel_ssb" ] && kernel_ssb="found $kernel_ssb in System.map"
|
|
fi
|
|
if [ -z "$kernel_ssb" ] && [ -n "$opt_config" ]; then
|
|
kernel_ssb=$(grep -w 'CONFIG_ARM64_SSBD=y' "$opt_config")
|
|
[ -n "$kernel_ssb" ] && kernel_ssb="CONFIG_ARM64_SSBD enabled in kconfig"
|
|
fi
|
|
if [ -z "$kernel_ssb" ] && [ -n "$g_kernel" ]; then
|
|
# this string only appears in kernel if CONFIG_ARM64_SSBD is set
|
|
kernel_ssb=$(grep -w "Speculative Store Bypassing Safe (SSBS)" "$g_kernel")
|
|
[ -n "$kernel_ssb" ] && kernel_ssb="found 'Speculative Store Bypassing Safe (SSBS)' in kernel"
|
|
fi
|
|
# /arm64 only
|
|
|
|
if [ -n "$kernel_ssb" ]; then
|
|
pstatus green YES "$kernel_ssb"
|
|
else
|
|
pstatus yellow NO
|
|
fi
|
|
|
|
kernel_ssbd_enabled=-1
|
|
if [ "$opt_live" = 1 ]; then
|
|
# https://elixir.bootlin.com/linux/v5.0/source/fs/proc/array.c#L340
|
|
pr_info_nol "* SSB mitigation is enabled and active: "
|
|
if grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+thread' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssbd_enabled=1
|
|
pstatus green YES "per-thread through prctl"
|
|
elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+globally mitigated' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssbd_enabled=2
|
|
pstatus green YES "global"
|
|
elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+vulnerable' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssbd_enabled=0
|
|
pstatus yellow NO
|
|
elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+not vulnerable' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssbd_enabled=-2
|
|
pstatus blue NO "not vulnerable"
|
|
elif grep -Eq 'Speculation.?Store.?Bypass:[[:space:]]+unknown' "$g_procfs/self/status" 2>/dev/null; then
|
|
kernel_ssbd_enabled=0
|
|
pstatus blue NO
|
|
else
|
|
pstatus blue UNKNOWN "unknown value: $(grep -E 'Speculation.?Store.?Bypass:' "$g_procfs/self/status" 2>/dev/null | cut -d: -f2-)"
|
|
fi
|
|
|
|
if [ "$kernel_ssbd_enabled" = 1 ]; then
|
|
pr_info_nol "* SSB mitigation currently active for selected processes: "
|
|
# silence grep's stderr here to avoid ENOENT errors from processes that have exited since the shell's expansion of the *
|
|
mitigated_processes=$(find /proc -mindepth 2 -maxdepth 2 -type f -name status -print0 2>/dev/null |
|
|
xargs -r0 grep -El 'Speculation.?Store.?Bypass:[[:space:]]+thread (force )?mitigated' 2>/dev/null |
|
|
sed s/status/exe/ | xargs -r -n1 readlink -f 2>/dev/null | xargs -r -n1 basename | sort -u | tr "\n" " " | sed 's/ $//')
|
|
if [ -n "$mitigated_processes" ]; then
|
|
pstatus green YES "$mitigated_processes"
|
|
else
|
|
pstatus yellow NO "no process found using SSB mitigation through prctl"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
elif [ "$sys_interface_available" = 0 ]; then
|
|
# we have no sysfs but were asked to use it only!
|
|
msg="/sys vulnerability interface use forced, but it's not available!"
|
|
status=UNK
|
|
fi
|
|
|
|
if ! is_cpu_affected "$cve"; then
|
|
# override status & msg in case CPU is not vulnerable after all
|
|
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
|
elif [ -z "$msg" ] || [ "$msg" = "Vulnerable" ]; then
|
|
# if msg is empty, sysfs check didn't fill it, rely on our own test
|
|
if [ -n "$cap_ssbd" ]; then
|
|
if [ -n "$kernel_ssb" ]; then
|
|
if [ "$opt_live" = 1 ]; then
|
|
if [ "$kernel_ssbd_enabled" -gt 0 ]; then
|
|
pvulnstatus "$cve" OK "your CPU and kernel both support SSBD and mitigation is enabled"
|
|
else
|
|
pvulnstatus "$cve" VULN "your CPU and kernel both support SSBD but the mitigation is not active"
|
|
fi
|
|
else
|
|
pvulnstatus "$cve" OK "your system provides the necessary tools for software mitigation"
|
|
fi
|
|
else
|
|
pvulnstatus "$cve" VULN "your kernel needs to be updated"
|
|
explain "You have a recent-enough CPU microcode but your kernel is too old to use the new features exported by your CPU's microcode. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources."
|
|
fi
|
|
else
|
|
if [ -n "$kernel_ssb" ]; then
|
|
pvulnstatus "$cve" VULN "Your CPU doesn't support SSBD"
|
|
explain "Your kernel is recent enough to use the CPU microcode features for mitigation, but your CPU microcode doesn't actually provide the necessary features for the kernel to use. The microcode of your CPU hence needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)."
|
|
else
|
|
pvulnstatus "$cve" VULN "Neither your CPU nor your kernel support SSBD"
|
|
explain "Both your CPU microcode and your kernel are lacking support for mitigation. If you're using a distro kernel, upgrade your distro to get the latest kernel available. Otherwise, recompile the kernel from recent-enough sources. The microcode of your CPU also needs to be upgraded. This is usually done at boot time by your kernel (the upgrade is not persistent across reboots which is why it's done at each boot). If you're using a distro, make sure you are up to date, as microcode updates are usually shipped alongside with the distro kernel. Availability of a microcode update for you CPU model depends on your CPU vendor. You can usually find out online if a microcode update is available for your CPU by searching for your CPUID (indicated in the Hardware Check section)."
|
|
fi
|
|
fi
|
|
else
|
|
pvulnstatus "$cve" "$status" "$msg"
|
|
fi
|
|
}
|
|
|
|
check_CVE_2018_3639_bsd() {
|
|
local kernel_ssb ssb_enabled ssb_active
|
|
pr_info_nol "* Kernel supports speculation store bypass: "
|
|
if sysctl hw.spec_store_bypass_disable >/dev/null 2>&1; then
|
|
kernel_ssb=1
|
|
pstatus green YES
|
|
else
|
|
kernel_ssb=0
|
|
pstatus yellow NO
|
|
fi
|
|
|
|
pr_info_nol "* Speculation store bypass is administratively enabled: "
|
|
ssb_enabled=$(sysctl -n hw.spec_store_bypass_disable 2>/dev/null)
|
|
pr_debug "hw.spec_store_bypass_disable=$ssb_enabled"
|
|
case "$ssb_enabled" in
|
|
0) pstatus yellow NO "disabled" ;;
|
|
1) pstatus green YES "enabled" ;;
|
|
2) pstatus green YES "auto mode" ;;
|
|
*) pstatus yellow NO "unavailable" ;;
|
|
esac
|
|
|
|
pr_info_nol "* Speculation store bypass is currently active: "
|
|
ssb_active=$(sysctl -n hw.spec_store_bypass_disable_active 2>/dev/null)
|
|
pr_debug "hw.spec_store_bypass_disable_active=$ssb_active"
|
|
case "$ssb_active" in
|
|
1) pstatus green YES ;;
|
|
*) pstatus yellow NO ;;
|
|
esac
|
|
|
|
if ! is_cpu_affected "$cve"; then
|
|
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
|
else
|
|
if [ "$ssb_active" = 1 ]; then
|
|
pvulnstatus "$cve" OK "SSBD mitigates the vulnerability"
|
|
elif [ -n "$cap_ssbd" ]; then
|
|
if [ "$kernel_ssb" = 1 ]; then
|
|
pvulnstatus "$cve" VULN "you need to enable SSBD through sysctl to mitigate the vulnerability"
|
|
explain "To enable SSBD right now, you can run \`sysctl hw.spec_store_bypass_disable=2'. To make this change persistent across reboots, you can add 'sysctl hw.spec_store_bypass_disable=2' to /etc/sysctl.conf."
|
|
else
|
|
pvulnstatus "$cve" VULN "your kernel needs to be updated"
|
|
fi
|
|
else
|
|
if [ "$kernel_ssb" = 1 ]; then
|
|
pvulnstatus "$cve" VULN "Your CPU doesn't support SSBD"
|
|
else
|
|
pvulnstatus "$cve" VULN "Neither your CPU nor your kernel support SSBD"
|
|
fi
|
|
fi
|
|
fi
|
|
}
|