Mitigating CVE-2021-28216: Secure FPDT Pointer Handling in UEFI

  • Thread Author
Boot firmware that writes or reads pointers from untrusted non‑volatile variables is a high‑risk pattern — CVE‑2021‑28216 is a classic example: an EDK II (TianoCore) implementation reads the BootPerformanceTable pointer from an NVRAM variable during PEI (Pre‑EFI Initialization), and multiple vendor advisories recommend disabling the FPDT S3 support by setting PcdFirmwarePerformanceDataTableS3Support to FALSE as a practical mitigation.

Background / overview​

The Firmware Performance Data Table (FPDT) and its BootPerformanceTable are ACPI constructs that let firmware record precise boot‑time and S3 suspend/resume timestamps and metrics for OS telemetry and diagnostics. FPDT entries are legitimate and useful: they help troubleshoot slow boots, identify long hardware init steps, and enable platform engineering to measure firmware changes. The FPDT format and table definitions are part of the ACPI/UEFI ecosystem and are consumed by both OSes and diagnostic tooling.
EDK II (TianoCore) implements FPDT support in firmware components (DXE/PEI modules) and uses a platform configuration value (a PCD — Platform Configuration Database token) to enable or disable certain behaviors. One such token appears in advisories as PcdFirmwarePerformanceDataTableS3Support; turning it off suppresses S3 performance‑table handling that otherwise writes/reads FPDT pointers into NVRAM. Multiple vulnerability trackers and distribution advisories reference this PCD as the recommended mitigation for CVE‑2021‑28216.
Why this matters now: although FPDT is not a novel feature, the way firmware authors populate and consume FPDT variables matters. If the BootPerformanceTable pointer value is taken from an NVRAM variable without adequate validation or locking, an attacker with the ability to write the same variable — whether locally, via a malicious OS agent, or through a compromised update path — can cause the firmware to dereference a crafted pointer during early boot. That can produce information disclosure, crashes, or even pointer‑based memory corruption depending on the platform and the pointer value. The NVD and downstream advisories treat this vulnerability with a high impact estimate because of these risks.

Technical anatomy: what the CVE says and why it matters​

Where it happens (PEI) and why early boot is sensitive​

The vulnerable code path is in the PEI phase — the earliest firmware stage after reset that sets up memory, HOBs, and platform configuration prior to DXE. PEI runs with minimal OS protections and often executes with full platform privileges. Mistakes here are costly: faults cause boot failures, and any memory corruption or pointer misuse can compromise the boot flow long before OS mitigations (KASLR, SMEP, etc.) exist to help contain an attack. The NVD description for CVE‑2021‑28216 explicitly notes the pointer read from an NVRAM variable in PEI.

What exactly is read — FPDT pointer semantics​

The firmware exposes a FIRMWARE_PERFORMANCE_VARIABLE that, per EDK2 headers, contains two EFI_PHYSICAL_ADDRESS fields: BootPerformanceTablePointer and S3PerformanceTablePointer. Those variables tell the OS where the firmware wrote the FPDT entries. If a BootPerformanceTablePointer value is read from NVRAM and trusted without sanity checks, a malicious value could cause the firmware to use an unexpected physical address as a table pointer. The EDK2 metadata that documents this struct shows the exact field names and their intent.

Attack surface and prerequisites​

Practical exploitation requires the ability to control or influence firmware NVRAM variables, or to cause the firmware to read an uninitialized or attacker‑controlled value. Common real‑world paths that lead to that capability include:
  • Local administrator or privileged OS components that can write efivars without variable locking enabled;
  • Firmware update utilities or tools that accept inputs from userland and write NVRAM variables (a frequent weak point in past UEFI issues);
  • Improperly designed vendor code that uses runtime/writable variables as trusted storage rather than locked, verified variables.
Because writing NVRAM typically requires local privileges (or an attacker with physical access and specialized tooling), the immediate attack vector is local. That said, the long list of past cases where signed utilities or flawed update paths allowed variable writes shows that local‑only exposure can still be practical in many ecosystems. Advisories therefore treat the vector as serious, with high confidentiality/integrity/availability impact on affected artifacts.

Failure modes​

If the pointer is invalid or attacker‑controlled, those are the likely consequences:
  • Information disclosure: reading or reporting a pointer to a memory region that OS or firmware will later export could leak kernel or platform addresses;
  • Denial of boot: dereferencing invalid pointers in PEI can trigger early‑boot faults and cause persistent boot failures or unrecoverable states;
  • Memory corruption: depending on the precise dereference and subsequent use, a crafted pointer could produce writes into firmware memory regions, enabling more severe persistence or integrity attacks (though proof of reliable RCE from this specific pointer read is not broadly documented).
Multiple vulnerability trackers classify this as a high‑impact local vulnerability and recommend targeted mitigations immediately.

What vendors and trackers recommend​

The universal short‑term recommendation in the metadata and distribution advisories is to disable S3 FPDT support by setting PcdFirmwarePerformanceDataTableS3Support = FALSE in the platform’s EDK II configuration, or to install vendor patches that implement proper validation and variable locking. Canonical’s Ubuntu advisory, OSV/NVD entries, and several distro trackers all mention this PCD recommendation.
Why that helps: disabling S3 FPDT support prevents the firmware from relying on the potentially writable NVRAM variable for the S3/Boot performance pointers. It removes the specific code path the advisories identify as reading the BootPerformanceTable pointer from NVRAM in PEI, thereby removing the immediate dereference risk while vendors produce and deliver a code fix. This is a high‑value emergency mitigation when a firmware update is not yet available for a given product image.
Caveat: flipping this PCD is a configuration change that affects S3 performance telemetry. For platforms that rely on FPDT records to analyze suspend/resume behavior, disabling S3 FPDT support will remove that telemetry (or move it to a different, audited mechanism). Firmware developers must weigh the operational cost of losing FPDT S3 metrics against the security gain; for most production‑sensitive environments the security tradeoff is the correct choice until a validated code fix is applied.

Practical remediation and mitigation plan​

Below is a prioritized plan for firmware engineers, OEM integrators, virtualization/cloud operators, and system administrators.

For firmware authors / OEM integrators (highest priority)​

  • Patch upstream EDK II modules or backport the vendor patch that addresses the unsafe NVRAM pointer read. Where vendors have published fixes, merge the upstream change and produce new firmware images. If a patch is available, this is the definitive fix.
  • If a patch cannot be applied immediately, set PcdFirmwarePerformanceDataTableS3Support to FALSE in the platform DEC/DSC so the S3 FPDT code path is disabled in produced firmware images. Rebuild and test firmware images thoroughly. Confirm that disabling the PCD removes the vulnerable NVRAM read.
  • Lock or protect NVRAM variables used for security‑sensitive data. Where firmware must store pointers or keys, ensure variables are set with appropriate attributes, validated on use, and secured by vendor variable locking mechanisms. The TianoCore secure guidelines explicitly warn against assuming variable contents are correct when variables are not locked.

For virtualization/cloud operators and OEM image builders​

  • Replace OVMF/edk2 images with patched versions from your vendor or distribution. Distributors (Debian/Ubuntu and others) have published edk2 updates that address multiple EDK II CVEs — apply those updates to base images and VM templates.
  • If you build custom OVMF images, flip the PCD described above during your build pipeline and regenerate your OVMF/firmware images. Coordinate this change with downstream teams; test S3 suspend/resume across representative hardware/VM configurations.

For system administrators and security teams​

  • Inventory: identify hosts and images that use EDK II (edk2, OVMF) firmware. For VMs, identify OVMF versions and the build provenance of firmware files in image repos. For physical devices, work with OEMs to obtain firmware attestation/patch timelines. Many distro advisories include package mappings for vulnerable edk2 builds — use those as a starting point.
  • Patch where possible: install vendor or distribution updates for edk2/ovmf and apply firmware updates from hardware vendors. If your vendor provides a firmware image with PCD changes shipped, apply it following normal maintenance windows.
  • Interim controls: where immediate patches are impossible, reduce local untrusted ability to write efivars (restrict who can run efibootmgr or efivarfs mounts), remove untrusted utilities that can write NVRAM variables, and enforce strict endpoint controls for admin privileges. Note these are blunt controls and may disrupt legitimate management workflows.

How to test and validate fixes​

  • Confirm PCD change in firmware build: after setting PcdFirmwarePerformanceDataTableS3Support = FALSE in your DEC/DSC, rebuild EDK II and verify that the resulting AutoGen or generated headers contain the expected PCD setting. Inspect the firmware binary / OVMF image to ensure the FPDT DXE/PEI module behavior has changed as expected.
  • Functional verification: exercise S3 suspend/resume on hardware or VM images to observe system behavior. The FPDT telemetry will be absent or altered when S3 support is disabled; validate that S3 still functions and that the platform resumes reliably. Use FPDT parser tools (EDK2 pytool extensions or equivalent) to confirm FPDT table presence/absence and verify no invalid BootPerformanceTable pointer is read.
  • Regression test: run full firmware functional tests (boot paths, capsule updates, Secure Boot verification) to ensure the PCD change produced no unintended regressions. For OEMs, include these tests in your build pipeline and require sign‑off before releasing firmware to customers.

Risk assessment and tradeoffs​

  • Security vs. telemetry: disabling S3 FPDT support trades away S3 performance measurements in order to remove an unsafe pointer read. For security‑conscious deployments where untrusted variable writes are possible, this is the safer default. For engineering teams that rely on FPDT telemetry for platform performance optimization, plan to reinstate measurements only after a validated code fix that performs robust validation and variable locking.
  • Attack feasibility: public trackers classify the attack vector as local with low complexity but high impact; that combination makes remediation urgent for multi‑tenant, shared, or developer platforms where local write access to efivars is possible. For strictly locked platforms (managed devices with locked variables and hardened firmware update chains), the practical exploitation window narrows, but inventory and verification are still required.
  • Vendor and distro readiness: many distribution advisories (Debian, Ubuntu) have mapped affected edk2/Ovmf package versions and published updates. Treat vendor package advisories as authoritative for image updates; do not assume that the absence of an advisement for a specific product implies that product is unaffected — inventory and direct verification are necessary.

Concrete developer checklist for fixing code (for EDK II maintainers)​

  • Audit all code paths that read NVRAM variables during PEI and DXE. Specifically, treat any variable that can be written at runtime as untrusted input. Add input validation, bounds checks, and sanity checks for pointer‑like values before dereference.
  • Prefer locked, read‑only variables or lock variables at runtime after the firmware writes them (where the platform policy allows variable locking). Do not use runtime‑writable variables as a substitute for secure storage of pointers or keys.
  • If a pointer must be persisted, store data in a format that includes integrity checks and versioning (for example, include a fixed magic, length, and checksum) so invalid or malicious values are rejected early. Add migration/version checks where table formats evolved.
  • Add defensive programming: initialize local temporaries, check allocation results, and avoid trusting cross‑phase variables without explicit validation. Upstream EDK II maintainers have adopted these practices in past fixes and expect maintainers to follow a similar pattern.

Detection and monitoring recommendations​

  • Log collection: capture early‑boot firmware logs and UEFI variables snapshots when possible. For large fleets, ingest boot telemetry into centralized observability to detect anomalous early‑boot crashes or repeated failures after firmware flashes.
  • Watch for signs of exploitation or failure: repeated PEI faults, S3 resume failures, or mismatched ACPI tables at boot time are strong signals that something is wrong. On virtualized hosts, check OVMF logs and config consistency for unexpected variable changes.
  • Harden update paths: ensure firmware update utilities and signed tooling are the only code that can write NVRAM variables needed by the boot path. Enforce code signing for update helpers and remove or strongly limit userland utilities with efivar write capability.

Final takeaways​

CVE‑2021‑28216 is a reminder that firmware telemetry features — FPDT included — must never be implemented in a way that trusts runtime‑writable storage as a secure source of pointers or bootstrap configuration. The immediate, pragmatic mitigation endorsed by multiple trackers is to set PcdFirmwarePerformanceDataTableS3Support = FALSE while vendors deliver validated code fixes that implement proper validation and variable locking. Apply distro/firmware vendor updates where available, audit your firmware build pipeline for PCD defaults, and treat any product that uses EDK II/OVMF as requiring explicit verification.
This is an actionable fix that balances safety and operational continuity: disable the S3 FPDT code path now if you cannot install a vetted firmware update, and plan the patch deployment and regression testing required to restore telemetry only after you confirm the pointer‑handling code has been corrected and the NVRAM variables are properly protected.
End of article.

Source: MSRC Security Update Guide - Microsoft Security Response Center