mirror of
https://github.com/speed47/spectre-meltdown-checker.git
synced 2026-04-07 17:23:18 +02:00
enh: detect IPBP return predictor bypass in Inception/SRSO ("PB-Inception") (#500)
AMD Zen 1-3 CPUs don't flush return predictions on IBPB, allowing cross-process Spectre attacks even with IBPB-on-entry active. The kernel fix (v6.12+, backported) adds RSB fill after IBPB on affected CPUs. Detect this gap by checking CPUID IBPB_RET bit and kernel ibpb_no_ret bug flag, and flag systems relying on IBPB without the RSB fill fix.
This commit is contained in:
@@ -467,6 +467,26 @@ check_cpu() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# IBPB_RET: CPUID EAX=0x80000008, ECX=0x00 return EBX[30] indicates IBPB also flushes
|
||||||
|
# return predictions (Zen4+). Without this bit, IBPB alone does not clear the return
|
||||||
|
# predictor, requiring an additional RSB fill (kernel X86_BUG_IBPB_NO_RET fix).
|
||||||
|
cap_ibpb_ret=''
|
||||||
|
if is_amd || is_hygon; then
|
||||||
|
pr_info_nol " * CPU indicates IBPB flushes return predictions: "
|
||||||
|
read_cpuid 0x80000008 0x0 $EBX 30 1 1
|
||||||
|
ret=$?
|
||||||
|
if [ $ret = $READ_CPUID_RET_OK ]; then
|
||||||
|
cap_ibpb_ret=1
|
||||||
|
pstatus green YES "IBPB_RET feature bit"
|
||||||
|
elif [ $ret = $READ_CPUID_RET_KO ]; then
|
||||||
|
cap_ibpb_ret=0
|
||||||
|
pstatus yellow NO
|
||||||
|
else
|
||||||
|
cap_ibpb_ret=-1
|
||||||
|
pstatus yellow UNKNOWN "$ret_read_cpuid_msg"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# STIBP
|
# STIBP
|
||||||
pr_info " * Single Thread Indirect Branch Predictors (STIBP)"
|
pr_info " * Single Thread Indirect Branch Predictors (STIBP)"
|
||||||
pr_info_nol " * SPEC_CTRL MSR is available: "
|
pr_info_nol " * SPEC_CTRL MSR is available: "
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ check_CVE_2023_20569() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_CVE_2023_20569_linux() {
|
check_CVE_2023_20569_linux() {
|
||||||
local status sys_interface_available msg kernel_sro kernel_sro_err kernel_srso kernel_ibpb_entry smt_enabled
|
local status sys_interface_available msg kernel_sro kernel_sro_err kernel_srso kernel_ibpb_entry kernel_ibpb_no_ret smt_enabled
|
||||||
status=UNK
|
status=UNK
|
||||||
sys_interface_available=0
|
sys_interface_available=0
|
||||||
msg=''
|
msg=''
|
||||||
@@ -25,6 +25,15 @@ check_CVE_2023_20569_linux() {
|
|||||||
status=VULN
|
status=VULN
|
||||||
msg="Vulnerable: Safe RET, no microcode (your kernel incorrectly reports this as mitigated, it was fixed in more recent kernels)"
|
msg="Vulnerable: Safe RET, no microcode (your kernel incorrectly reports this as mitigated, it was fixed in more recent kernels)"
|
||||||
fi
|
fi
|
||||||
|
# kernels before the IBPB_NO_RET fix (v6.12, backported to v6.11.5/v6.6.58/v6.1.114/v5.15.169/v5.10.228)
|
||||||
|
# don't fill the RSB after IBPB, so when sysfs reports an IBPB-based mitigation, the return predictor
|
||||||
|
# can still be poisoned cross-process (PB-Inception). Override sysfs in that case.
|
||||||
|
if [ "$status" = OK ] && echo "$ret_sys_interface_check_fullmsg" | grep -qi 'IBPB'; then
|
||||||
|
if [ "$cap_ibpb_ret" != 1 ] && ! grep -q 'ibpb_no_ret' "$g_kernel" 2>/dev/null; then
|
||||||
|
status=VULN
|
||||||
|
msg="Vulnerable: IBPB-based mitigation active but kernel lacks return prediction clearing after IBPB (PB-Inception, upgrade to kernel 6.12+)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$opt_sysfs_only" != 1 ]; then
|
if [ "$opt_sysfs_only" != 1 ]; then
|
||||||
@@ -117,6 +126,19 @@ check_CVE_2023_20569_linux() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check whether the kernel is aware of the IBPB return predictor bypass (PB-Inception).
|
||||||
|
# kernels with the fix (v6.12+, backported) contain the "ibpb_no_ret" bug flag string,
|
||||||
|
# and add an RSB fill after every IBPB on affected CPUs (Zen 1-3).
|
||||||
|
pr_info_nol "* Kernel is aware of IBPB return predictor bypass: "
|
||||||
|
if [ -n "$g_kernel_err" ]; then
|
||||||
|
pstatus yellow UNKNOWN "$g_kernel_err"
|
||||||
|
elif grep -q 'ibpb_no_ret' "$g_kernel"; then
|
||||||
|
kernel_ibpb_no_ret="ibpb_no_ret found in kernel image"
|
||||||
|
pstatus green YES "$kernel_ibpb_no_ret"
|
||||||
|
else
|
||||||
|
pstatus yellow NO
|
||||||
|
fi
|
||||||
|
|
||||||
# Zen & Zen2 : if the right IBPB microcode applied + SMT off --> not vuln
|
# Zen & Zen2 : if the right IBPB microcode applied + SMT off --> not vuln
|
||||||
if [ "$cpu_family" = $((0x17)) ]; then
|
if [ "$cpu_family" = $((0x17)) ]; then
|
||||||
pr_info_nol "* CPU supports IBPB: "
|
pr_info_nol "* CPU supports IBPB: "
|
||||||
@@ -166,7 +188,11 @@ check_CVE_2023_20569_linux() {
|
|||||||
elif [ -z "$kernel_sro" ]; then
|
elif [ -z "$kernel_sro" ]; then
|
||||||
pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic"
|
pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic"
|
||||||
elif [ -n "$cap_ibpb" ]; then
|
elif [ -n "$cap_ibpb" ]; then
|
||||||
pvulnstatus "$cve" OK "SMT is disabled and both your kernel and microcode support mitigation"
|
if [ "$cap_ibpb_ret" != 1 ] && [ -z "$kernel_ibpb_no_ret" ]; then
|
||||||
|
pvulnstatus "$cve" VULN "IBPB alone doesn't flush return predictions on this CPU, kernel update needed (PB-Inception, fixed in 6.12+)"
|
||||||
|
else
|
||||||
|
pvulnstatus "$cve" OK "SMT is disabled and both your kernel and microcode support mitigation"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
pvulnstatus "$cve" VULN "Your microcode is too old"
|
pvulnstatus "$cve" VULN "Your microcode is too old"
|
||||||
fi
|
fi
|
||||||
@@ -181,7 +207,11 @@ check_CVE_2023_20569_linux() {
|
|||||||
elif [ "$cap_sbpb" = 2 ]; then
|
elif [ "$cap_sbpb" = 2 ]; then
|
||||||
pvulnstatus "$cve" VULN "Your microcode doesn't support SBPB"
|
pvulnstatus "$cve" VULN "Your microcode doesn't support SBPB"
|
||||||
else
|
else
|
||||||
pvulnstatus "$cve" OK "Your kernel and microcode both support mitigation"
|
if [ "$cap_ibpb_ret" != 1 ] && [ -z "$kernel_ibpb_no_ret" ] && [ -n "$kernel_ibpb_entry" ]; then
|
||||||
|
pvulnstatus "$cve" VULN "IBPB alone doesn't flush return predictions on this CPU, kernel update needed (PB-Inception, fixed in 6.12+)"
|
||||||
|
else
|
||||||
|
pvulnstatus "$cve" OK "Your kernel and microcode both support mitigation"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# not supposed to happen, as normally this CPU should not be affected and not run this code
|
# not supposed to happen, as normally this CPU should not be affected and not run this code
|
||||||
|
|||||||
Reference in New Issue
Block a user