From 463e33d61c3c1cbc0ebf94256f61ef1f22c08e22 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:42:13 +0000 Subject: [PATCH] fix: CVE-2017-5715 (Spectre V2): Red Hat specific fix for RSB Filling (fixes #235) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit built from commit d040c0ffc384ed68483f70eb5e8c051cd8e568f0 dated 2026-04-06 17:40:59 +0200 by Stéphane Lesimple (speed47_github@speed47.net) --- spectre-meltdown-checker.sh | 57 ++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/spectre-meltdown-checker.sh b/spectre-meltdown-checker.sh index 213fe79..461c983 100755 --- a/spectre-meltdown-checker.sh +++ b/spectre-meltdown-checker.sh @@ -13,7 +13,7 @@ # # Stephane Lesimple # -VERSION='26.32.0406634' +VERSION='26.32.0406653' # --- Common paths and basedirs --- readonly VULN_SYSFS_BASE="/sys/devices/system/cpu/vulnerabilities" @@ -2925,10 +2925,17 @@ write_msr_one_core() { mockvarname="SMC_MOCK_WRMSR_${msr}_RET" # shellcheck disable=SC2086,SC1083 if [ -n "$(eval echo \${$mockvarname:-})" ]; then - pr_debug "write_msr: MOCKING enabled for msr $msr func returns $(eval echo \$$mockvarname)" + local mockret + mockret="$(eval echo \$$mockvarname)" + pr_debug "write_msr: MOCKING enabled for msr $msr func returns $mockret" g_mocked=1 - [ "$(eval echo \$$mockvarname)" = $WRITE_MSR_RET_LOCKDOWN ] && g_msr_locked_down=1 - return "$(eval echo \$$mockvarname)" + if [ "$mockret" = "$WRITE_MSR_RET_LOCKDOWN" ]; then + g_msr_locked_down=1 + ret_write_msr_msg="kernel lockdown is enabled, MSR writes are restricted" + elif [ "$mockret" = "$WRITE_MSR_RET_ERR" ]; then + ret_write_msr_msg="could not write MSR" + fi + return "$mockret" fi # proactive lockdown detection via sysfs (vanilla 5.4+, CentOS 8+, Rocky 9+): @@ -2949,7 +2956,7 @@ write_msr_one_core() { load_msr fi if [ ! -e $CPU_DEV_BASE/0/msr ] && [ ! -e ${BSD_CPUCTL_DEV_BASE}0 ]; then - ret_read_msr_msg="is msr kernel module available?" + ret_write_msr_msg="msr kernel module is not available" return $WRITE_MSR_RET_ERR fi @@ -3044,10 +3051,11 @@ readonly MSR_IA32_MCU_OPT_CTRL=0x123 readonly READ_MSR_RET_OK=0 readonly READ_MSR_RET_KO=1 readonly READ_MSR_RET_ERR=2 +readonly READ_MSR_RET_LOCKDOWN=3 # Read an MSR register value across one or all cores # Args: $1=msr_address $2=cpu_index(optional, default 0) # Sets: ret_read_msr_value, ret_read_msr_value_hi, ret_read_msr_value_lo, ret_read_msr_msg -# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR +# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR | READ_MSR_RET_LOCKDOWN read_msr() { local ret core first_core_ret first_core_value if [ "$opt_cpu" != all ]; then @@ -3079,7 +3087,7 @@ read_msr() { # Read an MSR register value from a single CPU core # Args: $1=core $2=msr_address # Sets: ret_read_msr_value, ret_read_msr_value_hi, ret_read_msr_value_lo, ret_read_msr_msg -# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR +# Returns: READ_MSR_RET_OK | READ_MSR_RET_KO | READ_MSR_RET_ERR | READ_MSR_RET_LOCKDOWN read_msr_one_core() { local ret core msr msr_dec mockvarname msr_h msr_l mockval core="$1" @@ -3111,21 +3119,28 @@ read_msr_one_core() { mockvarname="SMC_MOCK_RDMSR_${msr}_RET" # shellcheck disable=SC2086,SC1083 if [ -n "$(eval echo \${$mockvarname:-})" ] && [ "$(eval echo \$$mockvarname)" -ne 0 ]; then - pr_debug "read_msr: MOCKING enabled for msr $msr func returns $(eval echo \$$mockvarname)" + local mockret + mockret="$(eval echo \$$mockvarname)" + pr_debug "read_msr: MOCKING enabled for msr $msr func returns $mockret" g_mocked=1 - return "$(eval echo \$$mockvarname)" + if [ "$mockret" = "$READ_MSR_RET_LOCKDOWN" ]; then + ret_read_msr_msg="kernel lockdown is enabled, MSR reads are restricted" + elif [ "$mockret" = "$READ_MSR_RET_ERR" ]; then + ret_read_msr_msg="could not read MSR" + fi + return "$mockret" fi # proactive lockdown detection via sysfs (vanilla 5.4+, CentOS 8+, Rocky 9+): - # if the kernel lockdown is set to integrity or confidentiality, MSR writes will be denied, - # so we can skip the write attempt entirely and avoid relying on dmesg parsing + # if the kernel lockdown is set to integrity or confidentiality, MSR reads will be denied, + # so we can skip the read attempt entirely and avoid relying on dmesg parsing if [ -e "$SYSKERNEL_BASE/security/lockdown" ]; then if grep -qE '\[integrity\]|\[confidentiality\]' "$SYSKERNEL_BASE/security/lockdown" 2>/dev/null; then - pr_debug "write_msr: kernel lockdown detected via $SYSKERNEL_BASE/security/lockdown" - g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_WRMSR_${msr}_RET=$WRITE_MSR_RET_LOCKDOWN") + pr_debug "read_msr: kernel lockdown detected via $SYSKERNEL_BASE/security/lockdown" + g_mockme=$(printf "%b\n%b" "$g_mockme" "SMC_MOCK_RDMSR_${msr}_RET=$READ_MSR_RET_LOCKDOWN") g_msr_locked_down=1 - ret_write_msr_msg="your kernel is locked down, please reboot with lockdown=none in the kernel cmdline and retry" - return $WRITE_MSR_RET_LOCKDOWN + ret_read_msr_msg="kernel lockdown is enabled, MSR reads are restricted" + return $READ_MSR_RET_LOCKDOWN fi fi @@ -3134,7 +3149,7 @@ read_msr_one_core() { load_msr fi if [ ! -e $CPU_DEV_BASE/0/msr ] && [ ! -e ${BSD_CPUCTL_DEV_BASE}0 ]; then - ret_read_msr_msg="is msr kernel module available?" + ret_read_msr_msg="msr kernel module is not available" return $READ_MSR_RET_ERR fi @@ -6696,7 +6711,15 @@ check_CVE_2017_5715_linux() { fi fi if [ "$rsb_filling" = 0 ]; then - if [ -n "$g_kernel_err" ]; then + # Red Hat kernels (RHEL 6/7/8) stuff RSB on context switch as part of + # their retpoline implementation when retp_enabled=1, but don't use the + # upstream X86_FEATURE_RSB_CTXSW flag or "Filling RSB on context switch" + # string. Detect this via the RHEL-specific debugfs knob. + # See https://bugzilla.redhat.com/show_bug.cgi?id=1616245#c8 + if [ "$retp_enabled" = 1 ]; then + rsb_filling=1 + pstatus green YES "Red Hat kernel with retpoline enabled includes RSB filling" + elif [ -n "$g_kernel_err" ]; then pstatus yellow UNKNOWN "couldn't check ($g_kernel_err)" else if grep -qw -e 'Filling RSB on context switch' "$g_kernel"; then