Advisory ID:
BRLY-DVA-2024-013

[BRLY-DVA-2024-013] SMM memory corruption vulnerability in SMM module on Dell device (SMRAM write).

April 4, 2025
Severity:
High
CVSS Score
8.2
Public Disclosure Date:
April 4, 2025
CVE ID:

Summary

BINARLY REsearch team has discovered a SMM memory corruption vulnerability in a Dell device allowing a possible attacker to write fixed or predictable data to SMRAM. Exploiting this issue could lead to escalating privileges to SMM.
Vendors Affected Icon

Vendors Affected

Dell
Affected Products icon

Affected Products

No items found.

Potential Impact

An attacker can exploit this vulnerability to elevate privileges from ring 0 to ring -2, execute arbitrary code in System Management Mode - an environment more privileged than operating system (OS) and completely isolated from it. Running arbitrary code in SMM additionally bypasses SMM-based SPI flash protections against modifications, which can help an attacker to install a firmware backdoor/implant into BIOS. Such a malicious firmware code in BIOS could persist across operating system re-installs. Additionally, this vulnerability potentially could be used by malicious actors to bypass security mechanisms provided by UEFI firmware (for example, 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-2024-013
  • Dell PSIRT assigned CVE identifier: CVE-2024-32860
  • DSA identifier: DSA-2024-125
  • CVSS v3.1: 8.2 High AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Affected Dell firmware with confirmed impact by BINARLY team

Device name Unpacked firmware SHA256 Firmware version IBV Module name Module GUID Module SHA256 Module kind
Alienware Area 51m R2 cf79e46aefb1846f4267dff93714bedfa1b445695e7135d3df944639fac22df7 1.25.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 6ab61608d58b020349989904608117db089554c78052bb3537d4e7f6eb4761a8 SmmModule
Alienware Aurora R15 AMD fd331f58aa871b8c66bdf0bc51f36b1ae6274069ae10982e154bef6776449f0d 1.10.1 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 3d5750e52543e2853c21b09631e19dd344e82ff44eb98d81b5f386bbf51b924e SmmModule
Alienware Aurora R15 f2587b2f84c7c8c9eb1e1f116b2b4b6813e4c44b0c83109921020aed4b946393 1.11.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 6f497392d9da924d7496cc288cf2c9c2de968b549f2a0f00505606918371e2ee SmmModule
Alienware m15 R3 10698d72cf17eb875a48f3ca4480dea64a98faa83db6a822ac8487d2cd322661 1.26.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 0f6348134c2b14cef0753708f3a088ddb72d56852133c76fc29b50623a7493b9 SmmModule
Alienware m15 R4 5dfd1ca5cfe59a0e87d06539d0a1bd9ff30005d5ab4b9b7a18c439194c81ec59 1.20.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 6bef6c7b0e8acbddc1614af9b3482e79fc0f067ef1f871d3aa20a69db8634675 SmmModule
Inspiron 15 3502 27d39151de44da12dab8f0da98c17dbc0a643b781605c072c2801bad1f589382 1.15.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 cff2107c19e13f143e6059f67c5a9a73f81f10c8e9653b120a581912502490b4 SmmModule
Inspiron 15 3510 c04b81b78fb748b5e7a06e38f3e2cb79bc7963f46a736d8bb07b7a8b6a153b2e 1.18.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 98c4bb7a43902e05ea58e9ecd5a20cc92e02dd649326109ad9e294db5edc8664 SmmModule
Inspiron 15 3521 109e01605e969d06d26fe9e3776ef74a4cf55ec16358ac0c8524748c4722f57e 1.13.0 AMI DellDiagSmm 6983d90e-3ef7-4d09-8f36-63ae0c59cff2 ad97796b6a567021ff422510990f2d6e6d76fa41dca091ae7755409b621b6da3 SmmModule

For supported affected platforms, Dell has addressed this vulnerability in DSA-2024-125. All reported platforms have been determined to be End of Support Life.

Vulnerability description

Let's consider the vulnerability on the example of a module with SHA256 0f6348134c2b14cef0753708f3a088ddb72d56852133c76fc29b50623a7493b9. The pseudocode of the vulnerable function is presented below:

__int64 __fastcall SwSmiHandler(
        EFI_HANDLE DispatchHandle,
        const void *Context,
        UINTN *CommBuffer,
        UINTN *CommBufferSize)
{
  __int64 DellWmiSharedMem; // rax
  __int64 v5; // rdi
  int v7; // ecx
  int v8; // r9d
  unsigned int v9; // r8d
  unsigned int v10; // edx
  UINTN CpuIndex; // rbx
  char *v12; // rax
  __int64 v13; // r9
  char *v14; // rcx
  __int128 v15; // xmm1
  __int128 v16; // xmm0
  __int128 v17; // xmm1
  __int128 v18; // xmm0
  __int128 v19; // xmm1
  __int128 v20; // xmm0
  __int128 v21; // xmm1
  __int64 Status; // rax
  __int64 v23; // rax
  _DWORD *Ptr; // rcx
  unsigned int Data; // [rsp+30h] [rbp-D0h] BYREF
  EFI_GUID VendorGuid; // [rsp+38h] [rbp-C8h] BYREF
  UINTN DataSize; // [rsp+48h] [rbp-B8h] BYREF
  char v28; // [rsp+50h] [rbp-B0h] BYREF
  int Buffer; // [rsp+220h] [rbp+120h] BYREF
  unsigned int v30; // [rsp+224h] [rbp+124h] BYREF
  unsigned int v31; // [rsp+228h] [rbp+128h] BYREF
  int v32[9]; // [rsp+22Ch] [rbp+12Ch] BYREF
  char v33[464]; // [rsp+250h] [rbp+150h] BYREF
  _DWORD v34[3]; // [rsp+420h] [rbp+320h] BYREF
  unsigned int v35; // [rsp+42Ch] [rbp+32Ch] BYREF

  DellWmiSharedMem = gDellWmiSharedMem;
  v5 = 0;
  DataSize = 0;
  Data = 0;
  VendorGuid.Data1 = 0x8CC2B3F1;
  *&VendorGuid.Data2 = 0x4784EC41;
  *VendorGuid.Data4 = 0x5D4C4884;
  *&VendorGuid.Data4[4] = 0x91471358;
  if ( (gDellWmiSharedMem
     || ((DataSize = 4,
          (gRT->GetVariable(L"DELL_WMI_SHARED_MEM", &VendorGuid, 0, &DataSize, &Data) & 0x8000000000000000) != 0)
       ? (DellWmiSharedMem = gDellWmiSharedMem)
       : (DellWmiSharedMem = Data, gDellWmiSharedMem = Data),
         DellWmiSharedMem))
    && *DellWmiSharedMem == 'DWMI' )
  {
    if ( *(DellWmiSharedMem + 20) )
    {
      v7 = Buffer;
    }
    else
    {
      v7 = *(DellWmiSharedMem + 24);
      Buffer = v7;
    }
    if ( (*(DellWmiSharedMem + 20) & 0xFF00) != 0 )
    {
      v8 = v32[0];
    }
    else
    {
      v8 = *(DellWmiSharedMem + 28);
      v32[0] = v8;
    }
    if ( (*(DellWmiSharedMem + 20) & 0xFF0000) != 0 )
    {
      v9 = v30;
    }
    else
    {
      v9 = *(DellWmiSharedMem + 32);
      v30 = v9;
    }
    if ( (*(DellWmiSharedMem + 20) & 0xFF000000) != 0 )
    {
      v10 = v31;
    }
    else
    {
      v10 = *(DellWmiSharedMem + 36);
      v31 = v10;
    }
    if ( *(DellWmiSharedMem + 20) )
      v7 = DellWmiSharedMem + 48;
    Buffer = v7;
    if ( (*(DellWmiSharedMem + 20) & 0xFF00) != 0 )
      v8 = DellWmiSharedMem + 48;
    v32[0] = v8;
    CpuIndex = DataSize;
    if ( (*(DellWmiSharedMem + 20) & 0xFF0000) != 0 )
      v9 = DellWmiSharedMem + 48;
    v30 = v9;
    if ( (*(DellWmiSharedMem + 20) & 0xFF000000) != 0 )
    {
      v10 = DellWmiSharedMem + 48;
      v31 = DellWmiSharedMem + 48;
    }
  }
  else
  {
    CpuIndex = *CommBuffer;
    gEfiSmmCpuProtocol->ReadSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RAX, CpuIndex, &Buffer);
    gEfiSmmCpuProtocol->ReadSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RBX, CpuIndex, v32);
    gEfiSmmCpuProtocol->ReadSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RCX, CpuIndex, &v30);
    gEfiSmmCpuProtocol->ReadSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RDX, CpuIndex, &v31);
    v10 = v31;
    v9 = v30;
  }
  v12 = v33;
  v13 = 4;
  v14 = &v28;
  do
  {
    v15 = *(v14 + 1);
    *v12 = *v14;
    v16 = *(v14 + 2);
    *(v12 + 1) = v15;
    v17 = *(v14 + 3);
    *(v12 + 2) = v16;
    v18 = *(v14 + 4);
    *(v12 + 3) = v17;
    v19 = *(v14 + 5);
    *(v12 + 4) = v18;
    v20 = *(v14 + 6);
    *(v12 + 5) = v19;
    v21 = *(v14 + 7);
    v14 += 128;
    *(v12 + 6) = v20;
    v12 += 128;
    *(v12 - 1) = v21;
    --v13;
  }
  while ( v13 );
  if ( !v10 )
    goto LABEL_34;
  if ( !gAmiSmmBufferValidationProtocol )
    return EFI_ACCESS_DENIED;
  Status = (gAmiSmmBufferValidationProtocol->ValidateMemoryBuffer)(v10, v9);
  if ( Status >= 0 )
  {
LABEL_34:
    if ( gFuncTable[0] != -1 )
    {
      v23 = 0LL;
      while ( gFuncTable[v23 + 1] != LOBYTE(v34[0])
           || gFuncTable[v23] != 1
           && (gFuncTable[v23 + 2] != BYTE1(v34[0])
            || gFuncTable[v23] != 2
            && (gFuncTable[v23 + 3] != v35 || gFuncTable[v23] != 3 && gFuncTable[v23 + 4] != BYTE1(v35))) )
      {
        ++v5;
        v23 = 13 * v5;
        if ( gFuncTable[13 * v5] == -1 )
          return 0;
      }
      (*&gFuncTable[13 * v5 + 5])(v33, v34[0], v35, *(v34 + 1));
      Ptr = gDellWmiSharedMem;
      if ( *gDellWmiSharedMem == 'DWMI' )
      {
        *gDellWmiSharedMem = 0;
        Ptr[6] = v34[0];                        // unchecked write (SMRAM corruption)
        Ptr[7] = v35;                           // unchecked write (SMRAM corruption)
        Ptr[8] = v34[1];                        // unchecked write (SMRAM corruption)
        Ptr[9] = v34[2];                        // unchecked write (SMRAM corruption)
      }
      else
      {
        if ( v34[0] != Buffer )
          gEfiSmmCpuProtocol->WriteSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RAX, CpuIndex, v34);
        if ( v35 != v32[0] )
          gEfiSmmCpuProtocol->WriteSaveState(gEfiSmmCpuProtocol, 4, EFI_SMM_SAVE_STATE_REGISTER_RBX, CpuIndex, &v35);
        if ( v34[1] != v30 )
          gEfiSmmCpuProtocol->WriteSaveState(
            gEfiSmmCpuProtocol,
            4,
            EFI_SMM_SAVE_STATE_REGISTER_RCX,
            CpuIndex,
            &v34[1]);
        if ( v34[2] != v31 )
          gEfiSmmCpuProtocol->WriteSaveState(
            gEfiSmmCpuProtocol,
            4,
            EFI_SMM_SAVE_STATE_REGISTER_RDX,
            CpuIndex,
            &v34[2]);
      }
    }
    return 0;
  }
  return Status;
}

The GetVariable call initializes gDellWmiSharedMem with the value stored in the DELL_WMI_SHARED_MEM NVRAM variable. Since the DELL_WMI_SHARED_MEM NVRAM variable is controlled by an attacker, they can perform an arbitrary write operation here:

Ptr[6] = v34[0];                        // unchecked write (SMRAM corruption)
Ptr[7] = v35;                           // unchecked write (SMRAM corruption)
Ptr[8] = v34[1];                        // unchecked write (SMRAM corruption)
Ptr[9] = v34[2];                        // unchecked write (SMRAM corruption)

as Ptr is initialized from gDellWmiSharedMem.

In order to fix this vulnerability, all user-controllable offsets and pointers should be checked with SmmIsBufferOutsideSmmValid() or analogues before any write attempt.

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
Dell PSIRT is notified 2024-06-18
Dell PSIRT is confirmed issue 2024-08-21
BINARLY public disclosure date 2025-04-04

Acknowledgements

BINARLY REsearch team

Tags
No items found.
FWHunt
See if you are impacted now with our Firmware Vulnerability Scanner