# vim: set ts=4 sw=4 sts=4 et: ############################### # CVE-2023-20588, DIV0, AMD Division by Zero Speculative Data Leak check_CVE_2023_20588() { check_cve 'CVE-2023-20588' } # shellcheck disable=SC2034 _cve_2023_20588_pvulnstatus_smt() { # common logic for both live (cpuinfo) and live (kernel image fallback) paths: # if --paranoid and SMT is on, report VULN; otherwise OK. # $1 = mitigation detail message if [ "$opt_paranoid" != 1 ] || ! is_cpu_smt_enabled; then pvulnstatus "$cve" OK "Mitigation: amd_clear_divider on exit to user/guest" else pvulnstatus "$cve" VULN "DIV0 mitigation is active but SMT is enabled, data leak possible between sibling threads" explain "Disable SMT (Simultaneous Multi-Threading) for full protection against DIV0.\n " \ "The kernel mitigation only covers kernel-to-user and host-to-guest leak paths, not cross-SMT-thread leaks.\n " \ "You can disable SMT by booting with the \`nosmt\` kernel parameter, or at runtime:\n " \ "\`echo off > /sys/devices/system/cpu/smt/control\`" fi } # shellcheck disable=SC2034 _cve_2023_20588_pvulnstatus_no_kernel() { pvulnstatus "$cve" VULN "your kernel doesn't support DIV0 mitigation" explain "Update your kernel to a version that includes the amd_clear_divider mitigation (Linux >= 6.5 or a backported stable/vendor kernel).\n " \ "The kernel fix adds a dummy division on every exit to userspace and before VMRUN, preventing stale quotient data from leaking.\n " \ "Also disable SMT for full protection, as the mitigation doesn't cover cross-SMT-thread leaks." } check_CVE_2023_20588_linux() { local status sys_interface_available msg kernel_mitigated cpuinfo_div0 dmesg_div0 ret status=UNK sys_interface_available=0 msg='' # No sysfs interface exists for this CVE (no /sys/devices/system/cpu/vulnerabilities/div0). # sys_interface_available stays 0. # # Kernel source inventory for CVE-2023-20588 (DIV0), traced via git blame: # # --- sysfs messages --- # none: this vulnerability has no sysfs entry # # --- Kconfig symbols --- # none: the mitigation is unconditional, not configurable (no CONFIG_* knob) # # --- kernel functions (for $opt_map / System.map) --- # 77245f1c3c64 (v6.5, initial fix): amd_clear_divider() # initially called from exc_divide_error() (#DE handler) # f58d6fbcb7c8 (v6.5, follow-up fix): moved amd_clear_divider() call to # exit-to-userspace path and before VMRUN (SVM) # bfff3c6692ce (v6.8): moved DIV0 detection from model range check to # unconditional in init_amd_zen1() # 501bd734f933 (v6.11): amd_clear_divider() made __always_inline # (may no longer appear in System.map on newer kernels) # # --- dmesg --- # 77245f1c3c64 (v6.5): "AMD Zen1 DIV0 bug detected. Disable SMT for full protection." # (present since the initial fix, printed via pr_notice_once) # # --- /proc/cpuinfo bugs field --- # 77245f1c3c64 (v6.5): X86_BUG_DIV0 mapped to "div0" in bugs field # # --- CPU affection logic (for is_cpu_affected) --- # 77245f1c3c64 (v6.5, initial model list): # AMD: family 0x17 models 0x00-0x2f, 0x50-0x5f # bfff3c6692ce (v6.8): moved to init_amd_zen1(), unconditional for all Zen1 # (same model ranges, just different detection path) # vendor scope: AMD only (Zen1 microarchitecture) # # --- stable backports --- # 5.10.y, 5.15.y, 6.1.y, 6.4.y: backported via cpu_has_amd_erratum() path # (same as mainline v6.5 initial implementation) # 6.5.y, 6.7.y: same erratum-table detection as mainline v6.5 # 6.6.y: stable-specific commit 824549816609 backported the init_amd_zen1() # move (equivalent to mainline bfff3c6692ce but adapted to 6.6 context) # 6.8.y, 6.9.y, 6.10.y: carry mainline bfff3c6692ce directly # 6.7.y missed the init_amd_zen1() move (EOL before backport landed) # 501bd734f933 (__always_inline) was NOT backported to any stable branch # 4.14.y, 4.19.y, 5.4.y: do NOT have the fix (EOL or not backported) # no stable-specific string or behavior differences; all branches use the # same dmesg message and /proc/cpuinfo bugs field as mainline if [ "$opt_sysfs_only" != 1 ]; then pr_info_nol "* Kernel supports DIV0 mitigation: " kernel_mitigated='' if [ -n "$g_kernel_err" ]; then pstatus yellow UNKNOWN "$g_kernel_err" elif is_x86_kernel && grep -q 'amd_clear_divider' "$g_kernel"; then kernel_mitigated="found amd_clear_divider in kernel image" pstatus green YES "$kernel_mitigated" elif is_x86_kernel && [ -n "$opt_map" ] && grep -q 'amd_clear_divider' "$opt_map"; then kernel_mitigated="found amd_clear_divider in System.map" pstatus green YES "$kernel_mitigated" else pstatus yellow NO fi pr_info_nol "* DIV0 mitigation enabled and active: " cpuinfo_div0='' dmesg_div0='' if [ "$g_mode" = live ]; then if [ -e "$g_procfs/cpuinfo" ] && grep -qw 'div0' "$g_procfs/cpuinfo" 2>/dev/null; then cpuinfo_div0=1 pstatus green YES "div0 found in $g_procfs/cpuinfo bug flags" else # cpuinfo flag not found, fall back to dmesg dmesg_grep 'AMD Zen1 DIV0 bug detected' ret=$? if [ "$ret" -eq 0 ]; then dmesg_div0=1 pstatus green YES "DIV0 bug detected message found in dmesg" elif [ "$ret" -eq 2 ]; then pstatus yellow UNKNOWN "dmesg truncated, cannot check for DIV0 message" else pstatus yellow NO "div0 not found in $g_procfs/cpuinfo bug flags or dmesg" fi fi else pstatus blue N/A "not testable in no-runtime mode" fi pr_info_nol "* SMT (Simultaneous Multi-Threading) is enabled: " is_cpu_smt_enabled smt_ret=$? if [ "$smt_ret" = 0 ]; then pstatus yellow YES elif [ "$smt_ret" = 2 ]; then pstatus yellow UNKNOWN else pstatus green NO fi elif [ "$sys_interface_available" = 0 ]; then msg="/sys vulnerability interface use forced, but it's not available!" status=UNK fi if ! is_cpu_affected "$cve"; then pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" elif [ -z "$msg" ]; then if [ "$opt_sysfs_only" != 1 ]; then if [ "$g_mode" = live ]; then # live mode: cpuinfo div0 flag is the strongest proof the mitigation is active if [ "$cpuinfo_div0" = 1 ] || [ "$dmesg_div0" = 1 ]; then _cve_2023_20588_pvulnstatus_smt elif [ -n "$kernel_mitigated" ]; then # kernel has the code but the bug flag is not set, it shouldn't happen on affected CPUs, # but if it does, trust the kernel image evidence _cve_2023_20588_pvulnstatus_smt else _cve_2023_20588_pvulnstatus_no_kernel fi else # no-runtime mode: only kernel image / System.map evidence is available if [ -n "$kernel_mitigated" ]; then pvulnstatus "$cve" OK "Mitigation: amd_clear_divider found in kernel image" else _cve_2023_20588_pvulnstatus_no_kernel fi fi else pvulnstatus "$cve" "$status" "no sysfs interface available for this CVE, use --no-sysfs to check" fi else pvulnstatus "$cve" "$status" "$msg" fi } check_CVE_2023_20588_bsd() { if ! is_cpu_affected "$cve"; then pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" else pvulnstatus "$cve" UNK "your CPU is affected, but mitigation detection has not yet been implemented for BSD in this script" fi }