Skip to content

Commit

Permalink
feat: add Zenbleed (WIP)
Browse files Browse the repository at this point in the history
Check is not completely implemented yet:
- check the MSR
- check the firmware version

Don't use for anything else yet, than just checking
whether your CPU is affected
  • Loading branch information
speed47 committed Jul 25, 2023
1 parent 8cd707a commit 70ebf36
Showing 1 changed file with 118 additions and 1 deletion.
119 changes: 118 additions & 1 deletion spectre-meltdown-checker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ global_critical=0
global_unknown=0
nrpe_vuln=''

supported_cve_list='CVE-2017-5753 CVE-2017-5715 CVE-2017-5754 CVE-2018-3640 CVE-2018-3639 CVE-2018-3615 CVE-2018-3620 CVE-2018-3646 CVE-2018-12126 CVE-2018-12130 CVE-2018-12127 CVE-2019-11091 CVE-2019-11135 CVE-2018-12207 CVE-2020-0543'
supported_cve_list='CVE-2017-5753 CVE-2017-5715 CVE-2017-5754 CVE-2018-3640 CVE-2018-3639 CVE-2018-3615 CVE-2018-3620 CVE-2018-3646 CVE-2018-12126 CVE-2018-12130 CVE-2018-12127 CVE-2019-11091 CVE-2019-11135 CVE-2018-12207 CVE-2020-0543 CVE-2023-20593'

# find a sane command to print colored messages, we prefer `printf` over `echo`
# because `printf` behavior is more standard across Linux/BSD
Expand Down Expand Up @@ -295,6 +295,7 @@ cve2name()
CVE-2019-11135) echo "ZombieLoad V2, TSX Asynchronous Abort (TAA)";;
CVE-2018-12207) echo "No eXcuses, iTLB Multihit, machine check exception on page size changes (MCEPSC)";;
CVE-2020-0543) echo "Special Register Buffer Data Sampling (SRBDS)";;
CVE-2023-20593) echo "Zenbleed, cross-process information leak";;
*) echo "$0: error: invalid CVE '$1' passed to cve2name()" >&2; exit 255;;
esac
}
Expand All @@ -319,6 +320,7 @@ _is_cpu_affected_cached()
CVE-2019-11135) return $variant_taa;;
CVE-2018-12207) return $variant_itlbmh;;
CVE-2020-0543) return $variant_srbds;;
CVE-2023-20593) return $variant_zenbleed;;
*) echo "$0: error: invalid variant '$1' passed to is_cpu_affected()" >&2; exit 255;;
esac
}
Expand Down Expand Up @@ -348,6 +350,7 @@ is_cpu_affected()
variant_taa=''
variant_itlbmh=''
variant_srbds=''
variant_zenbleed=''

if is_cpu_mds_free; then
[ -z "$variant_msbds" ] && variant_msbds=immune
Expand Down Expand Up @@ -380,6 +383,7 @@ is_cpu_affected()
variant_mdsum=immune
variant_taa=immune
variant_srbds=immune
variant_zenbleed=immune
elif is_intel; then
# Intel
# https://github.com/crozone/SpectrePoC/issues/1 ^F E5200 => spectre 2 not affected
Expand Down Expand Up @@ -455,6 +459,7 @@ is_cpu_affected()
_debug "is_cpu_affected: intel family < 6 is immune to l1tf"
[ -z "$variantl1tf" ] && variantl1tf=immune
fi
variant_zenbleed=immune
elif is_amd || is_hygon; then
# AMD revised their statement about variant2 => affected
# https://www.amd.com/en/corporate/speculative-execution
Expand All @@ -469,6 +474,12 @@ is_cpu_affected()
_debug "is_cpu_affected: cpu not affected by speculative store bypass so not vuln to variant4"
fi
variantl1tf=immune

# Zenbleed
variant_zenbleed=immune
amd_legacy_erratum "$(amd_model_range 0x17 0x30 0x0 0x4f 0xf)" && variant_zenbleed=vuln
amd_legacy_erratum "$(amd_model_range 0x17 0x60 0x0 0x7f 0xf)" && variant_zenbleed=vuln
amd_legacy_erratum "$(amd_model_range 0x17 0xa0 0x0 0xaf 0xf)" && variant_zenbleed=vuln
elif [ "$cpu_vendor" = CAVIUM ]; then
variant3=immune
variant3a=immune
Expand Down Expand Up @@ -624,6 +635,7 @@ is_cpu_affected()
[ "$variant_taa" = "immune" ] && variant_taa=1 || variant_taa=0
[ "$variant_itlbmh" = "immune" ] && variant_itlbmh=1 || variant_itlbmh=0
[ "$variant_srbds" = "immune" ] && variant_srbds=1 || variant_srbds=0
[ "$variant_zenbleed" = "immune" ] && variant_zenbleed=1 || variant_zenbleed=0
variantl1tf_sgx="$variantl1tf"
# even if we are affected to L1TF, if there's no SGX, we're not affected to the original foreshadow
[ "$cpuid_sgx" = 0 ] && variantl1tf_sgx=1
Expand Down Expand Up @@ -1247,6 +1259,7 @@ pvulnstatus()
CVE-2019-11135) aka="TAA";;
CVE-2018-12207) aka="ITLBMH";;
CVE-2020-0543) aka="SRBDS";;
CVE-2023-20593) aka="ZENBLEED";;
*) echo "$0: error: invalid CVE '$1' passed to pvulnstatus()" >&2; exit 255;;
esac

Expand Down Expand Up @@ -1987,6 +2000,7 @@ is_zen_cpu()
[ "$cpu_family" = 23 ] && return 0
return 1
}

is_moksha_cpu()
{
parse_cpu_details
Expand All @@ -1995,6 +2009,29 @@ is_moksha_cpu()
return 1
}

# mimick the Linux macro
##define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \
# ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end))
amd_model_range()
{
echo $(( ($1 << 24) | ($2 << 16) | ($3 << 12) | ($4 << 4) | ($5) ))
}

# mimick the Linux func, usage:
# amd_legacy_erratum $(amd_model_range 0x17 0x30 0x0 0x4f 0xf)
# return true (0) if the current CPU is affected by this erratum, 1 otherwise
amd_legacy_erratum()
{
_range="$1"
_ms=$((cpu_model << 4 | cpu_stepping))
if [ "$cpu_family" = $(( ( (_range) >> 24) & 0xff )) ] && \
[ $_ms -ge $(( ( (_range) >> 12) & 0xfff )) ] && \
[ $_ms -le $(( (_range) & 0xfff )) ]; then
return 0
fi
return 1
}

# Test if the current host is a Xen PV Dom0 / DomU
is_xen() {
if [ ! -d "$procfs/xen" ]; then
Expand Down Expand Up @@ -5758,6 +5795,86 @@ check_CVE_2020_0543_bsd()
fi
}

####################
# Zenbleed section

check_CVE_2023_20593()
{
cve='CVE-2023-20593'
_info "\033[1;34m$cve aka '$(cve2name "$cve")'\033[0m"
if [ "$os" = Linux ]; then
check_CVE_2023_20593_linux
#elif echo "$os" | grep -q BSD; then
# check_CVE_2023_20593_bsd
else
_warn "Unsupported OS ($os)"
fi
}

check_CVE_2023_20593_linux()
{
status=UNK
sys_interface_available=0
msg=''
if [ "$opt_sysfs_only" != 1 ]; then
_info_nol "* Zenbleed mitigation is supported by kernel: "
kernel_zenbleed=''
if [ -n "$kernel_err" ]; then
kernel_zenbleed_err="$kernel_err"
# commit 522b1d69219d8f083173819fde04f994aa051a98
elif grep -q 'Zenbleed:' "$kernel"; then
kernel_zenbleed="found zenbleed message in kernel image"
fi
if [ -n "$kernel_zenbleed" ]; then
pstatus green YES "$kernel_zenbleed"
elif [ -n "$kernel_zenbleed_err" ]; then
pstatus yellow UNKNOWN "$kernel_zenbleed_err"
else
pstatus yellow NO
fi

_info_nol "* Zenbleed mitigation enabled and active: "
# TODO check whether the microcode is up to date (versions hardcoded in kernel)
if [ "$opt_live" = 1 ]; then
if [ -n "$kernel_zenbleed" ]; then
# FIXME actually read the MSR
pstatus green OK "yes (chicken bit set)"
else
pstatus yellow NO
fi
else
pstatus blue N/A "not testable in offline mode"
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_live" = 1 ]; then
if [ -n "$kernel_zenbleed" ]; then
pvulnstatus $cve OK "Your kernel mitigates Zenbleed"
else
pvulnstatus $cve VULN "Your kernel is too old to mitigate Zenbleed"
fi
else
if [ -n "$kernel_zenbleed" ]; then
pvulnstatus $cve OK "Your kernel supports Zenbleed mitigation"
else
pvulnstatus $cve VULN "Your kernel doesn't support Zenbleed, update it"
fi
fi
else
pvulnstatus $cve "$status" "$msg"
fi
}


#######################
# END OF VULNS SECTIONS

Expand Down

0 comments on commit 70ebf36

Please sign in to comment.