-
-
Save Freaky/2560975d3c94246b86f464b8be75c967 to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# | |
# PROVIDE: zenbleed_workaround | |
# REQUIRE: root mountcritlocal microcode_update | |
# BEFORE: SERVERS | |
# KEYWORD: nojail resume | |
# Source: https://gist.github.com/Freaky/2560975d3c94246b86f464b8be75c967 | |
# | |
# Copyright (c) 2023 Thomas Hurst <[email protected]> | |
# License: https://opensource.org/license/mit/ | |
. /etc/rc.subr | |
name="zenbleed_workaround" | |
desc="Zenbleed MSR chicken bit workaround" | |
rcvar="zenbleed_workaround_enable" | |
extra_commands="resume" | |
start_precmd="check_zen2" | |
resume_precmd="${start_precmd}" | |
stop_precmd="${start_precmd}" | |
start_cmd="workaround_zenbleed" | |
resume_cmd="${start_cmd}" | |
stop_cmd="restore_zenbleed" | |
load_rc_config "${name}" | |
: "${zenbleed_workaround_enable:=NO}" | |
CPUCTL="/usr/sbin/cpucontrol" | |
check_zen2() { | |
if ! kldstat -q -m cpuctl; then | |
if ! kldload cpuctl > /dev/null 2>&1; then | |
warn "Can't load cpuctl module." | |
return 1 | |
fi | |
fi | |
authenticamd="0x68747541 0x444d4163 0x69746e65" | |
if ! ${CPUCTL} -i 0x0 /dev/cpuctl0 | grep -q "$authenticamd"; then | |
warn "Not an AMD processor, ignoring" | |
return 1 | |
fi | |
cpuid=$(${CPUCTL} -i 0x1 /dev/cpuctl0 | awk '{ print $4 }') | |
family=$(( ((cpuid & 0xf00) >> 8) + ((cpuid & 0x0ff00000) >> 20) )) | |
model=$(( (cpuid & 0xf0) >> 4 | (cpuid & 0x000f0000) >> 12 )) | |
# Zen 2 is Family 23 Model 49 - 160 | |
if ! { [ $family -eq 23 ] && [ $model -ge 49 ] && [ $model -le 160 ]; } then | |
warn "Not a Zen 2 processor, ignoring" | |
return 1 | |
fi | |
hmicrocode=$(${CPUCTL} -m 0x8b /dev/cpuctl0 | awk '{ print $4 }') | |
microcode=$((hmicrocode)) | |
# Numbers sourced from Linux patch: | |
# https://freshbsd.org/linux/linux/commit/0a9266b79cacdd02b888aed1308c308ad6d4ee4e | |
if [ $model -ge $((0x30)) ] && [ $model -le $((0x3f)) ] && [ $microcode -ge $((0x0830107a)) ] || | |
[ $model -ge $((0x60)) ] && [ $model -le $((0x67)) ] && [ $microcode -ge $((0x0860010b)) ] || | |
[ $model -ge $((0x68)) ] && [ $model -le $((0x6f)) ] && [ $microcode -ge $((0x08608105)) ] || | |
[ $model -ge $((0x70)) ] && [ $model -le $((0x7f)) ] && [ $microcode -ge $((0x08701032)) ] || | |
[ $model -ge $((0xa0)) ] && [ $model -le $((0xaf)) ] && [ $microcode -ge $((0x08a00008)) ]; then | |
warn "Known-good microcode detected: ${hmicrocode}, ignoring" | |
return 1 | |
fi | |
} | |
check_date() { | |
# Start whinging mid-December | |
if [ "$(/bin/date +%s)" -ge 1702684800 ]; then | |
warn "Zenbleed should be resolved by updated AMD microcode, please check." | |
warn "Updated microcode is provided by sysutils/devcpu-data" | |
fi | |
} | |
workaround_zenbleed() { | |
check_date | |
check_startmsgs && echo "Applying Zenbleed MSR workaround" | |
for D in /dev/cpuctl* | |
do | |
${CPUCTL} -m "0xc0011029|=0x200" "$D" | |
done | |
} | |
restore_zenbleed() { | |
check_startmsgs && echo "Removing Zenbleed MSR workaround" | |
for D in /dev/cpuctl* | |
do | |
${CPUCTL} -m "0xc0011029&=~0x200" "$D" | |
done | |
} | |
run_rc_command "$1" | |
Proof of concept BSD port: https://git.hardenedbsd.org/shawn.webb/zenbleed (be sure to co the shawn.webb/bsd/main
branch)
Thanks. I added a resume command (just pointing at start_cmd, no need to run restart or indirect it through a function I can see), and made it slightly less chatty.
Did you check that it will still check for the correct cpu ?
For me it seems like it will only check at start, not after resume.
So you can have a case where it will not initially start (like on an intel cpu), but after resume it will set the bit.
But maybe I don't really know how resume works, maybe it check if it succeed before resuming it.
Good point. I added a resume_precmd
.
I added known-good microcode checks (just EPYC "Rome" CPUs right now I believe), and a warning that appears if you use the script after mid December.
Discovered via https://discord.com/channels/727023752348434432/827065966416363570/1135689521338515578.
For those of us who were not previously in the know: https://en.wikipedia.org/wiki/Transient_execution_CPU_vulnerability (redirected from Zenbleed).