Files
spectre-meltdown-checker/src/vulns/CVE-2018-3646.sh
2026-03-30 20:04:16 +02:00

215 lines
9.2 KiB
Bash

# vim: set ts=4 sw=4 sts=4 et:
# CVE-2018-3646 Foreshadow-NG VMM (L1 terminal fault VMM) - entry point
check_CVE_2018_3646() {
check_cve 'CVE-2018-3646'
}
# CVE-2018-3646 Foreshadow-NG VMM (L1 terminal fault VMM) - Linux mitigation check
check_CVE_2018_3646_linux() {
local status sys_interface_available msg l1d_mode ept_disabled l1d_kernel l1d_kernel_err l1d_xen_hardware l1d_xen_hypervisor l1d_xen_pv_domU smt_enabled
status=UNK
sys_interface_available=0
msg=''
if sys_interface_check "$VULN_SYSFS_BASE/l1tf" '.*' quiet; then
# this kernel has the /sys interface, trust it over everything
sys_interface_available=1
fi
l1d_mode=-1
if [ "$opt_sysfs_only" != 1 ]; then
check_has_vmm
pr_info "* Mitigation 1 (KVM)"
pr_info_nol " * EPT is disabled: "
ept_disabled=-1
if [ "$opt_live" = 1 ]; then
if ! [ -r "$SYS_MODULE_BASE/kvm_intel/parameters/ept" ]; then
pstatus blue N/A "the kvm_intel module is not loaded"
elif [ "$(cat "$SYS_MODULE_BASE/kvm_intel/parameters/ept")" = N ]; then
pstatus green YES
ept_disabled=1
else
pstatus yellow NO
fi
else
pstatus blue N/A "not testable in offline mode"
fi
pr_info "* Mitigation 2"
pr_info_nol " * L1D flush is supported by kernel: "
if [ "$opt_live" = 1 ] && grep -qw flush_l1d "$g_procfs/cpuinfo"; then
l1d_kernel="found flush_l1d in $g_procfs/cpuinfo"
fi
if [ -z "$l1d_kernel" ]; then
if ! command -v "${opt_arch_prefix}strings" >/dev/null 2>&1; then
l1d_kernel_err="missing '${opt_arch_prefix}strings' tool, please install it, usually it's in the binutils package"
elif [ -n "$g_kernel_err" ]; then
l1d_kernel_err="$g_kernel_err"
elif "${opt_arch_prefix}strings" "$g_kernel" | grep -qw flush_l1d; then
l1d_kernel='found flush_l1d in kernel image'
fi
fi
if [ -n "$l1d_kernel" ]; then
pstatus green YES "$l1d_kernel"
elif [ -n "$l1d_kernel_err" ]; then
pstatus yellow UNKNOWN "$l1d_kernel_err"
else
pstatus yellow NO
fi
pr_info_nol " * L1D flush enabled: "
if [ "$opt_live" = 1 ]; then
if [ -n "$ret_sys_interface_check_fullmsg" ]; then
# vanilla: VMX: $l1dstatus, SMT $smtstatus
# Red Hat: VMX: SMT $smtstatus, L1D $l1dstatus
# $l1dstatus is one of (auto|vulnerable|conditional cache flushes|cache flushes|EPT disabled|flush not necessary)
# $smtstatus is one of (vulnerable|disabled)
# can also just be "Not affected"
if echo "$ret_sys_interface_check_fullmsg" | grep -Eq -e 'Not affected' -e '(VMX:|L1D) (EPT disabled|vulnerable|flush not necessary)'; then
l1d_mode=0
pstatus yellow NO
elif echo "$ret_sys_interface_check_fullmsg" | grep -Eq '(VMX:|L1D) conditional cache flushes'; then
l1d_mode=1
pstatus green YES "conditional flushes"
elif echo "$ret_sys_interface_check_fullmsg" | grep -Eq '(VMX:|L1D) cache flushes'; then
l1d_mode=2
pstatus green YES "unconditional flushes"
else
if is_xen_dom0; then
l1d_xen_hardware=$(xl dmesg 2>/dev/null | grep 'Hardware features:' | grep 'L1D_FLUSH' | head -n1)
l1d_xen_hypervisor=$(xl dmesg 2>/dev/null | grep 'Xen settings:' | grep 'L1D_FLUSH' | head -n1)
l1d_xen_pv_domU=$(xl dmesg 2>/dev/null | grep 'PV L1TF shadowing:' | grep 'DomU enabled' | head -n1)
if [ -n "$l1d_xen_hardware" ] && [ -n "$l1d_xen_hypervisor" ] && [ -n "$l1d_xen_pv_domU" ]; then
l1d_mode=5
pstatus green YES "for XEN guests"
elif [ -n "$l1d_xen_hardware" ] && [ -n "$l1d_xen_hypervisor" ]; then
l1d_mode=4
pstatus yellow YES "for XEN guests (HVM only)"
elif [ -n "$l1d_xen_pv_domU" ]; then
l1d_mode=3
pstatus yellow YES "for XEN guests (PV only)"
else
l1d_mode=0
pstatus yellow NO "for XEN guests"
fi
else
l1d_mode=-1
pstatus yellow UNKNOWN "unrecognized mode"
fi
fi
else
l1d_mode=-1
pstatus yellow UNKNOWN "can't find or read $VULN_SYSFS_BASE/l1tf"
fi
else
l1d_mode=-1
pstatus blue N/A "not testable in offline mode"
fi
pr_info_nol " * Hardware-backed L1D flush supported: "
if [ "$opt_live" = 1 ]; then
if grep -qw flush_l1d "$g_procfs/cpuinfo" || [ -n "$l1d_xen_hardware" ]; then
pstatus green YES "performance impact of the mitigation will be greatly reduced"
else
pstatus blue NO "flush will be done in software, this is slower"
fi
else
pstatus blue N/A "not testable in offline mode"
fi
pr_info_nol " * Hyper-Threading (SMT) is enabled: "
is_cpu_smt_enabled
smt_enabled=$?
if [ "$smt_enabled" = 0 ]; then
pstatus yellow YES
elif [ "$smt_enabled" = 1 ]; then
pstatus green NO
else
pstatus yellow UNKNOWN
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
l1d_mode=-1
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 [ "$ret_sys_interface_check_fullmsg" = "Not affected" ]; then
# just in case a very recent kernel knows better than we do
pvulnstatus "$cve" OK "your kernel reported your CPU model as not affected"
elif [ "$g_has_vmm" = 0 ]; then
pvulnstatus "$cve" OK "this system is not running a hypervisor"
else
if [ "$ept_disabled" = 1 ]; then
pvulnstatus "$cve" OK "EPT is disabled which mitigates the vulnerability"
elif [ "$opt_paranoid" = 0 ]; then
if [ "$l1d_mode" -ge 1 ]; then
pvulnstatus "$cve" OK "L1D flushing is enabled and mitigates the vulnerability"
else
pvulnstatus "$cve" VULN "disable EPT or enable L1D flushing to mitigate the vulnerability"
fi
else
if [ "$l1d_mode" -ge 2 ]; then
if [ "$smt_enabled" = 1 ]; then
pvulnstatus "$cve" OK "L1D unconditional flushing and Hyper-Threading disabled are mitigating the vulnerability"
else
pvulnstatus "$cve" VULN "Hyper-Threading must be disabled to fully mitigate the vulnerability"
fi
else
if [ "$smt_enabled" = 1 ]; then
pvulnstatus "$cve" VULN "L1D unconditional flushing should be enabled to fully mitigate the vulnerability"
else
pvulnstatus "$cve" VULN "enable L1D unconditional flushing and disable Hyper-Threading to fully mitigate the vulnerability"
fi
fi
fi
if [ "$l1d_mode" -gt 3 ]; then
pr_warn
pr_warn "This host is a Xen Dom0. Please make sure that you are running your DomUs"
pr_warn "with a kernel which contains CVE-2018-3646 mitigations."
pr_warn
pr_warn "See https://www.suse.com/support/kb/doc/?id=7023078 and XSA-273 for details."
fi
fi
}
# CVE-2018-3646 Foreshadow-NG VMM (L1 terminal fault VMM) - BSD mitigation check
check_CVE_2018_3646_bsd() {
local kernel_l1d_supported kernel_l1d_enabled
pr_info_nol "* Kernel supports L1D flushing: "
if sysctl hw.vmm.vmx.l1d_flush >/dev/null 2>&1; then
pstatus green YES
kernel_l1d_supported=1
else
pstatus yellow NO
kernel_l1d_supported=0
fi
pr_info_nol "* L1D flushing is enabled: "
kernel_l1d_enabled=$(sysctl -n hw.vmm.vmx.l1d_flush 2>/dev/null)
case "$kernel_l1d_enabled" in
0) pstatus yellow NO ;;
1) pstatus green YES ;;
"") pstatus yellow NO ;;
*) pstatus yellow UNKNOWN ;;
esac
if ! is_cpu_affected "$cve"; then
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
else
if [ "$kernel_l1d_enabled" = 1 ]; then
pvulnstatus "$cve" OK "L1D flushing mitigates the vulnerability"
elif [ "$kernel_l1d_supported" = 1 ]; then
pvulnstatus "$cve" VULN "L1D flushing is supported by your kernel but is disabled"
else
pvulnstatus "$cve" VULN "your kernel needs to be updated"
fi
fi
}