Compare commits

...

5 Commits

Author SHA1 Message Date
Stéphane Lesimple e99a548dcc fix: fms2cpuid was incorrect for families > 0xF 2023-07-26 14:33:11 +02:00
Stéphane Lesimple 3d475dfaec feat: fwdb: add linux-firmware as AMD source, update fwdb accordingly 2023-07-26 13:57:05 +02:00
Stéphane Lesimple cba5010c2a chore: fix typo 2023-07-26 13:57:05 +02:00
Stéphane Lesimple c5661f098f enh: add --explain text for Zenbleed 2023-07-26 10:56:45 +02:00
Stéphane Lesimple 6844c01242 enh: add zenbleed support to the --variant option 2023-07-26 10:46:38 +02:00
2 changed files with 116 additions and 29 deletions

View File

@ -18,7 +18,7 @@ CVE
[CVE-2018-12127](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12127) | Microarchitectural Load Port Data Sampling | MLPDS, RIDL
[CVE-2019-11091](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11091) | Microarchitectural Data Sampling Uncacheable Memory | MDSUM, RIDL
[CVE-2019-11135](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11135) | TSX asynchronous abort | TAA, ZombieLoad V2
[CVE-2018-12207](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12207) | Machine Mheck Exception on Page Size Changes | MCEPSC, No eXcuses, iTLB Multihit
[CVE-2018-12207](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12207) | Machine Check Exception on Page Size Changes | MCEPSC, No eXcuses, iTLB Multihit
[CVE-2020-0543](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-0543) | Special Register Buffer Data Sampling | SRBDS
[CVE-2023-20593](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20593) | Cross-Process Information Leak | Zenbleed

View File

@ -25,6 +25,7 @@ exit_cleanup()
[ -n "${kerneltmp2:-}" ] && [ -f "$kerneltmp2" ] && rm -f "$kerneltmp2"
[ -n "${mcedb_tmp:-}" ] && [ -f "$mcedb_tmp" ] && rm -f "$mcedb_tmp"
[ -n "${intel_tmp:-}" ] && [ -d "$intel_tmp" ] && rm -rf "$intel_tmp"
[ -n "${linuxfw_tmp:-}" ] && [ -f "$linuxfw_tmp" ] && rm -f "$linuxfw_tmp"
[ "${mounted_debugfs:-}" = 1 ] && umount /sys/kernel/debug 2>/dev/null
[ "${mounted_procfs:-}" = 1 ] && umount "$procfs" 2>/dev/null
[ "${insmod_cpuid:-}" = 1 ] && rmmod cpuid 2>/dev/null
@ -86,10 +87,11 @@ show_usage()
--batch nrpe produce machine readable output formatted for NRPE
--batch prometheus produce output for consumption by prometheus-node-exporter
--variant VARIANT specify which variant you'd like to check, by default all variants are checked
VARIANT can be one of 1, 2, 3, 3a, 4, l1tf, msbds, mfbds, mlpds, mdsum, taa, mcepsc, srbds
can be specified multiple times (e.g. --variant 2 --variant 3)
--cve [cve1,cve2,...] specify which CVE you'd like to check, by default all supported CVEs are checked
--variant VARIANT specify which variant you'd like to check, by default all variants are checked.
can be used multiple times (e.g. --variant 3a --variant l1tf)
for a list of supported VARIANT parameters, use --variant help
--cve CVE specify which CVE you'd like to check, by default all supported CVEs are checked
can be used multiple times (e.g. --cve CVE-2017-5753 --cve CVE-2020-0543)
--hw-only only check for CPU information, don't check for any variant
--no-hw skip CPU information and checks, if you're inspecting a kernel not to be run on this host
--vmm [auto,yes,no] override the detection of the presence of a hypervisor, default: auto
@ -859,6 +861,29 @@ show_header()
_info
}
# Family-Model-Stepping to CPUID
# prints CPUID in base-10 to stdout
fms2cpuid()
{
_family="$1"
_model="$2"
_stepping="$3"
if [ "$(( _family ))" -le 15 ]; then
_extfamily=0
_lowfamily=$(( _family ))
else
# when we have a family > 0xF, then lowfamily is stuck at 0xF
# and extfamily is ADDED to it (as in "+"), to ensure old software
# never sees a lowfamily < 0xF for newer families
_lowfamily=15
_extfamily=$(( (_family) - 15 ))
fi
_extmodel=$(( (_model & 0xF0 ) >> 4 ))
_lowmodel=$(( (_model & 0x0F ) >> 0 ))
echo $(( (_stepping & 0x0F) | (_lowmodel << 4) | (_lowfamily << 8) | (_extmodel << 16) | (_extfamily << 20) ))
}
[ -z "$HOME" ] && HOME="$(getent passwd "$(whoami)" | cut -d: -f6)"
mcedb_cache="$HOME/.mcedb"
update_fwdb()
@ -924,7 +949,9 @@ update_fwdb()
return 1
fi
sqlite3 "$mcedb_tmp" "ALTER TABLE \"Intel\" ADD COLUMN \"origin\" TEXT"
sqlite3 "$mcedb_tmp" "ALTER TABLE \"AMD\" ADD COLUMN \"origin\" TEXT"
sqlite3 "$mcedb_tmp" "UPDATE \"Intel\" SET \"origin\"='mce'"
sqlite3 "$mcedb_tmp" "UPDATE \"AMD\" SET \"origin\"='mce'"
echo OK "MCExtractor database revision $mcedb_revision"
@ -975,6 +1002,48 @@ update_fwdb()
fi
echo DONE "(version $_intel_latest_date)"
# now parse the most recent linux-firmware amd-ucode README file
_info_nol "Fetching latest amd-ucode README from linux-firmware project... "
linuxfw_url="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/amd-ucode/README"
linuxfw_tmp=$(mktemp -t smc-linuxfw-XXXXXX)
if command -v wget >/dev/null 2>&1; then
wget -q "$linuxfw_url" -O "$linuxfw_tmp"; ret=$?
elif command -v curl >/dev/null 2>&1; then
curl -sL "$linuxfw_url" -o "$linuxfw_tmp"; ret=$?
elif command -v fetch >/dev/null 2>&1; then
fetch -q "$linuxfw_url" -o "$linuxfw_tmp"; ret=$?
else
echo ERROR "please install one of \`wget\`, \`curl\` of \`fetch\` programs"
return 1
fi
if [ "$ret" != 0 ]; then
echo ERROR "error $ret while downloading linux-firmware README"
return $ret
fi
echo DONE
_info_nol "Parsing the README... "
nbfound=0
for line in $(grep -E 'Family=0x[0-9a-f]+ Model=0x[0-9a-f]+ Stepping=0x[0-9a-f]+: Patch=0x[0-9a-f]+' "$linuxfw_tmp" | tr " " ","); do
_debug "Parsing line $line"
_family=$( echo "$line" | grep -Eoi 'Family=0x[0-9a-f]+' | cut -d= -f2)
_model=$( echo "$line" | grep -Eoi 'Model=0x[0-9a-f]+' | cut -d= -f2)
_stepping=$(echo "$line" | grep -Eoi 'Stepping=0x[0-9a-f]+' | cut -d= -f2)
_version=$( echo "$line" | grep -Eoi 'Patch=0x[0-9a-f]+' | cut -d= -f2)
_version=$(printf "0x%08X" "$(( _version ))")
_cpuid=$(fms2cpuid "$_family" "$_model" "$_stepping")
_cpuid=$(printf "0x%08X" "$_cpuid")
_date="20000101"
_sqlstm="$(printf "INSERT INTO \"AMD\" (\"origin\",\"cpuid\",\"version\",\"yyyymmdd\") VALUES ('%s','%s','%s','%s');" "linux-firmware" "$(printf "%08X" "$_cpuid")" "$(printf "%08X" "$_version")" "$_date")"
_debug "family $_family model $_model stepping $_stepping cpuid $_cpuid"
_debug "$_sqlstm"
sqlite3 "$mcedb_tmp" "$_sqlstm"
nbfound=$((nbfound + 1))
unset _family _model _stepping _version _cpuid _date _sqlstm
done
echo "found $nbfound microcodes"
unset nbfound
dbversion="$mcedb_revision+i$_intel_latest_date"
if [ "$1" != builtin ] && [ -n "$previous_dbversion" ] && [ "$previous_dbversion" = "v$dbversion" ]; then
@ -1151,25 +1220,29 @@ while [ -n "${1:-}" ]; do
shift 2
elif [ "$1" = "--variant" ]; then
if [ -z "$2" ]; then
echo "$0: error: option --variant expects a parameter (1, 2, 3, 3a, 4 or l1tf)" >&2
echo "$0: error: option --variant expects a parameter (see --variant help)" >&2
exit 255
fi
case "$2" in
1) opt_cve_list="$opt_cve_list CVE-2017-5753"; opt_cve_all=0;;
2) opt_cve_list="$opt_cve_list CVE-2017-5715"; opt_cve_all=0;;
3) opt_cve_list="$opt_cve_list CVE-2017-5754"; opt_cve_all=0;;
3a) opt_cve_list="$opt_cve_list CVE-2018-3640"; opt_cve_all=0;;
4) opt_cve_list="$opt_cve_list CVE-2018-3639"; opt_cve_all=0;;
msbds) opt_cve_list="$opt_cve_list CVE-2018-12126"; opt_cve_all=0;;
mfbds) opt_cve_list="$opt_cve_list CVE-2018-12130"; opt_cve_all=0;;
mlpds) opt_cve_list="$opt_cve_list CVE-2018-12127"; opt_cve_all=0;;
mdsum) opt_cve_list="$opt_cve_list CVE-2019-11091"; opt_cve_all=0;;
l1tf) opt_cve_list="$opt_cve_list CVE-2018-3615 CVE-2018-3620 CVE-2018-3646"; opt_cve_all=0;;
taa) opt_cve_list="$opt_cve_list CVE-2019-11135"; opt_cve_all=0;;
mcepsc) opt_cve_list="$opt_cve_list CVE-2018-12207"; opt_cve_all=0;;
srbds) opt_cve_list="$opt_cve_list CVE-2020-0543"; opt_cve_all=0;;
help) echo "The following parameters are supported for --variant (can be used multiple times):";
echo "1, 2, 3, 3a, 4, msbds, mfbds, mlpds, mdsum, l1tf, taa, mcepsc, srbds, zenbleed";
exit 0;;
1) opt_cve_list="$opt_cve_list CVE-2017-5753"; opt_cve_all=0;;
2) opt_cve_list="$opt_cve_list CVE-2017-5715"; opt_cve_all=0;;
3) opt_cve_list="$opt_cve_list CVE-2017-5754"; opt_cve_all=0;;
3a) opt_cve_list="$opt_cve_list CVE-2018-3640"; opt_cve_all=0;;
4) opt_cve_list="$opt_cve_list CVE-2018-3639"; opt_cve_all=0;;
msbds) opt_cve_list="$opt_cve_list CVE-2018-12126"; opt_cve_all=0;;
mfbds) opt_cve_list="$opt_cve_list CVE-2018-12130"; opt_cve_all=0;;
mlpds) opt_cve_list="$opt_cve_list CVE-2018-12127"; opt_cve_all=0;;
mdsum) opt_cve_list="$opt_cve_list CVE-2019-11091"; opt_cve_all=0;;
l1tf) opt_cve_list="$opt_cve_list CVE-2018-3615 CVE-2018-3620 CVE-2018-3646"; opt_cve_all=0;;
taa) opt_cve_list="$opt_cve_list CVE-2019-11135"; opt_cve_all=0;;
mcepsc) opt_cve_list="$opt_cve_list CVE-2018-12207"; opt_cve_all=0;;
srbds) opt_cve_list="$opt_cve_list CVE-2020-0543"; opt_cve_all=0;;
zenbleed) opt_cve_list="$opt_cve_list CVE-2023-20593"; opt_cve_all=0;;
*)
echo "$0: error: invalid parameter '$2' for --variant, expected either 1, 2, 3, 3a, 4, l1tf, msbds, mfbds, mlpds, mdsum, taa, mcepsc or srbds" >&2;
echo "$0: error: invalid parameter '$2' for --variant, see --variant help for a list" >&2;
exit 255
;;
esac
@ -5939,6 +6012,7 @@ check_CVE_2023_20593_linux()
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
zenbleed_print_vuln=0
if [ "$opt_live" = 1 ]; then
if [ "$fp_backup_fix" = 1 ] && [ "$cpu_ucode_zenbleed" = 1 ]; then
# this should never happen, but if it does, it's interesting to know
@ -5948,7 +6022,7 @@ check_CVE_2023_20593_linux()
elif [ "$fp_backup_fix" = 1 ]; then
pvulnstatus $cve OK "Your kernel mitigates Zenbleed"
else
pvulnstatus $cve VULN "Your kernel is too old to mitigate Zenbleed and your CPU microcode doesn't mitigate it either"
zenbleed_print_vuln=1
fi
else
if [ "$cpu_ucode_zenbleed" = 1 ]; then
@ -5956,9 +6030,17 @@ check_CVE_2023_20593_linux()
elif [ -n "$kernel_zenbleed" ]; then
pvulnstatus $cve OK "Your kernel mitigates Zenbleed"
else
pvulnstatus $cve VULN "Your kernel is too old to mitigate Zenbleed and your CPU microcode doesn't mitigate it either"
zenbleed_print_vuln=1
fi
fi
if [ "$zenbleed_print_vuln" = 1 ]; then
pvulnstatus $cve VULN "Your kernel is too old to mitigate Zenbleed and your CPU microcode doesn't mitigate it either"
explain "Your CPU vendor may have a new microcode for your CPU model that mitigates this issue (refer to the hardware section above).\n " \
"Otherwise, the Linux kernel is able to mitigate this issue regardless of the microcode version you have, but in this case\n " \
"your kernel is too old to support this, your Linux distribution vendor might have a more recent version you should upgrade to.\n " \
"Note that either having an up to date microcode OR an up to date kernel is enough to mitigate this issue."
fi
unset zenbleed_print_vuln
else
pvulnstatus $cve "$status" "$msg"
fi
@ -6057,7 +6139,7 @@ exit 0 # ok
# The builtin version follows, but the user can download an up-to-date copy (to be stored in his $HOME) by using --update-fwdb
# To update the builtin version itself (by *modifying* this very file), use --update-builtin-fwdb
# %%% MCEDB v270+i20230614
# %%% MCEDB v271+i20230614
# I,0x00000611,0x00000B27,19961218
# I,0x00000612,0x000000C6,19961210
# I,0x00000616,0x000000C6,19961210
@ -6395,7 +6477,8 @@ exit 0 # ok
# I,0x000B06E0,0x00000010,20221219
# I,0x000B06F2,0x0000002C,20230104
# I,0x000B06F5,0x0000002C,20230104
# I,0x000C06F1,0x20000270,20230221
# I,0x000C06F1,0x21000030,20230410
# I,0x000C06F2,0x21000030,20230410
# A,0x00000F00,0x02000008,20070614
# A,0x00000F01,0x0000001C,20021031
# A,0x00000F10,0x00000003,20020325
@ -6419,13 +6502,17 @@ exit 0 # ok
# A,0x00100F00,0x01000020,20070326
# A,0x00100F20,0x010000CA,20100331
# A,0x00100F22,0x010000C9,20100331
# A,0x00100F2A,0x01000084,20000101
# A,0x00100F40,0x01000085,20080501
# A,0x00100F41,0x010000DB,20111024
# A,0x00100F42,0x01000092,20081021
# A,0x00100F43,0x010000C8,20100311
# A,0x00100F52,0x010000DB,20000101
# A,0x00100F53,0x010000C8,20000101
# A,0x00100F62,0x010000C7,20100311
# A,0x00100F80,0x010000DA,20111024
# A,0x00100F81,0x010000D9,20111012
# A,0x00100F91,0x010000D9,20000101
# A,0x00100FA0,0x010000DC,20111024
# A,0x00120F00,0x03000002,20100324
# A,0x00200F30,0x02000018,20070921
@ -6475,18 +6562,18 @@ exit 0 # ok
# A,0x00820F00,0x08200002,20180214
# A,0x00820F01,0x08200103,20190417
# A,0x00830F00,0x08300027,20190401
# A,0x00830F10,0x08301072,20220215
# A,0x00830F10,0x0830107A,20230517
# A,0x00850F00,0x08500004,20180212
# A,0x00860F00,0x0860000E,20200127
# A,0x00860F01,0x08600109,20220328
# A,0x00860F81,0x08608104,20220328
# A,0x00870F00,0x08700004,20181206
# A,0x00870F10,0x08701030,20220328
# A,0x008A0F00,0x08A00006,20220322
# A,0x008A0F00,0x08A00008,20230615
# A,0x00A00F00,0x0A000033,20200413
# A,0x00A00F10,0x0A001078,20230117
# A,0x00A00F11,0x0A0011CE,20230114
# A,0x00A00F12,0x0A001231,20230117
# A,0x00A00F10,0x0A001079,20230609
# A,0x00A00F11,0x0A0011D1,20230710
# A,0x00A00F12,0x0A001234,20230710
# A,0x00A00F80,0x0A008003,20211015
# A,0x00A00F82,0x0A008205,20220414
# A,0x00A10F00,0x0A10004B,20220309