# vim: set ts=4 sw=4 sts=4 et:
###############################
# CVE-2025-40300, VMScape, VM-Exit Stale Branch Prediction

check_CVE_2025_40300() {
    check_cve 'CVE-2025-40300'
}

check_CVE_2025_40300_linux() {
    local status sys_interface_available msg kernel_vmscape kernel_vmscape_err
    status=UNK
    sys_interface_available=0
    msg=''

    if sys_interface_check "$VULN_SYSFS_BASE/vmscape"; then
        # this kernel has the /sys interface, trust it over everything
        sys_interface_available=1
        #
        # Kernel source inventory for vmscape, traced via git blame:
        #
        # --- sysfs messages ---
        # all versions:
        #   "Not affected"                              (cpu_show_common, pre-existing)
        #
        # --- mainline ---
        # a508cec6e521 (v6.17-rc6, initial vmscape sysfs):
        #   "Vulnerable"                                (VMSCAPE_MITIGATION_NONE)
        #   "Mitigation: IBPB before exit to userspace" (VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER)
        # 2f8f17341 (v6.17-rc6, vmscape_update_mitigation):
        #   "Mitigation: IBPB on VMEXIT"                (VMSCAPE_MITIGATION_IBPB_ON_VMEXIT)
        #     (when retbleed uses IBPB or srso uses IBPB_ON_VMEXIT)
        #
        # --- stable backports ---
        # 6.16.x (v6.16.7): identical to mainline (d83e6111337f)
        # 6.12.x (v6.12.47): identical to mainline (7c62c442b6eb)
        # 6.6.x (v6.6.106): identical to mainline (813cb831439c)
        # 6.1.x (v6.1.152): identical strings; uses VULNBL_INTEL_STEPPINGS macro,
        #   missing ARROWLAKE_U, ATOM_CRESTMONT_X, AMD 0x1a.
        #   Uses ALDERLAKE_N instead of type-specific ALDERLAKE split. (304d1fb275af)
        #
        # --- RHEL/CentOS ---
        # Not yet backported.
        #
        # --- Kconfig symbols ---
        # a508cec6e521 (v6.17-rc6): CONFIG_MITIGATION_VMSCAPE (default y)
        #   depends on KVM
        #
        # --- kernel functions (for $opt_map / System.map) ---
        # a508cec6e521 (v6.17-rc6): vmscape_select_mitigation(),
        #   vmscape_update_mitigation(), vmscape_apply_mitigation(),
        #   vmscape_parse_cmdline(), vmscape_show_state()
        #
        # --- CPU affection logic (for is_cpu_affected) ---
        # X86_BUG_VMSCAPE is set when ALL conditions are true:
        #   1. CPU matches model blacklist
        #   2. X86_FEATURE_HYPERVISOR is NOT set (bare metal only)
        # a508cec6e521 (v6.17-rc6, initial model list):
        #   Intel: SKYLAKE_X, SKYLAKE_L, SKYLAKE, KABYLAKE_L, KABYLAKE,
        #          CANNONLAKE_L, COMETLAKE, COMETLAKE_L, ALDERLAKE,
        #          ALDERLAKE_L, RAPTORLAKE, RAPTORLAKE_P, RAPTORLAKE_S,
        #          METEORLAKE_L, ARROWLAKE_H, ARROWLAKE, ARROWLAKE_U,
        #          LUNARLAKE_M, SAPPHIRERAPIDS_X, GRANITERAPIDS_X,
        #          EMERALDRAPIDS_X, ATOM_GRACEMONT, ATOM_CRESTMONT_X
        #   AMD: family 0x17 (Zen 1/+/2), family 0x19 (Zen 3/4),
        #        family 0x1a (Zen 5)
        #   Hygon: family 0x18
        # 8a68d64bb103 (v6.17-rc6, added old Intel CPUs):
        #   Intel: + SANDYBRIDGE_X, SANDYBRIDGE, IVYBRIDGE_X, IVYBRIDGE,
        #          HASWELL, HASWELL_L, HASWELL_G, HASWELL_X,
        #          BROADWELL_D, BROADWELL_X, BROADWELL_G, BROADWELL
        # Intel NOT affected: ICELAKE_*, TIGERLAKE_*, LAKEFIELD, ROCKETLAKE,
        #   ATOM_TREMONT_*, ATOM_GOLDMONT_*
        # immunity: no ARCH_CAP bits — determination is purely via blacklist
        # note: bare metal only (X86_FEATURE_HYPERVISOR excludes guests)
        # vendor scope: Intel + AMD + Hygon
        #
        # all messages start with either "Not affected", "Vulnerable", or "Mitigation"
        status=$ret_sys_interface_check_status
    fi

    if [ "$opt_sysfs_only" != 1 ]; then
        check_has_vmm
        pr_info_nol "* Kernel supports VMScape mitigation: "
        kernel_vmscape=''
        kernel_vmscape_err=''
        if [ -n "$g_kernel_err" ]; then
            kernel_vmscape_err="$g_kernel_err"
        elif is_x86_kernel && grep -q 'vmscape' "$g_kernel"; then
            kernel_vmscape="found vmscape in kernel image"
        fi
        if [ -z "$kernel_vmscape" ] && is_x86_kernel && [ -r "$opt_config" ]; then
            if grep -q '^CONFIG_MITIGATION_VMSCAPE=y' "$opt_config"; then
                kernel_vmscape="VMScape mitigation config option found enabled in kernel config"
            fi
        fi
        if [ -z "$kernel_vmscape" ] && is_x86_kernel && [ -n "$opt_map" ]; then
            if grep -q 'vmscape_select_mitigation' "$opt_map"; then
                kernel_vmscape="found vmscape_select_mitigation in System.map"
            fi
        fi
        if [ -n "$kernel_vmscape" ]; then
            pstatus green YES "$kernel_vmscape"
        elif [ -n "$kernel_vmscape_err" ]; then
            pstatus yellow UNKNOWN "$kernel_vmscape_err"
        else
            pstatus yellow NO
        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 [ "$opt_sysfs_only" != 1 ]; then
            if [ "$g_has_vmm" = 0 ]; then
                pvulnstatus "$cve" OK "this system is not running a hypervisor"
            elif [ -n "$kernel_vmscape" ]; then
                pvulnstatus "$cve" OK "Kernel mitigates the vulnerability"
            elif [ -z "$kernel_vmscape" ] && [ -z "$kernel_vmscape_err" ]; then
                pvulnstatus "$cve" VULN "Your kernel doesn't support VMScape mitigation"
                explain "Update your kernel to a version that includes the VMScape mitigation (Linux 6.18+, or check\n" \
                    "if your distro has a backport). The mitigation issues IBPB before returning to userspace\n" \
                    "after a VM exit, preventing stale guest branch predictions from leaking host kernel memory."
            else
                pvulnstatus "$cve" UNK "couldn't determine mitigation status: $kernel_vmscape_err"
            fi
        else
            pvulnstatus "$cve" "$status" "$ret_sys_interface_check_fullmsg"
        fi
    else
        pvulnstatus "$cve" "$status" "$msg"
    fi
}

check_CVE_2025_40300_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
}
