Skip to content

Commit ecee757

Browse files
PandiPanda69speed47
authored andcommitted
feat(inception): kernel checks + sbpb support detection
1 parent fb6933d commit ecee757

File tree

1 file changed

+79
-15
lines changed

1 file changed

+79
-15
lines changed

spectre-meltdown-checker.sh

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,7 +2704,8 @@ sys_interface_check()
27042704

27052705
# write_msr
27062706
# param1 (mandatory): MSR, can be in hex or decimal.
2707-
# param2 (optional): CPU index, starting from 0. Default 0.
2707+
# param2 (optional): value to write, can be in hex or decimal.
2708+
# param3 (optional): CPU index, starting from 0. Default 0.
27082709
WRITE_MSR_RET_OK=0
27092710
WRITE_MSR_RET_KO=1
27102711
WRITE_MSR_RET_ERR=2
@@ -2740,6 +2741,8 @@ write_msr_one_core()
27402741
_core="$1"
27412742
_msr_dec=$(( $2 ))
27422743
_msr=$(printf "0x%x" "$_msr_dec")
2744+
_value_dec=$(( $3 ))
2745+
_value=$(printf "0x%x" "$_value_dec")
27432746

27442747
write_msr_msg='unknown error'
27452748
: "${msr_locked_down:=0}"
@@ -2764,7 +2767,7 @@ write_msr_one_core()
27642767

27652768
_write_denied=0
27662769
if [ "$os" != Linux ]; then
2767-
cpucontrol -m "$_msr=0" "/dev/cpuctl$_core" >/dev/null 2>&1; ret=$?
2770+
cpucontrol -m "$_msr=$_value" "/dev/cpuctl$_core" >/dev/null 2>&1; ret=$?
27682771
else
27692772
# for Linux
27702773
# convert to decimal
@@ -2774,24 +2777,24 @@ write_msr_one_core()
27742777
# if wrmsr is available, use it
27752778
elif command -v wrmsr >/dev/null 2>&1 && [ "${SMC_NO_WRMSR:-}" != 1 ]; then
27762779
_debug "write_msr: using wrmsr"
2777-
wrmsr $_msr_dec 0 2>/dev/null; ret=$?
2780+
wrmsr $_msr_dec $_value_dec 2>/dev/null; ret=$?
27782781
# ret=4: msr doesn't exist, ret=127: msr.allow_writes=off
27792782
[ "$ret" = 127 ] && _write_denied=1
27802783
# or fallback to dd if it supports seek_bytes, we prefer it over perl because we can tell the difference between EPERM and EIO
27812784
elif dd if=/dev/null of=/dev/null bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>/dev/null && [ "${SMC_NO_DD:-}" != 1 ]; then
27822785
_debug "write_msr: using dd"
2783-
dd if=/dev/zero of=/dev/cpu/"$_core"/msr bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>/dev/null; ret=$?
2786+
awk "BEGIN{printf \"\%c\", $_value_dec}" | dd of=/dev/cpu/"$_core"/msr bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>/dev/null; ret=$?
27842787
# if it failed, inspect stderrto look for EPERM
27852788
if [ "$ret" != 0 ]; then
2786-
if dd if=/dev/zero of=/dev/cpu/"$_core"/msr bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>&1 | grep -qF 'Operation not permitted'; then
2789+
if aws "BEGIN{printf \"%c\", $_value_dec}" | dd of=/dev/cpu/"$_core"/msr bs=8 count=1 seek="$_msr_dec" oflag=seek_bytes 2>&1 | grep -qF 'Operation not permitted'; then
27872790
_write_denied=1
27882791
fi
27892792
fi
27902793
# or if we have perl, use it, any 5.x version will work
27912794
elif command -v perl >/dev/null 2>&1 && [ "${SMC_NO_PERL:-}" != 1 ]; then
27922795
_debug "write_msr: using perl"
27932796
ret=1
2794-
perl -e "open(M,'>','/dev/cpu/$_core/msr') and seek(M,$_msr_dec,0) and exit(syswrite(M,pack('H16',0)))"; [ $? -eq 8 ] && ret=0
2797+
perl -e "open(M,'>','/dev/cpu/$_core/msr') and seek(M,$_msr_dec,0) and exit(syswrite(M,pack(v4,$_value_dec)))"; [ $? -eq 8 ] && ret=0
27952798
else
27962799
_debug "write_msr: got no wrmsr, perl or recent enough dd!"
27972800
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_WRMSR_${_msr}_RET=$WRITE_MSR_RET_ERR")
@@ -2836,7 +2839,7 @@ write_msr_one_core()
28362839
else
28372840
ret=$WRITE_MSR_RET_KO
28382841
fi
2839-
_debug "write_msr: for cpu $_core on msr $_msr, ret=$ret"
2842+
_debug "write_msr: for cpu $_core on msr $_msr, value=$_value, ret=$ret"
28402843
mockme=$(printf "%b\n%b" "$mockme" "SMC_MOCK_WRMSR_${_msr}_RET=$ret")
28412844
return $ret
28422845
}
@@ -3530,6 +3533,28 @@ check_cpu()
35303533

35313534
fi
35323535

3536+
if is_amd || is_hygon; then
3537+
_info " * Selective Branch Predictor Barrier (SBPB)"
3538+
_info_nol " * PRED_CMD MSR is available: "
3539+
3540+
if [ "$opt_allow_msr_write" = 1 ]; then
3541+
# the MSR PRED_SBPB is at offset 0x49, BIT(7), write-only
3542+
write_msr 0x49 128; ret=$?
3543+
if [ $ret = $WRITE_MSR_RET_OK ]; then
3544+
pstatus green YES
3545+
cpuid_sbpb=1
3546+
elif [ $ret = $WRITE_MSR_RET_KO ]; then
3547+
pstatus yellow NO
3548+
else
3549+
pstatus yellow UNKNOWN "$write_msr_msg"
3550+
cpuid_sbpb=3
3551+
fi
3552+
else
3553+
pstatus yellow UNKNOWN "not allowed to write msr"
3554+
cpuid_sbpb=3
3555+
fi
3556+
fi
3557+
35333558
_info_nol " * CPU supports Transactional Synchronization Extensions (TSX): "
35343559
ret=$READ_CPUID_RET_KO
35353560
cpuid_rtm=0
@@ -6334,6 +6359,28 @@ check_CVE_2023_20569_linux() {
63346359
pstatus yellow NO
63356360
fi
63366361

6362+
_info_nol "* Kernel compiled with SRSO support "
6363+
if [ -r "$opt_config" ]; then
6364+
if grep -q '^CONFIG_CPU_SRSO=y' "$opt_config"; then
6365+
pstatus green YES
6366+
else
6367+
pstatus yellow NO "required for safe RET and ibpb_on_vmexit mitigations"
6368+
fi
6369+
else
6370+
pstatus yellow UNKNOWN "couldn't read your kernel configuration"
6371+
fi
6372+
6373+
_info_nol "* Kernel compiled with IBPB support "
6374+
if [ -r "$opt_config" ]; then
6375+
if grep -q '^CONFIG_CPU_IBPB_ENTRY=y' "$opt_config"; then
6376+
pstatus green YES
6377+
else
6378+
pstatus yellow NO "required for ibpb mitigation"
6379+
fi
6380+
else
6381+
pstatus yellow UNKNOWN "couldn't read your kernel configuration"
6382+
fi
6383+
63376384
if [ -n "$kernel_sro" ]; then
63386385

63396386
# TODO check mitigation
@@ -6342,20 +6389,30 @@ check_CVE_2023_20569_linux() {
63426389

63436390
# Zen & Zen2 : if the right IBPB microcode applied + SMT off --> not vuln
63446391
if [ "$cpu_family" = $(( 0x17 )) ]; then
6345-
_info_nol "* IBPB support: "
6392+
_info_nol " * IBPB support: "
63466393
if [ -n "$cpuid_ibpb" ]; then
63476394
pstatus green YES "$cpuid_ibpb"
63486395
else
63496396
pstatus red NO
63506397
fi
63516398

6352-
_info_nol "* SMT is enabled: "
6399+
_info_nol " * SMT is enabled: "
63536400
is_cpu_smt_enabled; smt_enabled=$?
63546401
if [ "$smt_enabled" = 0 ]; then
63556402
pstatus red YES
63566403
else
63576404
pstatus green NO
6358-
fi
6405+
fi
6406+
# Zen 3/4 microcode brings SBPB mitigation
6407+
elif [ "$cpu_family" = $(( 0x19 )) ]; then
6408+
_info_nol "* CPU supports SBPB: "
6409+
if [ "$cpuid_sbpb" = 1 ]; then
6410+
pstatus green YES
6411+
elif [ "$cpuid_sbpb" = 3 ]; then
6412+
pstatus yellow UNKNOWN "cannot write MSR"
6413+
else
6414+
pstatus yellow NO
6415+
fi
63596416
fi
63606417

63616418
elif [ "$sys_interface_available" = 0 ]; then
@@ -6367,13 +6424,20 @@ check_CVE_2023_20569_linux() {
63676424
if ! is_cpu_affected "$cve" ; then
63686425
# override status & msg in case CPU is not vulnerable after all
63696426
pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected"
6370-
elif [ "$cpu_family" = $(( 0x17 )) ] && [ "$smt_enabled" = 1 ] && [ -n "$cpuid_ibpb" ]; then
6371-
pvulnstatus "$cve" OK "IBPB supported and SMT is off"
6427+
elif [ "$cpu_family" = $(( 0x17 )) ]; then
6428+
if [ "$smt_enabled" = 1 ] && [ -n "$cpuid_ibpb" ]; then
6429+
pvulnstatus "$cve" OK "IBPB supported and SMT is off"
6430+
elif [ "$smt_enabled" != 1 ] && [ -n "$cpuid_ibpb" ]; then
6431+
pvulnstatus "$cve" VULN "SMT is enabled"
6432+
elif [ "$smt_enabled" = 1 ]; then
6433+
pvulnstatus "$cve" VULN "IBPB is not supported by your current microcode"
6434+
else
6435+
pvulnstatus "$cve" VULN "SMT is enabled and IBPB is not support by your current microcode"
6436+
fi
63726437
explain "Zen1/2 with SMT off aren't vulnerable after the right IBPB microcode has been applied. (https://github.com/torvalds/linux/commit/138bcddb86d8a4f842e4ed6f0585abc9b1a764ff#diff-17bd24a7a7850613cced545790ac30646097e8d6207348c2bd1845f397acb390R2272)"
63736438
elif [ -z "$msg" ]; then
6374-
# if msg is empty, sysfs check didn't fill it, rely on our own test
6375-
# TODO
6376-
pvulnstatus "$cve" UNK "further checks are required (WIP)"
6439+
# if msg is empty, sysfs check didn't fill it. If the kernel does not bring the mitigation, system vuln.
6440+
pvulnstatus $cve VULN "upgrade your kernel"
63776441
else
63786442
pvulnstatus $cve "$status" "$msg"
63796443
fi

0 commit comments

Comments
 (0)