diff --git a/src/vulns/CVE-2023-20569.sh b/src/vulns/CVE-2023-20569.sh index 7e6838c..e7793fb 100644 --- a/src/vulns/CVE-2023-20569.sh +++ b/src/vulns/CVE-2023-20569.sh @@ -9,15 +9,25 @@ check_CVE_2023_20569() { # CVE-2023-20569 Inception (SRSO, speculative return stack overflow) - Linux mitigation check 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 smt_enabled kernel_srso_accurate_reporting status=UNK sys_interface_available=0 msg='' + kernel_srso_accurate_reporting=0 if sys_interface_check "$VULN_SYSFS_BASE/spec_rstack_overflow"; then # this kernel has the /sys interface, trust it over everything sys_interface_available=1 status=$ret_sys_interface_check_status + # kernels before the fix from dc6306ad5b0d (v6.6-rc6, backported to v6.5.6) + # incorrectly reported "Mitigation: safe RET, no microcode" as mitigated, + # when in fact userspace is still vulnerable because IBPB doesn't flush + # branch type predictions without the extending microcode. + # override the sysfs status in that case. + if echo "$ret_sys_interface_check_fullmsg" | grep -qi 'Mitigation:.*safe RET.*no microcode'; then + status=VULN + msg="Vulnerable: Safe RET, no microcode (your kernel incorrectly reports this as mitigated, it was fixed in more recent kernels)" + fi fi if [ "$opt_sysfs_only" != 1 ]; then @@ -65,6 +75,22 @@ check_CVE_2023_20569_linux() { fi fi + # check whether the running kernel has the corrected SRSO reporting + # (dc6306ad5b0d, v6.6-rc6, backported to v6.5.6): kernels with the fix + # contain the string "Vulnerable: Safe RET, no microcode" in their image, + # while older kernels only have "safe RET" (and append ", no microcode" dynamically). + pr_info_nol "* Kernel has accurate SRSO reporting: " + if [ -n "$g_kernel_err" ]; then + pstatus yellow UNKNOWN "$g_kernel_err" + elif grep -q 'Vulnerable: Safe RET, no microcode' "$g_kernel"; then + kernel_srso_accurate_reporting=1 + pstatus green YES + elif [ -n "$kernel_sro" ]; then + pstatus yellow NO "your kernel reports partial SRSO mitigations as fully mitigated, upgrade recommended" + else + pstatus yellow NO "your kernel is too old and doesn't have the SRSO mitigation logic" + fi + pr_info_nol "* Kernel compiled with IBPB_ENTRY support: " if [ -r "$opt_config" ]; then # CONFIG_CPU_IBPB_ENTRY: Linux < 6.9 @@ -134,37 +160,50 @@ check_CVE_2023_20569_linux() { # 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, so we rely on our own logic - # Zen/Zen2 - if [ "$cpu_family" = $((0x17)) ]; then - if [ "$smt_enabled" = 0 ]; then - pvulnstatus "$cve" VULN "SMT is enabled on your Zen/Zen2 CPU, which makes mitigation ineffective" - explain "For Zen/Zen2 CPUs, proper mitigation needs an up to date microcode, and SMT needs to be disabled (this can be done by adding \`nosmt\` to your kernel command line)" - elif [ -z "$kernel_sro" ]; then - pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic" - elif [ -n "$cap_ibpb" ]; then - pvulnstatus "$cve" OK "SMT is disabled and both your kernel and microcode support mitigation" + # if msg is empty, sysfs check didn't fill it, rely on our own test + if [ "$opt_sysfs_only" != 1 ]; then + # Zen/Zen2 + if [ "$cpu_family" = $((0x17)) ]; then + if [ "$smt_enabled" = 0 ]; then + pvulnstatus "$cve" VULN "SMT is enabled on your Zen/Zen2 CPU, which makes mitigation ineffective" + explain "For Zen/Zen2 CPUs, proper mitigation needs an up to date microcode, and SMT needs to be disabled (this can be done by adding \`nosmt\` to your kernel command line)" + elif [ -z "$kernel_sro" ]; then + pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic" + elif [ -n "$cap_ibpb" ]; then + pvulnstatus "$cve" OK "SMT is disabled and both your kernel and microcode support mitigation" + else + pvulnstatus "$cve" VULN "Your microcode is too old" + fi + # Zen3/Zen4 + elif [ "$cpu_family" = $((0x19)) ]; then + if [ -z "$kernel_sro" ]; then + pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic" + elif [ -z "$kernel_srso" ] && [ -z "$kernel_ibpb_entry" ]; then + pvulnstatus "$cve" VULN "Your kernel doesn't have either SRSO or IBPB_ENTRY compiled-in" + elif [ "$cap_sbpb" = 3 ]; then + pvulnstatus "$cve" UNK "Couldn't verify if your microcode supports IBPB (rerun with --allow-msr-write)" + elif [ "$cap_sbpb" = 2 ]; then + pvulnstatus "$cve" VULN "Your microcode doesn't support SBPB" + else + pvulnstatus "$cve" OK "Your kernel and microcode both support mitigation" + fi else - pvulnstatus "$cve" VULN "Your microcode is too old" - fi - # Zen3/Zen4 - elif [ "$cpu_family" = $((0x19)) ]; then - if [ -z "$kernel_sro" ]; then - pvulnstatus "$cve" VULN "Your kernel is too old and doesn't have the SRSO mitigation logic" - elif [ -z "$kernel_srso" ] && [ -z "$kernel_ibpb_entry" ]; then - pvulnstatus "$cve" VULN "Your kernel doesn't have either SRSO or IBPB_ENTRY compiled-in" - elif [ "$cap_sbpb" = 3 ]; then - pvulnstatus "$cve" UNK "Couldn't verify if your microcode supports IBPB (rerun with --allow-msr-write)" - elif [ "$cap_sbpb" = 2 ]; then - pvulnstatus "$cve" VULN "Your microcode doesn't support SBPB" - else - pvulnstatus "$cve" OK "Your kernel and microcode both support mitigation" + # not supposed to happen, as normally this CPU should not be affected and not run this code + pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" fi else - # not supposed to happen, as normally this CPU should not be affected and not run this code - pvulnstatus "$cve" OK "your CPU vendor reported your CPU model as not affected" + pvulnstatus "$cve" "$status" "$ret_sys_interface_check_fullmsg" fi else pvulnstatus "$cve" "$status" "$msg" + if echo "$msg" | grep -qi 'your kernel incorrectly reports this as mitigated'; then + explain "Your kernel's /sys interface reports 'Mitigation: safe RET, no microcode' for the SRSO vulnerability.\n" \ + "This was a bug in the kernel's reporting (fixed in v6.5.6/v6.6-rc6, commit dc6306ad5b0d):\n" \ + "the Safe RET mitigation alone only protects the kernel from userspace attacks, but without\n" \ + "the IBPB-extending microcode, userspace itself remains vulnerable because IBPB doesn't flush\n" \ + "branch type predictions. Newer kernels correctly report this as 'Vulnerable: Safe RET, no microcode'.\n" \ + "To fully mitigate, you need both the Safe RET kernel support AND an updated CPU microcode.\n" \ + "Updating your kernel to v6.5.6+ or v6.6+ will also give you accurate vulnerability reporting." + fi fi }