Many modern processors have issues that allow unprivileged attackers to bypass user-kernel or memory access restrictions, by exploiting speculative execution and shared resources. Currently, FreeBSD issued patches for Meltdown and Spectre V2.
Steps to patch Meltdown and Spectre vulnerabilities on FreeBSD
Make a backup – it cannot be stressed enough how important it is to make a backup of your system before you do this. Most of the actions listed in this post are written with the assumption that they will be executed by the root user running the bash or any other modern shell. I tested it on FreeBSD 11.x amd64 only.
Step 1 – Find your current FreeBSD version
Note down the current version.
Step 2 – Update your vulnerable system via a binary patch
Type the following to fetch, install, and patch Meltdown and Spectre vulnerabilities:
# freebsd-update fetch
Looking up update.FreeBSD.org mirrors... 3 mirrors found. Fetching metadata signature for 11.1-RELEASE from update6.freebsd.org... done. Fetching metadata index... done. Fetching 2 metadata patches.. done. Applying metadata patches... done. Inspecting system... done. Preparing to download files... done. Fetching 755 patches.....10....20....30....40....50....60.......750... done. Applying patches... done. Fetching 10 files... done.
# freebsd-update install
freebsd-update install Installing updates... done.
Step 3 – Reboot the FreeBSD box
Type the following shutdown command or reboot command
# shutdown -r now
Step 4 – Verification for Meltdown vulnerability on FreeBSD
The mitigation is known as Page Table Isolation (PTI). PTI largely separates kernel and user mode page tables, so that even during speculative execution most of the kernel’s data is unmapped and not accessible. A patched kernel will automatically enable PTI on Intel CPUs. The status can be checked by typing the following sysctl command:
# sysctl vm.pmap.pti
Another option is to download the Meltdown attack tools from here as follows:
# cd /tmp
# git clone https://github.com/dag-erling/meltdown
Cloning into 'meltdown'... remote: Counting objects: 123, done. remote: Total 123 (delta 0), reused 0 (delta 0), pack-reused 122 Receiving objects: 100% (123/123), 25.08 KiB | 1.19 MiB/s, done. Resolving deltas: 100% (73/73), done.
# cd /tmp/meltdown
cc -O2 -pipe -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -c meltdown.c -o meltdown.o cc -O2 -pipe -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -c util.c -o util.o cc -O2 -pipe -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -c amd64.S -o amd64.o (cd /tmp/meltdown && DEPENDFILE=.depend.mdattack NO_SUBDIR=1 make -f Makefile _RECURSING_PROGS=t PROG=mdattack ) echo mdattack.full: /usr/lib/libc.a >> .depend.mdattack Warning: Object directory not changed from original /tmp/meltdown cc -O2 -pipe -g -MD -MF.depend.mdattack.mdattack.o -MTmdattack.o -std=gnu99 -fstack-protector-strong -Qunused-arguments -c mdattack.c -o mdattack.o cc -O2 -pipe -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -o mdattack.full mdattack.o meltdown.o util.o amd64.o objcopy --only-keep-debug mdattack.full mdattack.debug objcopy --strip-debug --add-gnu-debuglink=mdattack.debug mdattack.full mdattack (cd /tmp/meltdown && DEPENDFILE=.depend.mdcheck NO_SUBDIR=1 make -f Makefile _RECURSING_PROGS=t PROG=mdcheck ) echo mdcheck.full: /usr/lib/libc.a >> .depend.mdcheck Warning: Object directory not changed from original /tmp/meltdown cc -O2 -pipe -g -MD -MF.depend.mdcheck.mdcheck.o -MTmdcheck.o -std=gnu99 -fstack-protector-strong -Qunused-arguments -c mdcheck.c -o mdcheck.o cc -O2 -pipe -g -std=gnu99 -fstack-protector-strong -Qunused-arguments -o mdcheck.full mdcheck.o meltdown.o util.o amd64.o objcopy --only-keep-debug mdcheck.full mdcheck.debug objcopy --strip-debug --add-gnu-debuglink=mdcheck.debug mdcheck.full mdcheck Warning: Object directory not changed from original /tmp/meltdown
The mdcheck tool attempts to determine if your system is vulnerable. The exact method varies from one platform to another. The result is indicated by the exit code: 0 for complete success, 1 for partial success (mostly seen in virtual machines) and 2 for complete failure:
# echo $?
The mdattack tool performs a Meltdown attack on a designated target specified as a virtual address and a length and prints the result:
Step 4 – Verification for Spectre 2 vulnerability on FreeBSD
The patches for retpoline approach to mitigation of the Spectre variant 2 vulnerability are in work, meantime we provide IBRS-based mitigation on Intel CPUs. The IBRS mitigation main disadvantage is the significant performance penalty. Also, due to the situation with the Intel microcode releases, it is somewhat not trivial to find working and stable blob.
AMD promised to provide the same mechanism, but its presence on AMD CPUs is detected differently than on Intel CPUs. We do not yet see any AMD CPU with this capability, so the supposed code to detect and use IBRS on AMD is not committed. Also, it seems that AMD specifies that even if SMEP is enabled, user/kernel boundary IBRS protection still requires Return Stack Buffer (RSB) flush. On Intels, it is only needed for CPUs not providing the SMEP.
You can verify that the IBRS-enabling microcode is loaded by looking at the dmesg buffer after the microcode update. If the line Structured Extended Features3=0xc000000<IBPB,STIBP> appears in the CPU features report, then IBPB (the IBRS barrier) feature is patched in, so system can perform the mitigation on user/kernel boundary. Current status of the mitigation can be verified with the sysctl hw.ibrs_active. If the CPU feature is present and not disabled by the tunable/sysctl hw.ibrs_disable, it should indicate activation.
# sysctl hw.ibrs_active
# sysctl hw.ibrs_disable
If you have access to the Intel microcode list, for instance https://newsroom.intel.com/wp-content/uploads/sites/11/2018/04/microcode-update-guidance.pdf, you can look at the version of the currently patched microcode as well. Use sysutils/x86info from ports, load the cpuctl(4) driver (already required for microcode load), and use the ‘-a’ switch to see the microcode version among other things:
# pkg install x86info
# kldload cpuctl
# x86info -a
Sample session from above commands: