mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-08-15 16:25:36 +02:00
b8b2f8377b
Inside a Xen PVH domU (and any guest where the kernel sets
X86_FEATURE_HYPERVISOR), the kernel appends "; SMT Host state unknown"
to the MDS/MMIO sysfs vuln string: the host controls SMT scheduling and
the guest genuinely can't see it. The "SMT is either mitigated or
disabled" check only matched 'SMT (disabled|mitigated)', so this read as
"not mitigated" and --paranoid flipped the verdict to a misleading
VULN "you must disable SMT (Hyper-Threading)".
Make *_smt_mitigated a tri-state: 1 (disabled/mitigated), 0 (vulnerable),
and 2 (host state unknown). In paranoid mode, when the in-guest
mitigation is active but SMT host state is unknown, report UNK with an
explanation that cross-thread protection depends on the hypervisor host's
SMT/core-scheduling config, instead of VULN. PV DomUs (kernel reports
"SMT vulnerable", no HYPERVISOR bit) are unchanged and still flagged.
(cherry picked from commit 1e33f40f0a)
158 lines
7.0 KiB
Bash
158 lines
7.0 KiB
Bash
# vim: set ts=4 sw=4 sts=4 et:
|
|
###############################
|
|
# CVE-2019-11135, TAA, ZombieLoad V2, TSX Asynchronous Abort
|
|
|
|
check_CVE_2019_11135() {
|
|
check_cve 'CVE-2019-11135'
|
|
}
|
|
|
|
check_CVE_2019_11135_linux() {
|
|
local status sys_interface_available msg kernel_taa kernel_taa_err
|
|
status=UNK
|
|
sys_interface_available=0
|
|
msg=''
|
|
if sys_interface_check "$VULN_SYSFS_BASE/tsx_async_abort"; 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 "* TAA mitigation is supported by kernel: "
|
|
kernel_taa=''
|
|
if [ -n "$g_kernel_err" ]; then
|
|
kernel_taa_err="$g_kernel_err"
|
|
elif is_x86_kernel && grep -q 'tsx_async_abort' "$g_kernel"; then
|
|
kernel_taa="found tsx_async_abort in kernel image"
|
|
fi
|
|
if [ -n "$kernel_taa" ]; then
|
|
pstatus green YES "$kernel_taa"
|
|
elif [ -n "$kernel_taa_err" ]; then
|
|
pstatus yellow UNKNOWN "$kernel_taa_err"
|
|
else
|
|
pstatus yellow NO
|
|
fi
|
|
|
|
pr_info_nol "* TAA mitigation enabled and active: "
|
|
if [ "$g_mode" = live ]; then
|
|
if [ -n "$ret_sys_interface_check_fullmsg" ]; then
|
|
if echo "$ret_sys_interface_check_fullmsg" | grep -qE '^Mitigation'; then
|
|
pstatus green YES "$ret_sys_interface_check_fullmsg"
|
|
else
|
|
pstatus yellow NO
|
|
fi
|
|
else
|
|
pstatus yellow NO "tsx_async_abort not found in sysfs hierarchy"
|
|
fi
|
|
else
|
|
pstatus blue N/A "not testable in no-runtime 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 ! 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" ]; then
|
|
# if msg is empty, sysfs check didn't fill it, rely on our own test
|
|
if [ "$g_mode" = live ]; then
|
|
# if we're in live mode and $msg is empty, sysfs file is not there so kernel is too old
|
|
pvulnstatus "$cve" VULN "Your kernel doesn't support TAA mitigation, update it"
|
|
else
|
|
if [ -n "$kernel_taa" ]; then
|
|
pvulnstatus "$cve" OK "Your kernel supports TAA mitigation"
|
|
else
|
|
pvulnstatus "$cve" VULN "Your kernel doesn't support TAA mitigation, update it"
|
|
fi
|
|
fi
|
|
else
|
|
if [ "$opt_paranoid" = 1 ]; then
|
|
# in paranoid mode, TSX or SMT enabled are not OK, even if TAA is mitigated
|
|
# first check sysfs, then fall back to MSR-based detection for older kernels
|
|
# that may not report TSX as disabled even when microcode has done so
|
|
tsx_disabled=0
|
|
if echo "$ret_sys_interface_check_fullmsg" | grep -qF 'TSX disabled'; then
|
|
tsx_disabled=1
|
|
elif [ "$cap_tsx_ctrl_rtm_disable" = 1 ] && [ "$cap_tsx_ctrl_cpuid_clear" = 1 ]; then
|
|
# TSX disabled via IA32_TSX_CTRL MSR (0x122)
|
|
tsx_disabled=1
|
|
elif [ "$cap_tsx_force_abort_rtm_disable" = 1 ] && [ "$cap_tsx_force_abort_cpuid_clear" = 1 ]; then
|
|
# TSX disabled via IA32_TSX_FORCE_ABORT MSR (0x10F), for older Skylake-era CPUs
|
|
tsx_disabled=1
|
|
fi
|
|
if [ "$tsx_disabled" = 0 ]; then
|
|
pvulnstatus "$cve" VULN "TSX must be disabled for full mitigation"
|
|
elif echo "$ret_sys_interface_check_fullmsg" | grep -qF 'SMT vulnerable'; then
|
|
pvulnstatus "$cve" VULN "SMT (HyperThreading) must be disabled for full mitigation"
|
|
elif echo "$ret_sys_interface_check_fullmsg" | grep -qF 'SMT Host state unknown'; then
|
|
# The kernel appends "SMT Host state unknown" when running under a
|
|
# hypervisor (X86_FEATURE_HYPERVISOR): the host controls SMT
|
|
# scheduling, so it can't be determined from inside the guest (#343).
|
|
pvulnstatus "$cve" UNK "TAA is mitigated and TSX is disabled, but SMT (Hyper-Threading) cross-thread protection can't be verified from inside a VM guest: it depends on the hypervisor host's SMT/core-scheduling configuration"
|
|
else
|
|
pvulnstatus "$cve" "$status" "$msg"
|
|
fi
|
|
else
|
|
pvulnstatus "$cve" "$status" "$msg"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_CVE_2019_11135_bsd() {
|
|
local taa_enable taa_state mds_disable kernel_taa kernel_mds
|
|
pr_info_nol "* Kernel supports TAA mitigation (machdep.mitigations.taa.enable): "
|
|
taa_enable=$(sysctl -n machdep.mitigations.taa.enable 2>/dev/null)
|
|
if [ -n "$taa_enable" ]; then
|
|
kernel_taa=1
|
|
case "$taa_enable" in
|
|
0) pstatus yellow YES "disabled" ;;
|
|
1) pstatus green YES "TSX disabled via MSR" ;;
|
|
2) pstatus green YES "VERW mitigation" ;;
|
|
3) pstatus green YES "auto" ;;
|
|
*) pstatus yellow YES "unknown value: $taa_enable" ;;
|
|
esac
|
|
else
|
|
kernel_taa=0
|
|
pstatus yellow NO
|
|
fi
|
|
|
|
pr_info_nol "* TAA mitigation state: "
|
|
taa_state=$(sysctl -n machdep.mitigations.taa.state 2>/dev/null)
|
|
if [ -n "$taa_state" ]; then
|
|
if echo "$taa_state" | grep -qi 'not.affected\|mitigation'; then
|
|
pstatus green YES "$taa_state"
|
|
else
|
|
pstatus yellow NO "$taa_state"
|
|
fi
|
|
else
|
|
# fallback: TAA is also mitigated by MDS VERW if enabled
|
|
mds_disable=$(sysctl -n hw.mds_disable 2>/dev/null)
|
|
if [ -z "$mds_disable" ]; then
|
|
mds_disable=$(sysctl -n machdep.mitigations.mds.disable 2>/dev/null)
|
|
fi
|
|
if [ -n "$mds_disable" ] && [ "$mds_disable" != 0 ]; then
|
|
kernel_mds=1
|
|
pstatus green YES "MDS VERW mitigation active (also covers TAA)"
|
|
else
|
|
kernel_mds=0
|
|
pstatus yellow NO "no TAA or MDS sysctl found"
|
|
fi
|
|
fi
|
|
|
|
if ! is_cpu_affected "$cve"; then
|
|
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
|
|
elif [ "$kernel_taa" = 1 ] && [ "$taa_enable" != 0 ]; then
|
|
pvulnstatus "$cve" OK "TAA mitigation is enabled"
|
|
elif [ "$kernel_mds" = 1 ]; then
|
|
pvulnstatus "$cve" OK "MDS VERW mitigation is active and also covers TAA"
|
|
elif [ "$kernel_taa" = 1 ] && [ "$taa_enable" = 0 ]; then
|
|
pvulnstatus "$cve" VULN "TAA mitigation is supported but disabled"
|
|
explain "To enable TAA mitigation, run \`sysctl machdep.mitigations.taa.enable=3' for auto mode.\n " \
|
|
"To make this persistent, add 'machdep.mitigations.taa.enable=3' to /etc/sysctl.conf."
|
|
else
|
|
pvulnstatus "$cve" VULN "your kernel doesn't support TAA mitigation, update it"
|
|
fi
|
|
}
|