# vim: set ts=4 sw=4 sts=4 et: ############################### # CVE-2025-54505, FPDSS, AMD Zen1 Floating-Point Divider Stale Data Leak check_CVE_2025_54505() { check_cve 'CVE-2025-54505' } # Print remediation advice for FPDSS when reporting VULN # Callers: check_CVE_2025_54505_linux _cve_2025_54505_explain_fix() { explain "Update your kernel to one that carries commit e55d98e77561 (\"x86/CPU: Fix FPDSS on Zen1\", mainline Linux 7.1),\n " \ "or the equivalent backport from your distribution. The kernel sets bit 9 of MSR 0xc0011028 unconditionally on\n " \ "every Zen1 CPU at boot, which disables the hardware optimization responsible for the leak.\n " \ "To manually mitigate the issue right now, you may use the following command:\n " \ "\`wrmsr -a 0xc0011028 \$((\$(rdmsr -c 0xc0011028) | (1<<9)))\`,\n " \ "however note that this manual mitigation will only be active until the next reboot.\n " \ "No microcode update is required: the chicken bit is present on every Zen1 CPU." } check_CVE_2025_54505_linux() { local status sys_interface_available msg kernel_mitigated dmesg_fpdss msr_fpdss ret status=UNK sys_interface_available=0 msg='' # No sysfs interface exists for this vulnerability (no /sys/devices/system/cpu/vulnerabilities/fpdss). # sys_interface_available stays 0. # # Kernel source inventory for FPDSS, 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) --- # none: the fix is two inline lines in init_amd_zen1(), no dedicated function # # --- dmesg --- # e55d98e77561 (v7.1, initial fix): "AMD Zen1 FPDSS bug detected, enabling mitigation." # (printed via pr_notice_once on every Zen1 CPU) # # --- /proc/cpuinfo bugs field --- # none: no X86_BUG_FPDSS flag defined; no cpuinfo exposure # # --- MSR --- # e55d98e77561 (v7.1): MSR_AMD64_FP_CFG = 0xc0011028, bit 9 = ZEN1_DENORM_FIX_BIT # kernel calls msr_set_bit() unconditionally on any Zen1 CPU in init_amd_zen1(). # The bit is present in Zen1 silicon independently of microcode (no microcode # revision gate in the kernel, unlike Zenbleed which uses amd_zenbleed_microcode[]). # # --- CPU affection logic (for is_cpu_affected) --- # e55d98e77561 (v7.1): applied unconditionally in init_amd_zen1(), i.e. all Zen1 # AMD: family 0x17 models 0x00-0x2f, 0x50-0x5f (same cohort as DIV0) # vendor scope: AMD only (Zen1 microarchitecture) # # --- stable backports --- # as of this writing, no stable/LTS backport has landed; only mainline (Linux 7.1). if [ "$opt_sysfs_only" != 1 ]; then pr_info_nol "* Kernel supports FPDSS mitigation: " kernel_mitigated='' if [ -n "$g_kernel_err" ]; then pstatus yellow UNKNOWN "$g_kernel_err" elif is_x86_kernel && grep -q 'AMD Zen1 FPDSS bug detected' "$g_kernel"; then kernel_mitigated="found FPDSS mitigation message in kernel image" pstatus green YES "$kernel_mitigated" else pstatus yellow NO fi pr_info_nol "* FPDSS mitigation enabled and active: " msr_fpdss='' dmesg_fpdss='' if [ "$g_mode" = live ] && is_x86_cpu && is_cpu_affected "$cve"; then # guard with is_cpu_affected to avoid #GP on non-Zen1 CPUs where 0xc0011028 is undefined read_msr 0xc0011028 ret=$? if [ "$ret" = "$READ_MSR_RET_OK" ]; then if [ $((ret_read_msr_value_lo >> 9 & 1)) -eq 1 ]; then msr_fpdss=1 pstatus green YES "ZEN1_DENORM_FIX_BIT set in FP_CFG MSR" else msr_fpdss=0 pstatus yellow NO "ZEN1_DENORM_FIX_BIT is cleared in FP_CFG MSR" fi else # MSR unreadable (lockdown, no msr module, etc.): fall back to dmesg dmesg_grep 'AMD Zen1 FPDSS bug detected' ret=$? if [ "$ret" -eq 0 ]; then dmesg_fpdss=1 pstatus green YES "FPDSS mitigation message found in dmesg" elif [ "$ret" -eq 2 ]; then pstatus yellow UNKNOWN "couldn't read MSR and dmesg is truncated" else pstatus yellow UNKNOWN "couldn't read MSR and no FPDSS message in dmesg" fi fi elif [ "$g_mode" = live ]; then pstatus blue N/A "CPU is incompatible" else pstatus blue N/A "not testable in no-runtime mode" 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 if [ "$msr_fpdss" = 1 ] || [ "$dmesg_fpdss" = 1 ]; then pvulnstatus "$cve" OK "ZEN1_DENORM_FIX_BIT is set in FP_CFG MSR, mitigation is active" elif [ "$msr_fpdss" = 0 ]; then pvulnstatus "$cve" VULN "ZEN1_DENORM_FIX_BIT is cleared in FP_CFG MSR, FPDSS can leak data between threads" _cve_2025_54505_explain_fix elif [ -n "$kernel_mitigated" ]; then # MSR unreadable at runtime, but kernel image carries the mitigation code # and init_amd_zen1() sets the bit unconditionally, so mitigation is active pvulnstatus "$cve" OK "kernel image carries FPDSS mitigation code (init_amd_zen1 sets the MSR bit unconditionally at boot)" else pvulnstatus "$cve" VULN "your kernel doesn't support FPDSS mitigation" _cve_2025_54505_explain_fix fi else if [ -n "$kernel_mitigated" ]; then pvulnstatus "$cve" OK "Mitigation: FPDSS message found in kernel image" else pvulnstatus "$cve" VULN "your kernel doesn't support FPDSS mitigation" _cve_2025_54505_explain_fix 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_2025_54505_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 }