mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-06-04 13:43:05 +02:00
hw: detect VM guest via hypervisor CPUID flag, warn on unreliable microcode
Addresses issue #336: when running inside a VM (KVM, VMware, ESXi, Hyper-V, VirtualBox), the hypervisor can present a fake CPUID and microcode version to the guest, making the microcode up-to-date check meaningless or misleading. Changes: - Add is_running_as_guest() to 370_hw_vmm.sh: detects VM guest status by checking for the 'hypervisor' CPUID flag in /proc/cpuinfo, which is exposed by KVM, VMware, Hyper-V, VirtualBox and most other hypervisors. Result is cached in g_is_guest_vm / g_is_guest_vm_reason. - Add "Running as VM guest: YES/NO" line to the CPU details block in check_cpu() (400_hw_check.sh), shown for both x86 and ARM guests. - Add a pr_warn block after the microcode-is-latest check in check_cpu() advising the user to verify microcode information on the hypervisor host when a VM guest is detected. - Add minimal ARM CPU details block in check_cpu(): vendor, model name, implementer(s), part(s), architecture(s), and VM guest status. ARM CPUs previously got no output from check_cpu() due to the x86-only early return guard. - Expose guest VM status in JSON output (250_output_emitters.sh): - system section: guest_vm (bool) and guest_vm_reason (string) - cpu_microcode section: unreliable_in_vm (bool)
This commit is contained in:
@@ -110,7 +110,8 @@ _build_json_system() {
|
||||
1) smt_val='false' ;;
|
||||
*) smt_val='null' ;;
|
||||
esac
|
||||
g_json_system=$(printf '{"kernel_release":%s,"kernel_version":%s,"kernel_arch":%s,"kernel_image":%s,"kernel_config":%s,"kernel_version_string":%s,"kernel_cmdline":%s,"cpu_count":%s,"smt_enabled":%s,"hypervisor_host":%s,"hypervisor_host_reason":%s}' \
|
||||
is_running_as_guest || true
|
||||
g_json_system=$(printf '{"kernel_release":%s,"kernel_version":%s,"kernel_arch":%s,"kernel_image":%s,"kernel_config":%s,"kernel_version_string":%s,"kernel_cmdline":%s,"cpu_count":%s,"smt_enabled":%s,"hypervisor_host":%s,"hypervisor_host_reason":%s,"guest_vm":%s,"guest_vm_reason":%s}' \
|
||||
"$(_json_str "$kernel_release")" \
|
||||
"$(_json_str "$kernel_version")" \
|
||||
"$(_json_str "$kernel_arch")" \
|
||||
@@ -121,7 +122,9 @@ _build_json_system() {
|
||||
"$(_json_num "${g_max_core_id:+$((g_max_core_id + 1))}")" \
|
||||
"$smt_val" \
|
||||
"$(_json_bool "${g_has_vmm:-}")" \
|
||||
"$(_json_str "${g_has_vmm_reason:-}")")
|
||||
"$(_json_str "${g_has_vmm_reason:-}")" \
|
||||
"$(_json_bool "${g_is_guest_vm:-}")" \
|
||||
"$(_json_str "${g_is_guest_vm_reason:-}")")
|
||||
}
|
||||
|
||||
# Build the "cpu" section of the comprehensive JSON output
|
||||
@@ -262,14 +265,15 @@ _build_json_cpu_microcode() {
|
||||
blacklisted='false'
|
||||
fi
|
||||
latest_hex="${ret_is_latest_known_ucode_version:-}"
|
||||
g_json_cpu_microcode=$(printf '{"installed_version":%s,"latest_version":%s,"microcode_up_to_date":%s,"is_blacklisted":%s,"message":%s,"db_source":%s,"db_info":%s}' \
|
||||
g_json_cpu_microcode=$(printf '{"installed_version":%s,"latest_version":%s,"microcode_up_to_date":%s,"is_blacklisted":%s,"message":%s,"db_source":%s,"db_info":%s,"unreliable_in_vm":%s}' \
|
||||
"$(_json_str "$ucode_hex")" \
|
||||
"$(_json_str "$latest_hex")" \
|
||||
"$ucode_uptodate" \
|
||||
"$blacklisted" \
|
||||
"$(_json_str "${ret_is_latest_known_ucode_latest:-}")" \
|
||||
"$(_json_str "${g_mcedb_source:-}")" \
|
||||
"$(_json_str "${g_mcedb_info:-}")")
|
||||
"$(_json_str "${g_mcedb_info:-}")" \
|
||||
"$(_json_bool "${g_is_guest_vm:-}")")
|
||||
}
|
||||
|
||||
# --- Format-specific batch emitters ---
|
||||
|
||||
@@ -55,3 +55,21 @@ is_xen_domU() {
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check whether the system is running as a guest inside a virtual machine.
|
||||
# Uses the 'hypervisor' CPUID feature flag exposed in /proc/cpuinfo by KVM,
|
||||
# VMware, Hyper-V, VirtualBox, and most other type-1 and type-2 hypervisors.
|
||||
# Returns: 0 if running as a VM guest, 1 otherwise
|
||||
# Sets: g_is_guest_vm (1=guest, 0=not a guest), g_is_guest_vm_reason
|
||||
is_running_as_guest() {
|
||||
if [ "${g_is_guest_vm_cached:-0}" != 1 ]; then
|
||||
g_is_guest_vm=0
|
||||
g_is_guest_vm_reason=''
|
||||
if [ -e "$g_procfs/cpuinfo" ] && grep -qw 'hypervisor' "$g_procfs/cpuinfo" 2>/dev/null; then
|
||||
g_is_guest_vm=1
|
||||
g_is_guest_vm_reason="'hypervisor' flag in $g_procfs/cpuinfo"
|
||||
fi
|
||||
g_is_guest_vm_cached=1
|
||||
fi
|
||||
[ "$g_is_guest_vm" = 1 ]
|
||||
}
|
||||
|
||||
@@ -388,6 +388,30 @@ check_kernel_info() {
|
||||
check_cpu() {
|
||||
local capabilities ret spec_ctrl_msr codename ucode_str
|
||||
|
||||
if is_arm_cpu; then
|
||||
pr_info "* CPU details"
|
||||
pr_info " * Vendor: $cpu_vendor"
|
||||
pr_info " * Model name: $cpu_friendly_name"
|
||||
if [ -n "${cpu_impl_list:-}" ]; then
|
||||
pr_info " * Implementer(s): $cpu_impl_list"
|
||||
fi
|
||||
if [ -n "${cpu_part_list:-}" ]; then
|
||||
pr_info " * Part(s): $cpu_part_list"
|
||||
fi
|
||||
if [ -n "${cpu_arch_list:-}" ]; then
|
||||
pr_info " * Architecture(s): $cpu_arch_list"
|
||||
fi
|
||||
if has_runtime; then
|
||||
pr_info_nol " * Running as VM guest: "
|
||||
if is_running_as_guest; then
|
||||
pstatus yellow YES "$g_is_guest_vm_reason"
|
||||
else
|
||||
pstatus green NO
|
||||
fi
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if ! uname -m | grep -qwE 'x86_64|i[3-6]86|amd64'; then
|
||||
return
|
||||
fi
|
||||
@@ -416,6 +440,15 @@ check_cpu() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if has_runtime; then
|
||||
pr_info_nol " * Running as VM guest: "
|
||||
if is_running_as_guest; then
|
||||
pstatus yellow YES "$g_is_guest_vm_reason"
|
||||
else
|
||||
pstatus green NO
|
||||
fi
|
||||
fi
|
||||
|
||||
pr_info "* Hardware support (CPU microcode) for mitigation techniques"
|
||||
pr_info " * Indirect Branch Restricted Speculation (IBRS)"
|
||||
pr_info_nol " * SPEC_CTRL MSR is available: "
|
||||
@@ -1365,6 +1398,13 @@ check_cpu() {
|
||||
else
|
||||
pstatus blue UNKNOWN "$ret_is_latest_known_ucode_latest"
|
||||
fi
|
||||
if is_running_as_guest; then
|
||||
pr_warn
|
||||
pr_warn "Note: this system is running inside a VM ($g_is_guest_vm_reason)."
|
||||
pr_warn "The hypervisor may be faking the CPU model and microcode version;"
|
||||
pr_warn "verify the above microcode information on the hypervisor host for accuracy."
|
||||
pr_warn
|
||||
fi
|
||||
}
|
||||
|
||||
# Display per-CVE CPU vulnerability status based on CPU model/family.
|
||||
|
||||
Reference in New Issue
Block a user