External Input

External input describes data that can be controlled by an attacker. Examples include:
  • UEFI capsule image
  • Boot logo in Bitmap (BMP) or Joint Photographic Experts Group (JPEG) format
  • Contents of file system partitions
  • Read/write variables
  • System Management Mode (SMM) communication buffer
  • Network packets
Previous Vulnerabilities:

Boot Logo Image

At BlackHat 2009, Invisible Things Lab demonstrated how to use a buffer overflow in BMP file processing to construct an attack and flash a new firmware. The BMP file is an external input where an attacker may input a large value for PixelWidth and PixelHeight. This causes BltBufferSize to overflow and results in a very small number. This is a typical integer overflow caused by multiplication.
EFI_STATUS ConvertBmpToGopBlt ()
/// ...
if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight
IsAllocated = FALSE;
if (*GopBlt == NULL) {
*GopBltSize = BltBufferSize;
*GopBlt = EfiLibAllocatePool (*GopBltSize);
To handle these cases, code should check for integer overflow using division, as shown below:
if (BmpHeader->PixelWidth > MAX_UINT / sizeof
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) / BmpHeader->PixelHeight) {

SMM Callout

At Black Hat DC 2009, Invisible Things Lab demonstrated a way to inject code into SMM. The SMM code referenced (ACPINV below) a function pointer in Advanced Configuration and Power Interface (ACPI) Non-Volatile Storage (NVS) memory and invoked this function address. An attacker may modify the function pointer address in ACPI NVS so it points to a malicious function.
mov [ACPINV+x], %rax
call *0x18(%rax)
A similar issue is also found in ThinkPad 2016. The SmmRuntimeCallHandle is the pointer in ACPI Reserved memory. As such, the attacker may replace this function pointer with any address.
This is shown in line with the statement: RtServices = (EFI_SMM_RT_CALLBACK_SERVICES *) SmmRtStruct->PrivateData.SmmRuntimeCallHandle; below.
SmmRuntimeManagementCallback (
IN EFI_HANDLE SmmImageHandle,
IN OUT VOID *CommunicationBuffer,
IN OUT UINTN *SourceSize
RtServices = NULL;
SmmRtStruct = (SMM_RUNTIME_COMMUNICATION_STRUCTURE *) CommunicationBuffer;
RtServices = (EFI_SMM_RT_CALLBACK_SERVICES *) SmmRtStruct->PrivateData.SmmRuntimeCallHandle;
if (RtServices != NULL) {
RtServices->CallbackFunction (RtServices->Context, mSmst, (VOID *) &SmmRtStruct->PrivateData);
SmmRtStruct->PrivateData.SmmRuntimeCallHandle = NULL;
It is critical that SMM never reference memory outside System Management RAM (SMRAM) for function pointers.
In the latest Intel processors, the SMM_Code_Access_Chk feature can be used to block code execution outside of the value set by the SMRAM Range Register (SMRR). This feature MUST be enabled if it is supported.
The latest versions of EDK II also enable Executable Disable (XD) for memory addresses outside of SMRAM.

SMM Communication

In CanSecWest 2015, a new class of SMM attack was disclosed. The attacker may construct a SMM communication buffer that points to memory owned by System Management RAM (SMRAM) or Virtual Machine Monitor (VMM), then pass this address into a System Management Interrupt (SMI) handler. This causes the SMI handler to perform the write for the attacker. This typically classified as a “confused deputy” attack. See the lines with CommBuffer and with the CopyMem statement below.
SmmVariableHandler ()
// ...
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;
switch (SmmVariableFunctionHeader->Function) {
Status = VariableServiceGetVariable (
(UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
VariableServiceGetVariable (
// ...
// ...
CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);
To mitigate this attack, the SMI handler is required to use the library service SmmIsBufferOutsideSmmValid() to check the communication buffer before accessing it.
ACPI table for Authenticated Code Module (ACM) is a signed binary module delivered by Intel. It is used to construct a dynamic root of trust for measurement (DRTM) environment. In 2011, Invisible Things Lab disclosed a way to hijack the SINIT ACM. The issue happens when the ACM code parses the untrusted ACPI DMA Remapping (DMAR) table. The DMAR table is used before validation of the address. As such the attacker may control the copied memory length and override the Intel Trusted Executable Technology (TXT) heap and SINIT ACM itself. See line 6741 below.
6675: mov (%edi),%esi
6677: cmpl $0x52414d44,(%esi)
; (DWORD*)esi == ’DMAR’?
667d: je 0x6697
6697: mov (%edi),%edi
6699: mov %edi,%es:0xa57
; var_a57 = &dmar
66a0: mov 0x4(%edi),%ecx
; ecx = dmar.len
66a3: push %ecx
66a4: add %edi,%ecx
66a6: mov %ecx,%es:0xa5b
; var_a5b = &dmar + dmar.len
6701: mov %es:0xa47,%edi
; edi = var_a47 (memory on the TXT heap)
6708: mov (%edi),%eax
670a: mov %es:0xa5b,%ebx
; ebx = &dmar + dmar.len
6711: sub %es:0xa57,%ebx
; ebx = dmar.len
6738: mov %es:0xa57,%esi
; var_a57 = &dmar
673f: mov %ebx, %ecx
6741: rep movsb %ds:(%esi),%es:(%edi)
; memcpy (var_a47, dmar, dmar.len)
Adding a check for the length field of untrusted data source is mandatory.

Capsule Image

Most UEFI firmware supports capsule based firmware update. In 2014, MITRE demonstrated how to use a vulnerability in the capsule coalesce process to attack the firmware update process.
This is another example of an integer overflow. NOTE: MemorySize if statement and Size += below.
CapsuleDataCoalesce (
IN OUT VOID **MemoryBase,
IN OUT UINTN *MemorySize
if (*MemorySize <= (CapsuleSize + DescriptorsSize)) {
GetCapsuleInfo (
// ...
} else {
Size += (UINTN) Desc->Length;
Before the code performs the addition, the code must use subtraction to check if the addition will cause an integer overflow.

Read/Write Variable

A read/write variable is another potential attack surface because it is easily controlled by an attacker. In CanSecWest 2014, MITRE demonstrated how to modify the “Setup” variable to bypass UEFI secure boot ImageVerificationPolicy.
The attack taught us that it is a bad idea to embed security policy in a read/write “Setup” variable.

S3 Boot Script

The S3 Boot Script is used to restore the register settings during the ACPI S3 resume process. In CanSecWest 2015, Invisible Things Lab found some firmware implementations did not protect the S3 script or the dispatch function code, so it remained in an OS-accessible ACPI memory region. This allowed an attacker to inject malicious boot script content to bypass the silicon lock register setting in the S3 Boot Script. See the use of EntryFunc and EntryPoint below.
BootScriptExecuteDispatch (IN UINT8 *Script)
EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch.EntryPoint);
Status = EntryFunc (NULL, NULL);
As a mitigation, the lockbox should be used to protect data used in the S3 resume phase.

Network for AMT

Intel® Active Management Technology (Intel® AMT) is a remote management feature in the Intel vPRO platform. In 2017, Embed disclosed an issue with Intel AMT where providing an empty response will cause password verification to succeed as if the attacker provided the admin password. See the use of strncmp and response.length below.
/* NETSTACK_CODE:20431FC8 */
if(strncmp(computed_response, response.value, response.length))
goto error;
return 0;
To avoid similar issues, network packet processing code should always be carefully reviewed.