The stack buffer overflow vulnerability leads to arbitrary code execution in DXE driver on Intel platform.
BINARLY efiXplorer team has discovered a stack overflow vulnerability that allows a local root user to access UEFI DXE driver and execute arbitrary code.
Image preview
Potential Impact
An attacker with local privileged access can exploit this vulnerability to elevate privileges from ring 3 or ring 0 (depends on the operating system) to DXE driver and execute arbitrary code. A malicious code installed as a result of vulnerability exploitation in DXE driver could survive across an operating system (OS) boot process and runtime or modify NVRAM area on SPI flash storage (to gain persistence on target platform). Additionally, this vulnerability potentially could be used by malicious actors to bypass OS security mechanisms (modify privileged memory or runtime variables), influence on OS boot process, and in some cases would allow an attacker to hook or modify EFI Runtime services.
Image preview
Vulnerability Information
- BINARLY internal vulnerability identifier: BRLY-2021-053
- HP PSIRT assigned CVE identifier: CVE-2021-39299, CVE-2021-39300
- CVSS v3.1: 7.5 High AV:L/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H
Image preview
Affected Intel firmware
| Device/Firmware | File Name | SHA256 (File PE32 section) | File GUID |
|---|---|---|---|
HP EliteBook x360 1040 G8 | 0614 | eeeacc5cb2fad20df51283460831816aed4f67e769e4f57186180adf7d20da3d | 03E0A38B-3FBE-49CB-B311-726611213182 |
Image preview
Vulnerability description
The vulnerability exists in notifier for SA_POLICY_PROTOCOL located at offset 0x1538.
The pseudocode for this notifier is shown below:
__int64 SaPolisyProtocolNotifier()
{
EFI_STATUS Status; // rax
__int64 result; // rax
void *Interface; // [rsp+30h] [rbp-50h] BYREF
EFI_GUID VendorGuid; // [rsp+48h] [rbp-38h] BYREF
char IntelTechnologiesOptionsBuffer[40]; // [rsp+58h] [rbp-28h] BYREF
char Buffer; // [rsp+A0h] [rbp+20h] BYREF
UINTN DataSize; // [rsp+A8h] [rbp+28h] BYREF
...
VendorGuid.Data1 = 0xFB3B9ECE;
*&VendorGuid.Data2 = 0x49334ABA;
*VendorGuid.Data4 = 0xD6B49DB4;
*&VendorGuid.Data4[4] = 0x5123897D;
gBS->LocateProtocol(&SA_POLICY_PROTOCOL_GUID, 0, &Interface);
...
ZeroMem(&Buffer, 1);
DataSize = 0;
Status = gRT->GetVariable(L"PciePwrMgmt", &VendorGuid, 0, &DataSize, &Buffer);
if ( Status == EFI_BUFFER_TOO_SMALL )
Status = gRT->GetVariable(L"PciePwrMgmt", &VendorGuid, 0, &DataSize, &Buffer);
if ( Status || Buffer )
{
...
}
...
DataSize = 30;
gRT->GetVariable(L"IntelTechnologiesOptions", &VendorGuid, 0, &DataSize, IntelTechnologiesOptionsBuffer);
...
return result;
}
Consider following code snippet:
DataSize = 0;
Status = gRT->GetVariable(L"PciePwrMgmt", &VendorGuid, 0, &DataSize, &Buffer);
if ( Status == EFI_BUFFER_TOO_SMALL )
Status = gRT->GetVariable(L"PciePwrMgmt", &VendorGuid, 0, &DataSize, &Buffer);
The first call to GetVariable is occurs with DataSize = 0. Thus, after this call, the DataSize variable will contain the real size of the PciePwrMgmt NVRAM variable buffer and GetVariable will return EFI_BUFFER_TOO_SMALL.
During the second call, the data from the PciePwrMgmt NVRAM variable will be written to the Buffer stack variable.
The size of the Buffer on the stack is 1 byte, but a potential attacker could make the buffer size of the PciePwrMgmt NVRAM variable much larger than 1 which will lead to a stack overflow and arbitrary code execution.
Image preview
Disclosure timeline
This bug is subject to a 90 day disclosure deadline. After 90 days elapsed or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.
| Disclosure Activity | Date |
|---|---|
Intel PSIRT is notified | 2022-01-05 |
HP PSIRT provide patch release | 2022-01-27 |
BINARLY public disclosure date | 2022-05-23 |
Image preview
Acknowledgements
Image preview
See if you are impacted now with our Firmware Vulnerability Scanner
Find Vulnerabilities, Generate SBOMs & CBOMs