Skip to main content
This vulnerability consists of a stack-based buffer overflow in the SMI handler of a Lenovo UEFI firmware. The relevant code of the affected component is as follows:
The fourth call to gEfiSmmCpuProtocol->ReadSaveState initializes the RdiReg variable with the pointer value specified in EFI_SMM_SAVE_STATE_REGISTER_RDI. Further in the code, the call to CopyMem uses fields from a structure pointed to by RdiReg + 0x38 as its SourceBuffer and Length parameters. For reference, the CopyMem prototype is as follows:
Name is attacker-controlled and Var->VariableNameSize is not validated before the call to CopyMem, thus allowing an attacker to overflow the stack-allocated buffer with attacker-controllable data.

Finding the vulnerable function

An easy approach is to match these five calls to gEfiSmmCpuProtocol->ReadSaveState in a row and later retrieve the address of the fourth one. The following disassembled code represents this part (dynamic operand values are masked with ..):
The pattern below, especially when combined with the rest of the rule logic, is generic enough to catch variations of the function of interest while remaining strict enough to avoid false positives. As always, there is a trade-off.
The two-dot sequence (..) matches any single byte. It is also possible to match nibbles using a single dot; for example, .f matches any byte whose low nibble is f (e.g., 0f, 1f, …, ff).

Finding the call to CopyMem

Here is the disassembled code around the call to CopyMem:
And here’s a pattern to locate this call:

Annotating and returning evidence

The final step is to annotate the appropriate addresses and return evidence. The complete check function is as follows: