The impact is focused on disclosing the content from privileged memory (including protected by virtualization technologies) to obtain sensitive data from processes running on the same processor (CPU). Cloud environments can have a greater impact when a physical server can be shared by multiple users or legal entities.
Binarly REsearch Team discovered that most enterprise vendors are affected by not correctly applying the Return Stack Buffer (RSB) stuffing mitigation logic before resuming from SMM (RSM instruction).
Incomplete list of affected devices can be found in our FirmwareBleed repository.
The impact is focused on disclosing the content from privileged memory (including protected by virtualization technologies) to obtain sensitive data from processes running on the same processor (CPU). Cloud environments can have a greater impact when a physical server can be shared by multiple users or legal entities.
The main CPU cores may use branch predictors other than the Return Stack Buffer (RSB) when the RSB underflows. Basically, RSB predict the target of RET instructions but when RSB underflows happen some of the CPU cores could fall back to using other branch predictors.
The best mitigation practice introduced by Intel in 2018 to address RSB behavior in SMM runtime was to leverage CALL instructions before returning from SMM context to avoid interfering with non-SMM usage of the retpoline mitigations. Regardless of whether Windows and Linux operating systems retpoline or not, if the SMM (SMI handlers) in system firmware don't have mitigations in place, an attack window will be available by design.
The original patch with mitigation code has been pushed by Intel to EDKII github repository in August 2018 to PiSmmCpuDxeSmm
module to mitigate CVE-2017-5715
by adding Return Stack Buffer stuffing logic before resuming from SMM.
On AMD and Intel processors based on EDKII system firmwares, the same mitigation logic applies and the same mistakes in implementation too.
As an example, most of the analyzed UEFI firmwares images (most recent versions) have multiple cases when Resume from SMM (RSM) in SmiEntry
is not mitigated. In the code of the PiSmmCpuDxeSmm
there are three RSM instructions and two RSB stuffing mitigations. However, the third one does not. Additionally, the first two (where RSB stuffing is present) are not used during exit from SMM. The following figure shows the correct applied RSB stuffing mitigation (StuffRsb EDKII macros):
.text:00000000000010C0 B8 10 00 00 00 mov eax, 10h
.text:00000000000010C5 Unroll1:
.text:00000000000010C5 E8 07 00 00 00 call Unroll2
.text:00000000000010CA SpecTrap1:
.text:00000000000010CA F3 90 pause
.text:00000000000010CC 0F AE E8 lfence
.text:00000000000010CF EB F9 jmp short SpecTrap1
.text:00000000000010D1 Unroll2:
.text:00000000000010D1 E8 07 00 00 00 call StuffLoop
.text:00000000000010D6 SpecTrap2:
.text:00000000000010D6 F3 90 pause
.text:00000000000010D8 0F AE E8 lfence
.text:00000000000010DB EB F9 jmp short SpecTrap2
.text:00000000000010DD StuffLoop:
.text:00000000000010DD 48 FF C8 dec rax
.text:00000000000010E0 75 E3 jnz short Unroll1
.text:00000000000010E2 48 81 C4 00 01 00 00 add rsp, 100h
.text:00000000000010E9 0F AA rsm
On the other hand, during our research we found places where RSB mitigations are missed before the RSM instruction is executed in SmiEntry
routine.
Code snippet without StuffRsb
mitigation before RSM in SmiEntry
presented below:
.text:0000000000002345 8A 00 mov al, [rax]
.text:0000000000002347 3C 00 cmp al, 0
.text:0000000000002349 74 0B jz short loc_2356
.text:000000000000234B B9 A2 06 00 00 mov ecx, 6A2h
.text:0000000000002350 89 D8 mov eax, ebx
.text:0000000000002352 31 D2 xor edx, edx
.text:0000000000002354 0F 30 wrmsr
.text:0000000000002356 0F AA rsm
This code pattern was obtained from Intel NUC M15.
On the another Intel-powered platforms, we also found alternate code patterns. Below is the similar code to SmiEntry
from EDKII without RSB stuffing:
.text:000000000000224E 48 8B 5C 24 08 mov rbx, [rsp+8]
.text:0000000000002253 48 81 EC 00 02 00 00 sub rsp, 200h
.text:000000000000225A 48 0F AE 04 24 fxsave64 qword ptr [rsp]
.text:000000000000225F 48 83 C4 E0 add rsp, 0FFFFFFFFFFFFFFE0h
.text:0000000000002263 48 89 D9 mov rcx, rbx
.text:0000000000002266 E8 9D 25 00 00 call nullsub_1
.text:000000000000226B 48 89 D9 mov rcx, rbx
.text:000000000000226E E8 99 25 00 00 call sub_480C
.text:0000000000002273 48 89 D9 mov rcx, rbx
.text:0000000000002276 E8 8D 25 00 00 call nullsub_1
.text:000000000000227B 48 83 C4 20 add rsp, 20h
.text:000000000000227F 48 0F AE 0C 24 fxrstor64 qword ptr [rsp]
.text:0000000000002284 48 81 C4 00 02 00 00 add rsp, 200h
.text:000000000000228B 48 8D 05 5E 00 00 00 lea rax, dword_22F0
.text:0000000000002292 48 31 DB xor rbx, rbx
.text:0000000000002295 8B 18 mov ebx, [rax]
.text:0000000000002297 48 8D 04 24 lea rax, [rsp]
.text:000000000000229B 48 05 00 10 00 00 add rax, 1000h
.text:00000000000022A1 48 25 00 F0 FF FF and rax, 0FFFFFFFFFFFFF000h
.text:00000000000022A7 48 29 D8 sub rax, rbx
.text:00000000000022AA 48 8D 0C 24 lea rcx, [rsp]
.text:00000000000022AE 48 29 C1 sub rcx, rax
.text:00000000000022B1 48 8D 7C 24 FF lea rdi, [rsp-1]
.text:00000000000022B6 48 31 C0 xor rax, rax
.text:00000000000022B9 FD std
.text:00000000000022BA F3 AA rep stosb
.text:00000000000022BC FC cld
.text:00000000000022BD 48 8D 05 B9 FE FF FF lea rax, byte_217D
.text:00000000000022C4 8A 00 mov al, [rax]
.text:00000000000022C6 3C 00 cmp al, 0
.text:00000000000022C8 74 16 jz short loc_22E0
.text:00000000000022CA 5A pop rdx
.text:00000000000022CB F7 C2 04 00 00 00 test edx, 4
.text:00000000000022D1 74 0D jz short loc_22E0
.text:00000000000022D3 B9 A0 01 00 00 mov ecx, 1A0h
.text:00000000000022D8 0F 32 rdmsr
.text:00000000000022DA 66 83 CA 04 or dx, 4
.text:00000000000022DE 0F 30 wrmsr
.text:00000000000022E0 0F AA rsm
Applying the RSB stuffing mitigation incorrectly can lead to the following security issues:
The Binarly team recommends applying mitigation code before every RSM instruction that can be executed during runtime.
Binarly REsearch Team