# vim: set ts=4 sw=4 sts=4 et:
###############################
# CVE-0001-0003, ARM SSBS NOSYNC, ARM64 erratum 3194386, MSR SSBS not self-synchronizing

check_CVE_0001_0003() {
    check_cve 'CVE-0001-0003'
}

# On affected cores, the "MSR SSBS, #x" instruction is not self-synchronizing, so subsequent
# speculative instructions may execute without observing the new SSBS state. This can permit
# unintended speculative store bypass (Spectre V4 / CVE-2018-3639) even when software thinks
# the mitigation is in effect. Kernel workaround (ARM64_WORKAROUND_SPECULATIVE_SSBS):
#   - place a Speculation Barrier (SB) or ISB after every kernel-side SSBS change
#   - hide SSBS from userspace hwcaps and EL0 reads of ID_AA64PFR1_EL1 so that userspace
#     routes SSB mitigation changes through the prctl(PR_SET_SPECULATION_CTRL) path
# Affected cores (via ARM64_ERRATUM_3194386, with individual sub-errata numbers):
#   Cortex-A76/A77/A78/A78C/A710/A715/A720/A720AE/A725, X1/X1C/X2/X3/X4/X925,
#   Neoverse-N1/N2/N3, Neoverse-V1/V2/V3/V3AE
# References:
#   arch/arm64/Kconfig (ARM64_ERRATUM_3194386)
#   arch/arm64/kernel/cpu_errata.c (erratum_spec_ssbs_list, "SSBS not fully self-synchronizing")
check_CVE_0001_0003_linux() {
    local cve kernel_mitigated
    cve='CVE-0001-0003'
    kernel_mitigated=''

    if [ "$opt_sysfs_only" != 1 ] && is_arm_kernel; then
        if [ -n "$opt_config" ] && grep -q '^CONFIG_ARM64_ERRATUM_3194386=y' "$opt_config"; then
            kernel_mitigated="found CONFIG_ARM64_ERRATUM_3194386=y in kernel config"
        fi
        if [ -z "$kernel_mitigated" ] && [ -n "$g_kernel" ]; then
            if "${opt_arch_prefix}strings" "$g_kernel" 2>/dev/null | grep -qE 'SSBS not fully self-synchronizing'; then
                kernel_mitigated="found erratum descriptor string in kernel image"
            fi
        fi
        if [ -z "$kernel_mitigated" ] && [ "$g_mode" = live ]; then
            if dmesg 2>/dev/null | grep -qE 'SSBS not fully self-synchronizing'; then
                kernel_mitigated="erratum workaround reported as applied in dmesg"
            fi
        fi

        pr_info_nol "* Kernel has the ARM64 SSBS self-sync workaround compiled in: "
        if [ -n "$kernel_mitigated" ]; then
            pstatus green YES "$kernel_mitigated"
        else
            pstatus yellow NO
        fi
    fi

    if ! is_cpu_affected "$cve"; then
        pvulnstatus "$cve" OK "your CPU is not affected by this erratum"
    elif [ "$opt_sysfs_only" = 1 ]; then
        pvulnstatus "$cve" UNK "no sysfs interface exists for this erratum, own checks have been skipped (--sysfs-only)"
    elif [ -n "$kernel_mitigated" ]; then
        pvulnstatus "$cve" OK "your kernel includes the erratum workaround"
    else
        pvulnstatus "$cve" VULN "your CPU is affected by this erratum and the kernel does not appear to include the workaround; Spectre V4 (CVE-2018-3639) mitigation may be unreliable on this system"
        explain "Run a kernel built with CONFIG_ARM64_ERRATUM_3194386=y. This option is 'default y' in mainline and enabled by most distro kernels. Without it, the Spectre V4 / speculative-store-bypass mitigation advertised by SSBS is not reliably applied. Userspace should use prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, ...) to request the mitigation rather than rely on the SSBS hwcap."
    fi
}

check_CVE_0001_0003_bsd() {
    local cve
    cve='CVE-0001-0003'
    if ! is_cpu_affected "$cve"; then
        pvulnstatus "$cve" OK "your CPU is not affected by this erratum"
    else
        pvulnstatus "$cve" UNK "your CPU is affected, but mitigation detection has not yet been implemented for BSD in this script"
    fi
}
