fix: CVE-2017-5715 (Spectre V2): Red Hat specific fix for RSB Filling (fixes #235)

built from commit d040c0ffc3
 dated 2026-04-06 17:40:59 +0200
 by Stéphane Lesimple (speed47_github@speed47.net)
This commit is contained in:
github-actions[bot]
2026-04-06 15:42:13 +00:00
parent 4d1af90420
commit 463e33d61c

View File

@@ -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