Advisory ID:
BRLY-DVA-2025-011

Multiple SMM memory corruption vulnerabilities in SMM module on Gigabyte device (SMRAM write)

July 9, 2025
Severity:
High
CVSS Score
8.2
Public Disclosure Date:
July 9, 2025
CVE ID:

Summary

BINARLY REsearch team has discovered multiple memory corruption vulnerabilities in Gigabyte device firmware that could allow a potential attacker to write fixed or predictable data to an attacker-controlled address.
Vendors Affected Icon

Vendors Affected

AMI
Gigabyte
Affected Products icon

Affected Products

Multiple

Potential Impact

An attacker could exploit this vulnerability to elevate privileges from ring 0 to ring -2 and execute arbitrary code in System Management Mode, an environment more privileged than and completely isolated from the operating system (OS). Running arbitrary code in SMM also bypasses SMM-based SPI flash protections against modification, which can help an attacker to install a firmware backdoor/implant. Such malicious code in the firmware could persist through operating system reinstallations. In addition, this vulnerability could potentially be used by malicious actors to bypass security mechanisms provided by UEFI firmware, such as Secure Boot and some types of memory isolation for hypervisors.

This vulnerability was detected by the Deep Vulnerability Analysis (DVA) component from Binarly Platform

Vulnerability Information

  • BINARLY internal vulnerability identifier: BRLY-DVA-2025-011
  • CERT/CC assigned CVE identifier: CVE-2025-7029
  • CVSS v3.1: 8.2 High AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Affected firmware with confirmed impact by BINARLY team

Device Version OEM IBV Module Kind
GA-H110M-S2HP F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2V F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2V DDR3 F21e (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-DS2V DDR3 F22a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-DS2 FCa (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D2V F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2H DDR3 F21a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-A F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-Gaming 3 F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2 F27b (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110N F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2 DDR3 F20g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-WW F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-H DDR3 F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-DS2V F25b (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2H F26g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-H (rev. 1.0/1.1/1.2) F28a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-DS3H DDR3 F21f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-HD3 DDR3 F20i (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
G1.Sniper M7 F20h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150-HD3P F24h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-Gaming F20h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D3H F25d (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150-HD3 F23f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
G1.Sniper B7 F22g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-DS3P F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-DS2 DDR3 F20g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-D3H F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-DS2 (rev. 1.0/1.1/1.2) F28b (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D3V DDR3 F20h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2PV F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2PT F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D3V F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-D3H R2 TPM F22e (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-D3H R2 F24a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110-D3 F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2PV DDR3 F20g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2PH DDR3 F20g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150-HD3 DDR3 F20h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D3H DDR3 F21a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-D2V DDR3 F20g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110-D3A F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-S2PH F28b (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-DS3H F22h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150M-HD3 F22g (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110TN-E F23f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150N-GSM F24b (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150N Phoenix-WIFI F22f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-B150N Phoenix F20h (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110MSTX-HD3-ZK F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110TN-M F23f (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110TN-CM F26a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-H110M-M.2 F25a (2024-07-31) Gigabyte AMI OverClockSmiHandler SMM
GA-X150M-PRO ECC F22i (2024-08-14) Gigabyte AMI OverClockSmiHandler SMM
GA-X170-EXTREME ECC F21h (2024-08-01) Gigabyte AMI OverClockSmiHandler SMM

Vulnerability description

Let's consider the module e07a5de6ced42c97783bf81375729c78d4233eaa294820eb2624b83c9dcd644b.

The pseudocode of the vulnerable function at 0xB10 is shown below (SwSmiInputValue: 0xB2):

EFI_STATUS SwSmiHandler(
        EFI_HANDLE DispatchHandle,
        const void *Context,
        EFI_SMM_SW_CONTEXT *CommBuffer,
        UINTN *CommBufferSize)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS NUMPAD "+" TO EXPAND]

  ...
  Value = 0;
  DataSize = 0x5F;
  Length = 0;
  Count = 0;
  Status = gEfiSmmVariableProtocol->SmmGetVariable(
             L"OcSetup",
             &OC_SETUP_VARIABLE_GUID,
             &Attributes,
             &DataSize,
             &OcSetupData);
  if ( Status < 0 || !OcSetupData.OverclockingSupport )
    return Status;
  if ( CommBuffer && CommBufferSize )
    CpuIndex = CommBuffer->SwSmiCpuIndex;
  if ( CpuIndex == -1 )
    return EFI_UNSUPPORTED;

  Status = gEfiSmmCpuProtocol->ReadSaveState(
             gEfiSmmCpuProtocol,
             4,
             EFI_SMM_SAVE_STATE_REGISTER_RBX,
             CpuIndex,
             &RbxRegister);

  Status = gEfiSmmCpuProtocol->ReadSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RCX, CpuIndex, &Buffer);

  BiosSettingHeader = RbxRegister;
  BiosSettingEntries = (RbxRegister + 16);

  TurboBoostEnabled = IsTurboBoostEnabled();
  ProgrammableTdpLimit = IsProgrammableTdpLimit();
  ProgrammableTjOffset = IsProgrammableTjOffset();

  if ( Buffer > 2 )
  {
    Value = 0x8004;
    Status0 = gEfiSmmCpuProtocol->WriteSaveState(
                gEfiSmmCpuProtocol,
                4,
                EFI_SMM_SAVE_STATE_REGISTER_RBX,
                CpuIndex,
                &Value);
    Status = Status0;
    return Status0;
  }
  if ( !Buffer )
  {
    Length = 0x110;
    Count = 0x20;
    if ( TurboBoostEnabled )
    {
      Length += 8;
      ++Count;
      if ( ProgrammableTdpLimit )
      {
        Length += 32;
        Count += 4;
      }
      if ( ProgrammableTjOffset )
      {
        Length += 16;
        Count += 2;
        if ( gCoreThreadCount > 2 )
        {
          Length += 16;
          Count += 2;
        }
      }
    }
    if ( BiosSettingHeader->Signature != '2DB$' )
    {
      if ( BiosSettingHeader->Signature == '$DB$' )
      {
        // SMRAM write
        BiosSettingHeader->Signature = '2DB$';
        BiosSettingHeader->Length = Length;
        BiosSettingHeader->MajorRev = 2;
        BiosSettingHeader->MinorRev = 0;

        Value = 1;
      }
      else
      {
        Value = 0x8001;
      }
      Status0 = gEfiSmmCpuProtocol->WriteSaveState(
                  gEfiSmmCpuProtocol,
                  4,
                  EFI_SMM_SAVE_STATE_REGISTER_RBX,
                  CpuIndex,
                  &Value);
      Status = Status0;
      return Status0;
    }
    if ( BiosSettingHeader->Length > 0xC00 )
    {
      Value = 0x8008;
      Status0 = gEfiSmmCpuProtocol->WriteSaveState(
                  gEfiSmmCpuProtocol,
                  4,
                  EFI_SMM_SAVE_STATE_REGISTER_RBX,
                  CpuIndex,
                  &Value);
      Status = Status0;
      return Status0;
    }
    if ( BiosSettingHeader->Length <= Length )
    {
      if ( BiosSettingHeader->Length < 0xC )
      {
        Value = 32771;
        Status0 = gEfiSmmCpuProtocol->WriteSaveState(
                    gEfiSmmCpuProtocol,
                    4,
                    EFI_SMM_SAVE_STATE_REGISTER_RBX,
                    CpuIndex,
                    &Value);
        Status = Status0;
        return Status0;
      }
      if ( BiosSettingHeader->Length < Length )
      {
        // SMRAM write
        BiosSettingHeader->Length = Length;
        BiosSettingHeader->MajorRev = 2;
        BiosSettingHeader->MinorRev = 0;

        Value = 32770;
        Status0 = gEfiSmmCpuProtocol->WriteSaveState(
                    gEfiSmmCpuProtocol,
                    4,
                    EFI_SMM_SAVE_STATE_REGISTER_RBX,
                    CpuIndex,
                    &Value);
        Status = Status0;
        return Status0;
      }
      Value = 0;
      Status = gEfiSmmCpuProtocol->WriteSaveState(
                 gEfiSmmCpuProtocol,
                 4u,
                 EFI_SMM_SAVE_STATE_REGISTER_RBX,
                 CpuIndex,
                 &Value);

      // SMRAM write
      BiosSettingHeader->MajorRev = 2;
      BiosSettingHeader->MinorRev = 0;
    }
    else
    {

      // SMRAM write
      BiosSettingHeader->Length = Length;
      BiosSettingHeader->MajorRev = 2;
      BiosSettingHeader->MinorRev = 0;

      Value = 2;
      Status = gEfiSmmCpuProtocol->WriteSaveState(
                 gEfiSmmCpuProtocol,
                 4,
                 EFI_SMM_SAVE_STATE_REGISTER_RBX,
                 CpuIndex,
                 &Value);
    }

    // SMRAM write
    BiosSettingHeader->Count = Count;

    // SMRAM write
    BiosSettingEntries->BiosImplementationType = 0x29;
    BiosSettingEntries->SettingValue = OcSetupData.EnableGv;
    BiosSettingEntries[1].BiosImplementationType = 0;
    BiosSettingEntries[1].SettingValue = OcSetupData.CpuRatio;
    BiosSettingEntries[2].BiosImplementationType = 7;
    BiosSettingEntries[2].SettingValue = OcSetupData.tCL;
    BiosSettingEntries[3].BiosImplementationType = 8;
    BiosSettingEntries[3].SettingValue = OcSetupData.tRCDtRP;
    BiosSettingEntries[4].BiosImplementationType = 0xA;
    BiosSettingEntries[4].SettingValue = OcSetupData.tRAS;
    BiosSettingEntries[5].BiosImplementationType = 0xB;
    if ( OcSetupData.tWR )
      BiosSettingEntries[5].SettingValue = OcSetupData.tWR;
    else
      BiosSettingEntries[5].SettingValue = 0xFFFFFFFE;
    BiosSettingEntries[6].BiosImplementationType = 0x15;
    BiosSettingEntries[6].SettingValue = OcSetupData.tRFC;
    BiosSettingEntries[7].BiosImplementationType = 0x16;
    BiosSettingEntries[7].SettingValue = OcSetupData.tRRD;
    BiosSettingEntries[8].BiosImplementationType = 0x17;
    BiosSettingEntries[8].SettingValue = OcSetupData.tWTR;
    BiosSettingEntries[9].BiosImplementationType = 0x19;
    BiosSettingEntries[9].SettingValue = OcSetupData.tRTP;
    BiosSettingEntries[10].BiosImplementationType = 0x28;
    BiosSettingEntries[10].SettingValue = OcSetupData.tFAW;
    BiosSettingEntries[11].BiosImplementationType = 0x18;
    if ( OcSetupData.NModeSupport )
      BiosSettingEntries[11].SettingValue = OcSetupData.NModeSupport;
    else
      BiosSettingEntries[11].SettingValue = 0xFFFFFFFE;
    ...
  }
  if...
  if...
  return Status;
}

As we can see from the pseudocode, the pointers to the BiosSettingHeader and BiosSettingEntries buffers (where BiosSettingEntries is BiosSettingHeader + 16) are controlled by the attacker as they are derived from the RBX value obtained with gEfiSmmCpuProtocol->ReadSaveState. These buffers are not validated to avoid overlapping with SMRAM.

The function includes multiple write operations to the controlled buffer:

// SMRAM write
BiosSettingHeader->Signature = '2DB$';
BiosSettingHeader->Length = Length;
BiosSettingHeader->MajorRev = 2;
BiosSettingHeader->MinorRev = 0;
...
// SMRAM write
BiosSettingHeader->Count = Count;

// SMRAM write
BiosSettingEntries->BiosImplementationType = 0x29;
BiosSettingEntries->SettingValue = OcSetupData.EnableGv;
BiosSettingEntries[1].BiosImplementationType = 0;
BiosSettingEntries[1].SettingValue = OcSetupData.CpuRatio;
BiosSettingEntries[2].BiosImplementationType = 7;
BiosSettingEntries[2].SettingValue = OcSetupData.tCL;
BiosSettingEntries[3].BiosImplementationType = 8;
BiosSettingEntries[3].SettingValue = OcSetupData.tRCDtRP;
BiosSettingEntries[4].BiosImplementationType = 0xA;
BiosSettingEntries[4].SettingValue = OcSetupData.tRAS;
BiosSettingEntries[5].BiosImplementationType = 0xB;
...

This allows an attacker to corrupt the SMRAM if BiosSettingHeader (RBX) points to SMRAM or just before SMRAM.

Disclosure timeline

This vulnerability is subject to a 90 day disclosure period. After 90 days or when a patch has been made generally available (whichever comes first) the advisory will be publicly disclosed.

Disclosure Activity Date
CERT/CC is notified 2025-04-15
Gigabyte confirmed issue 2025-06-12
CERT/CC assigned CVE number 2025-07-02
BINARLY public disclosure date 2025-07-10

Acknowledgements

BINARLY REsearch team

References

Tags
AMI
Firmware
UEFI
FWHunt
See if you are impacted now with our Firmware Vulnerability Scanner