Reviewed-by: Jiaxin Wu <jiaxin...@intel.com>

> -----Original Message-----
> From: Xie, Yuanhao <yuanhao....@intel.com>
> Sent: Tuesday, May 7, 2024 2:09 PM
> To: devel@edk2.groups.io
> Cc: Liming Gao <gaolim...@byosoft.com.cn>; Wu, Jiaxin
> <jiaxin...@intel.com>; Ni, Ray <ray...@intel.com>; Xie, Yuanhao
> <yuanhao....@intel.com>
> Subject: [PATCH 2/3] MdeModulePkg: Refactors SmmLockBox.c.
> 
> The Lockbox Driver allows sensitive data to be securely stored in a
> designated area, thus protected against unauthorized access.
> 
> This patch does not introduce any functional modifications.
> It refactors the existing logic into a common component to facilitates
> the integration of the Standalone MM Lockbox Driver in an upcoming patch
> 
> Cc: Liming Gao <gaolim...@byosoft.com.cn>
> Cc: Jiaxin Wu <jiaxin...@intel.com>
> Cc: Ray Ni <ray...@intel.com>
> 
> Signed-off-by: Yuanhao Xie <yuanhao....@intel.com>
> ---
>  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c       | 361
> ++++++++++++---------------------------------------------------------------------------
> ----------------------------------------------------------------------------------------------
> ----------------------------------------------------------------------------------------------
> --------------------------------------------------------------------------------------
>  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf     |   4
> +++-
>  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.c |
> 384
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++
>  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.h |
> 148
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++
>  4 files changed, 547 insertions(+), 350 deletions(-)
> 
> diff --git a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
> index c1e15c596b..2774979c34 100644
> --- a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
> +++ b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.c
> @@ -9,7 +9,7 @@
>    SmmLockBoxHandler(), SmmLockBoxRestore(), SmmLockBoxUpdate(),
> SmmLockBoxSave()
>    will receive untrusted input and do basic validation.
> 
> -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
> 
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -31,360 +31,24 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <Protocol/LockBox.h>
>  #include <Guid/SmmLockBox.h>
> 
> -BOOLEAN  mLocked = FALSE;
> +#include "SmmLockBoxCommon.h"
> 
>  /**
> -  Dispatch function for SMM lock box save.
> +  This function is an abstraction layer for implementation specific Mm buffer
> validation routine.
> 
> -  Caution: This function may receive untrusted input.
> -  Restore buffer and length are external input, so this function will 
> validate
> -  it is in SMRAM.
> +  @param Buffer  The buffer start address to be checked.
> +  @param Length  The buffer length to be checked.
> 
> -  @param LockBoxParameterSave  parameter of lock box save
> +  @retval TRUE  This buffer is valid per processor architecture and not 
> overlap
> with SMRAM.
> +  @retval FALSE This buffer is not valid per processor architecture or 
> overlap
> with SMRAM.
>  **/
> -VOID
> -SmmLockBoxSave (
> -  IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE  *LockBoxParameterSave
> +BOOLEAN
> +IsBufferOutsideMmValid (
> +  IN EFI_PHYSICAL_ADDRESS  Buffer,
> +  IN UINT64                Length
>    )
>  {
> -  EFI_STATUS                       Status;
> -  EFI_SMM_LOCK_BOX_PARAMETER_SAVE  TempLockBoxParameterSave;
> -
> -  //
> -  // Sanity check
> -  //
> -  if (mLocked) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> -    LockBoxParameterSave->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  CopyMem (&TempLockBoxParameterSave, LockBoxParameterSave, sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SAVE));
> -
> -  //
> -  // Sanity check
> -  //
> -  if (!SmmIsBufferOutsideSmmValid
> ((UINTN)TempLockBoxParameterSave.Buffer,
> (UINTN)TempLockBoxParameterSave.Length)) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Save address in SMRAM or buffer
> overflow!\n"));
> -    LockBoxParameterSave->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  //
> -  // The SpeculationBarrier() call here is to ensure the above range check 
> for
> -  // the CommBuffer have been completed before calling into SaveLockBox().
> -  //
> -  SpeculationBarrier ();
> -
> -  //
> -  // Save data
> -  //
> -  Status = SaveLockBox (
> -             &TempLockBoxParameterSave.Guid,
> -             (VOID *)(UINTN)TempLockBoxParameterSave.Buffer,
> -             (UINTN)TempLockBoxParameterSave.Length
> -             );
> -  LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;
> -  return;
> -}
> -
> -/**
> -  Dispatch function for SMM lock box set attributes.
> -
> -  @param LockBoxParameterSetAttributes  parameter of lock box set
> attributes
> -**/
> -VOID
> -SmmLockBoxSetAttributes (
> -  IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> *LockBoxParameterSetAttributes
> -  )
> -{
> -  EFI_STATUS                                 Status;
> -  EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> TempLockBoxParameterSetAttributes;
> -
> -  //
> -  // Sanity check
> -  //
> -  if (mLocked) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> -    LockBoxParameterSetAttributes->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  CopyMem (&TempLockBoxParameterSetAttributes,
> LockBoxParameterSetAttributes, sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES));
> -
> -  //
> -  // Update data
> -  //
> -  Status = SetLockBoxAttributes (
> -             &TempLockBoxParameterSetAttributes.Guid,
> -             TempLockBoxParameterSetAttributes.Attributes
> -             );
> -  LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;
> -  return;
> -}
> -
> -/**
> -  Dispatch function for SMM lock box update.
> -
> -  Caution: This function may receive untrusted input.
> -  Restore buffer and length are external input, so this function will 
> validate
> -  it is in SMRAM.
> -
> -  @param LockBoxParameterUpdate  parameter of lock box update
> -**/
> -VOID
> -SmmLockBoxUpdate (
> -  IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE  *LockBoxParameterUpdate
> -  )
> -{
> -  EFI_STATUS                         Status;
> -  EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
> TempLockBoxParameterUpdate;
> -
> -  //
> -  // Sanity check
> -  //
> -  if (mLocked) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> -    LockBoxParameterUpdate->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  CopyMem (&TempLockBoxParameterUpdate, LockBoxParameterUpdate,
> sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE));
> -
> -  //
> -  // Sanity check
> -  //
> -  if (!SmmIsBufferOutsideSmmValid
> ((UINTN)TempLockBoxParameterUpdate.Buffer,
> (UINTN)TempLockBoxParameterUpdate.Length)) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Update address in SMRAM or
> buffer overflow!\n"));
> -    LockBoxParameterUpdate->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  //
> -  // The SpeculationBarrier() call here is to ensure the above range check 
> for
> -  // the CommBuffer have been completed before calling into
> UpdateLockBox().
> -  //
> -  SpeculationBarrier ();
> -
> -  //
> -  // Update data
> -  //
> -  Status = UpdateLockBox (
> -             &TempLockBoxParameterUpdate.Guid,
> -             (UINTN)TempLockBoxParameterUpdate.Offset,
> -             (VOID *)(UINTN)TempLockBoxParameterUpdate.Buffer,
> -             (UINTN)TempLockBoxParameterUpdate.Length
> -             );
> -  LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;
> -  return;
> -}
> -
> -/**
> -  Dispatch function for SMM lock box restore.
> -
> -  Caution: This function may receive untrusted input.
> -  Restore buffer and length are external input, so this function will 
> validate
> -  it is in SMRAM.
> -
> -  @param LockBoxParameterRestore  parameter of lock box restore
> -**/
> -VOID
> -SmmLockBoxRestore (
> -  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE  *LockBoxParameterRestore
> -  )
> -{
> -  EFI_STATUS                          Status;
> -  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> TempLockBoxParameterRestore;
> -
> -  CopyMem (&TempLockBoxParameterRestore, LockBoxParameterRestore,
> sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE));
> -
> -  //
> -  // Sanity check
> -  //
> -  if (!SmmIsBufferOutsideSmmValid
> ((UINTN)TempLockBoxParameterRestore.Buffer,
> (UINTN)TempLockBoxParameterRestore.Length)) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Restore address in SMRAM or
> buffer overflow!\n"));
> -    LockBoxParameterRestore->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> -    return;
> -  }
> -
> -  //
> -  // Restore data
> -  //
> -  if ((TempLockBoxParameterRestore.Length == 0) &&
> (TempLockBoxParameterRestore.Buffer == 0)) {
> -    Status = RestoreLockBox (
> -               &TempLockBoxParameterRestore.Guid,
> -               NULL,
> -               NULL
> -               );
> -  } else {
> -    Status = RestoreLockBox (
> -               &TempLockBoxParameterRestore.Guid,
> -               (VOID *)(UINTN)TempLockBoxParameterRestore.Buffer,
> -               (UINTN *)&TempLockBoxParameterRestore.Length
> -               );
> -    if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)) {
> -      //
> -      // Return the actual Length value.
> -      //
> -      LockBoxParameterRestore->Length =
> TempLockBoxParameterRestore.Length;
> -    }
> -  }
> -
> -  LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
> -  return;
> -}
> -
> -/**
> -  Dispatch function for SMM lock box restore all in place.
> -
> -  @param LockBoxParameterRestoreAllInPlace  parameter of lock box restore
> all in place
> -**/
> -VOID
> -SmmLockBoxRestoreAllInPlace (
> -  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
> *LockBoxParameterRestoreAllInPlace
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  Status                                                 = 
> RestoreAllLockBoxInPlace ();
> -  LockBoxParameterRestoreAllInPlace->Header.ReturnStatus =
> (UINT64)Status;
> -  return;
> -}
> -
> -/**
> -  Dispatch function for a Software SMI handler.
> -
> -  Caution: This function may receive untrusted input.
> -  Communicate buffer and buffer size are external input, so this function 
> will
> do basic validation.
> -
> -  @param DispatchHandle  The unique handle assigned to this handler by
> SmiHandlerRegister().
> -  @param Context         Points to an optional handler context which was
> specified when the
> -                         handler was registered.
> -  @param CommBuffer      A pointer to a collection of data in memory that 
> will
> -                         be conveyed from a non-SMM environment into an SMM
> environment.
> -  @param CommBufferSize  The size of the CommBuffer.
> -
> -  @retval EFI_SUCCESS Command is handled successfully.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SmmLockBoxHandler (
> -  IN EFI_HANDLE  DispatchHandle,
> -  IN CONST VOID  *Context         OPTIONAL,
> -  IN OUT VOID    *CommBuffer      OPTIONAL,
> -  IN OUT UINTN   *CommBufferSize  OPTIONAL
> -  )
> -{
> -  EFI_SMM_LOCK_BOX_PARAMETER_HEADER  *LockBoxParameterHeader;
> -  UINTN                              TempCommBufferSize;
> -
> -  DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Enter\n"));
> -
> -  //
> -  // If input is invalid, stop processing this SMI
> -  //
> -  if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
> -    return EFI_SUCCESS;
> -  }
> -
> -  TempCommBufferSize = *CommBufferSize;
> -
> -  //
> -  // Sanity check
> -  //
> -  if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size invalid!\n"));
> -    return EFI_SUCCESS;
> -  }
> -
> -  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer,
> TempCommBufferSize)) {
> -    DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer in SMRAM or
> overflow!\n"));
> -    return EFI_SUCCESS;
> -  }
> -
> -  LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
> *)((UINTN)CommBuffer);
> -
> -  LockBoxParameterHeader->ReturnStatus = (UINT64)-1;
> -
> -  DEBUG ((DEBUG_INFO, "SmmLockBox LockBoxParameterHeader - %x\n",
> (UINTN)LockBoxParameterHeader));
> -
> -  DEBUG ((DEBUG_INFO, "SmmLockBox Command - %x\n",
> (UINTN)LockBoxParameterHeader->Command));
> -
> -  switch (LockBoxParameterHeader->Command) {
> -    case EFI_SMM_LOCK_BOX_COMMAND_SAVE:
> -      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {
> -        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for SAVE
> invalid!\n"));
> -        break;
> -      }
> -
> -      SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
> *)(UINTN)LockBoxParameterHeader);
> -      break;
> -    case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:
> -      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {
> -        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> UPDATE invalid!\n"));
> -        break;
> -      }
> -
> -      SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
> *)(UINTN)LockBoxParameterHeader);
> -      break;
> -    case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:
> -      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {
> -        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> RESTORE invalid!\n"));
> -        break;
> -      }
> -
> -      SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> *)(UINTN)LockBoxParameterHeader);
> -      break;
> -    case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:
> -      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {
> -        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> SET_ATTRIBUTES invalid!\n"));
> -        break;
> -      }
> -
> -      SmmLockBoxSetAttributes
> ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> *)(UINTN)LockBoxParameterHeader);
> -      break;
> -    case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:
> -      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {
> -        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> RESTORE_ALL_IN_PLACE invalid!\n"));
> -        break;
> -      }
> -
> -      SmmLockBoxRestoreAllInPlace
> ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
> *)(UINTN)LockBoxParameterHeader);
> -      break;
> -    default:
> -      DEBUG ((DEBUG_ERROR, "SmmLockBox Command invalid!\n"));
> -      break;
> -  }
> -
> -  LockBoxParameterHeader->Command = (UINT32)-1;
> -
> -  DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Exit\n"));
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Smm Ready To Lock event notification handler.
> -
> -  It sets a flag indicating that SMRAM has been locked.
> -
> -  @param[in] Protocol   Points to the protocol's unique identifier.
> -  @param[in] Interface  Points to the interface instance.
> -  @param[in] Handle     The handle on which the interface was installed.
> -
> -  @retval EFI_SUCCESS   Notification handler runs successfully.
> - **/
> -EFI_STATUS
> -EFIAPI
> -SmmReadyToLockEventNotify (
> -  IN CONST EFI_GUID  *Protocol,
> -  IN VOID            *Interface,
> -  IN EFI_HANDLE      Handle
> -  )
> -{
> -  mLocked = TRUE;
> -  return EFI_SUCCESS;
> +  return SmmIsBufferOutsideSmmValid (Buffer, Length);
>  }
> 
>  /**
> @@ -438,6 +102,5 @@ SmmLockBoxEntryPoint (
>                         NULL
>                         );
>    ASSERT_EFI_ERROR (Status);
> -
>    return Status;
>  }
> diff --git
> a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> index 5081b2d7f2..f279706e90 100644
> --- a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +++ b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> @@ -6,7 +6,7 @@
>  #  This external input must be validated carefully to avoid security issue 
> like
>  #  buffer overflow, integer overflow.
>  #
> -#  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -30,6 +30,8 @@
> 
>  [Sources]
>    SmmLockBox.c
> +  SmmLockBoxCommon.c
> +  SmmLockBoxCommon.h
> 
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git
> a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.c
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.c
> new file mode 100644
> index 0000000000..5c6eae05af
> --- /dev/null
> +++
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.c
> @@ -0,0 +1,384 @@
> +/** @file
> +  LockBox SMM/MM driver.
> +
> +  Caution: This module requires additional review when modified.
> +  This driver will have external input - communicate buffer in SMM mode.
> +  This external input must be validated carefully to avoid security issue 
> like
> +  buffer overflow, integer overflow.
> +
> +  SmmLockBoxHandler(), SmmLockBoxRestore(), SmmLockBoxUpdate(),
> SmmLockBoxSave()
> +  will receive untrusted input and do basic validation.
> +
> +Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiSmm.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/LockBoxLib.h>
> +
> +#include <Protocol/SmmReadyToLock.h>
> +#include <Protocol/SmmCommunication.h>
> +#include <Protocol/LockBox.h>
> +#include <Guid/SmmLockBox.h>
> +#include "SmmLockBoxCommon.h"
> +
> +BOOLEAN  mLocked = FALSE;
> +
> +/**
> +  Dispatch function for SMM lock box save.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterSave  parameter of lock box save
> +**/
> +VOID
> +SmmLockBoxSave (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE  *LockBoxParameterSave
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_SMM_LOCK_BOX_PARAMETER_SAVE  TempLockBoxParameterSave;
> +
> +  //
> +  // Sanity check
> +  //
> +  if (mLocked) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> +    LockBoxParameterSave->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  CopyMem (&TempLockBoxParameterSave, LockBoxParameterSave, sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SAVE));
> +
> +  //
> +  // Sanity check
> +  //
> +  if (!IsBufferOutsideMmValid ((UINTN)TempLockBoxParameterSave.Buffer,
> (UINTN)TempLockBoxParameterSave.Length)) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Save address in SMRAM or buffer
> overflow!\n"));
> +    LockBoxParameterSave->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  //
> +  // The SpeculationBarrier() call here is to ensure the above range check 
> for
> +  // the CommBuffer have been completed before calling into SaveLockBox().
> +  //
> +  SpeculationBarrier ();
> +
> +  //
> +  // Save data
> +  //
> +  Status = SaveLockBox (
> +             &TempLockBoxParameterSave.Guid,
> +             (VOID *)(UINTN)TempLockBoxParameterSave.Buffer,
> +             (UINTN)TempLockBoxParameterSave.Length
> +             );
> +  LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;
> +  return;
> +}
> +
> +/**
> +  Dispatch function for SMM lock box set attributes.
> +
> +  @param LockBoxParameterSetAttributes  parameter of lock box set
> attributes
> +**/
> +VOID
> +SmmLockBoxSetAttributes (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> *LockBoxParameterSetAttributes
> +  )
> +{
> +  EFI_STATUS                                 Status;
> +  EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> TempLockBoxParameterSetAttributes;
> +
> +  //
> +  // Sanity check
> +  //
> +  if (mLocked) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> +    LockBoxParameterSetAttributes->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  CopyMem (&TempLockBoxParameterSetAttributes,
> LockBoxParameterSetAttributes, sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES));
> +
> +  //
> +  // Update data
> +  //
> +  Status = SetLockBoxAttributes (
> +             &TempLockBoxParameterSetAttributes.Guid,
> +             TempLockBoxParameterSetAttributes.Attributes
> +             );
> +  LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;
> +  return;
> +}
> +
> +/**
> +  Dispatch function for SMM lock box update.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterUpdate  parameter of lock box update
> +**/
> +VOID
> +SmmLockBoxUpdate (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE  *LockBoxParameterUpdate
> +  )
> +{
> +  EFI_STATUS                         Status;
> +  EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
> TempLockBoxParameterUpdate;
> +
> +  //
> +  // Sanity check
> +  //
> +  if (mLocked) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
> +    LockBoxParameterUpdate->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  CopyMem (&TempLockBoxParameterUpdate, LockBoxParameterUpdate,
> sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE));
> +
> +  //
> +  // Sanity check
> +  //
> +  if (!IsBufferOutsideMmValid
> ((UINTN)TempLockBoxParameterUpdate.Buffer,
> (UINTN)TempLockBoxParameterUpdate.Length)) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Update address in SMRAM or
> buffer overflow!\n"));
> +    LockBoxParameterUpdate->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  //
> +  // The SpeculationBarrier() call here is to ensure the above range check 
> for
> +  // the CommBuffer have been completed before calling into
> UpdateLockBox().
> +  //
> +  SpeculationBarrier ();
> +
> +  //
> +  // Update data
> +  //
> +  Status = UpdateLockBox (
> +             &TempLockBoxParameterUpdate.Guid,
> +             (UINTN)TempLockBoxParameterUpdate.Offset,
> +             (VOID *)(UINTN)TempLockBoxParameterUpdate.Buffer,
> +             (UINTN)TempLockBoxParameterUpdate.Length
> +             );
> +  LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;
> +  return;
> +}
> +
> +/**
> +  Dispatch function for SMM lock box restore.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterRestore  parameter of lock box restore
> +**/
> +VOID
> +SmmLockBoxRestore (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> *LockBoxParameterRestore
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> TempLockBoxParameterRestore;
> +
> +  CopyMem (&TempLockBoxParameterRestore, LockBoxParameterRestore,
> sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE));
> +
> +  //
> +  // Sanity check
> +  //
> +  if (!IsBufferOutsideMmValid
> ((UINTN)TempLockBoxParameterRestore.Buffer,
> (UINTN)TempLockBoxParameterRestore.Length)) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Restore address in SMRAM or
> buffer overflow!\n"));
> +    LockBoxParameterRestore->Header.ReturnStatus =
> (UINT64)EFI_ACCESS_DENIED;
> +    return;
> +  }
> +
> +  //
> +  // Restore data
> +  //
> +  if ((TempLockBoxParameterRestore.Length == 0) &&
> (TempLockBoxParameterRestore.Buffer == 0)) {
> +    Status = RestoreLockBox (
> +               &TempLockBoxParameterRestore.Guid,
> +               NULL,
> +               NULL
> +               );
> +  } else {
> +    Status = RestoreLockBox (
> +               &TempLockBoxParameterRestore.Guid,
> +               (VOID *)(UINTN)TempLockBoxParameterRestore.Buffer,
> +               (UINTN *)&TempLockBoxParameterRestore.Length
> +               );
> +    if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)) {
> +      //
> +      // Return the actual Length value.
> +      //
> +      LockBoxParameterRestore->Length =
> TempLockBoxParameterRestore.Length;
> +    }
> +  }
> +
> +  LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
> +  return;
> +}
> +
> +/**
> +  Dispatch function for SMM lock box restore all in place.
> +
> +  @param LockBoxParameterRestoreAllInPlace  parameter of lock box restore
> all in place
> +**/
> +VOID
> +SmmLockBoxRestoreAllInPlace (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
> *LockBoxParameterRestoreAllInPlace
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status                                                 = 
> RestoreAllLockBoxInPlace ();
> +  LockBoxParameterRestoreAllInPlace->Header.ReturnStatus =
> (UINT64)Status;
> +  return;
> +}
> +
> +/**
> +  Dispatch function for a Software SMI handler.
> +
> +  Caution: This function may receive untrusted input.
> +  Communicate buffer and buffer size are external input, so this function 
> will
> do basic validation.
> +
> +  @param DispatchHandle  The unique handle assigned to this handler by
> SmiHandlerRegister().
> +  @param Context         Points to an optional handler context which was
> specified when the
> +                         handler was registered.
> +  @param CommBuffer      A pointer to a collection of data in memory that 
> will
> +                         be conveyed from a non-SMM environment into an SMM
> environment.
> +  @param CommBufferSize  The size of the CommBuffer.
> +
> +  @retval EFI_SUCCESS Command is handled successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmLockBoxHandler (
> +  IN EFI_HANDLE  DispatchHandle,
> +  IN CONST VOID  *Context         OPTIONAL,
> +  IN OUT VOID    *CommBuffer      OPTIONAL,
> +  IN OUT UINTN   *CommBufferSize  OPTIONAL
> +  )
> +{
> +  EFI_SMM_LOCK_BOX_PARAMETER_HEADER  *LockBoxParameterHeader;
> +  UINTN                              TempCommBufferSize;
> +
> +  DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Enter\n"));
> +
> +  //
> +  // If input is invalid, stop processing this SMI
> +  //
> +  if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  TempCommBufferSize = *CommBufferSize;
> +
> +  //
> +  // Sanity check
> +  //
> +  if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size
> invalid!\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (!IsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize))
> {
> +    DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer in SMRAM or
> overflow!\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
> *)((UINTN)CommBuffer);
> +
> +  LockBoxParameterHeader->ReturnStatus = (UINT64)-1;
> +
> +  DEBUG ((DEBUG_INFO, "SmmLockBox LockBoxParameterHeader - %x\n",
> (UINTN)LockBoxParameterHeader));
> +
> +  DEBUG ((DEBUG_INFO, "SmmLockBox Command - %x\n",
> (UINTN)LockBoxParameterHeader->Command));
> +
> +  switch (LockBoxParameterHeader->Command) {
> +    case EFI_SMM_LOCK_BOX_COMMAND_SAVE:
> +      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {
> +        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for SAVE
> invalid!\n"));
> +        break;
> +      }
> +
> +      SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
> *)(UINTN)LockBoxParameterHeader);
> +      break;
> +    case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:
> +      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {
> +        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> UPDATE invalid!\n"));
> +        break;
> +      }
> +
> +      SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
> *)(UINTN)LockBoxParameterHeader);
> +      break;
> +    case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:
> +      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {
> +        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> RESTORE invalid!\n"));
> +        break;
> +      }
> +
> +      SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> *)(UINTN)LockBoxParameterHeader);
> +      break;
> +    case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:
> +      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {
> +        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> SET_ATTRIBUTES invalid!\n"));
> +        break;
> +      }
> +
> +      SmmLockBoxSetAttributes
> ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> *)(UINTN)LockBoxParameterHeader);
> +      break;
> +    case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:
> +      if (TempCommBufferSize < sizeof
> (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {
> +        DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for
> RESTORE_ALL_IN_PLACE invalid!\n"));
> +        break;
> +      }
> +
> +      SmmLockBoxRestoreAllInPlace
> ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
> *)(UINTN)LockBoxParameterHeader);
> +      break;
> +    default:
> +      DEBUG ((DEBUG_ERROR, "SmmLockBox Command invalid!\n"));
> +      break;
> +  }
> +
> +  LockBoxParameterHeader->Command = (UINT32)-1;
> +
> +  DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Exit\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Smm Ready To Lock event notification handler.
> +
> +  It sets a flag indicating that SMRAM has been locked.
> +
> +  @param[in] Protocol   Points to the protocol's unique identifier.
> +  @param[in] Interface  Points to the interface instance.
> +  @param[in] Handle     The handle on which the interface was installed.
> +
> +  @retval EFI_SUCCESS   Notification handler runs successfully.
> + **/
> +EFI_STATUS
> +EFIAPI
> +SmmReadyToLockEventNotify (
> +  IN CONST EFI_GUID  *Protocol,
> +  IN VOID            *Interface,
> +  IN EFI_HANDLE      Handle
> +  )
> +{
> +  mLocked = TRUE;
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.h
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.h
> new file mode 100644
> index 0000000000..2205c4fb3b
> --- /dev/null
> +++
> b/MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBoxCommon.h
> @@ -0,0 +1,148 @@
> +/** @file
> +  LockBox SMM/MM driver.
> +
> +  Caution: This module requires additional review when modified.
> +  This driver will have external input - communicate buffer in SMM mode.
> +  This external input must be validated carefully to avoid security issue 
> like
> +  buffer overflow, integer overflow.
> +
> +  SmmLockBoxHandler(), SmmLockBoxRestore(), SmmLockBoxUpdate(),
> SmmLockBoxSave()
> +  will receive untrusted input and do basic validation.
> +
> +Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiSmm.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/LockBoxLib.h>
> +
> +#include <Protocol/SmmReadyToLock.h>
> +#include <Protocol/SmmCommunication.h>
> +#include <Protocol/LockBox.h>
> +#include <Guid/SmmLockBox.h>
> +
> +/**
> +  This function is an abstraction layer for implementation specific Mm buffer
> validation routine.
> +
> +  @param Buffer  The buffer start address to be checked.
> +  @param Length  The buffer length to be checked.
> +
> +  @retval TRUE  This buffer is valid per processor architecture and not 
> overlap
> with SMRAM.
> +  @retval FALSE This buffer is not valid per processor architecture or 
> overlap
> with SMRAM.
> +**/
> +BOOLEAN
> +IsBufferOutsideMmValid (
> +  IN EFI_PHYSICAL_ADDRESS  Buffer,
> +  IN UINT64                Length
> +  );
> +
> +/**
> +  Dispatch function for SMM lock box save.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterSave  parameter of lock box save
> +**/
> +VOID
> +SmmLockBoxSave (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE  *LockBoxParameterSave
> +  );
> +
> +/**
> +  Dispatch function for SMM lock box set attributes.
> +
> +  @param LockBoxParameterSetAttributes  parameter of lock box set
> attributes
> +**/
> +VOID
> +SmmLockBoxSetAttributes (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
> *LockBoxParameterSetAttributes
> +  );
> +
> +/**
> +  Dispatch function for SMM lock box update.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterUpdate  parameter of lock box update
> +**/
> +VOID
> +SmmLockBoxUpdate (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE  *LockBoxParameterUpdate
> +  );
> +
> +/**
> +  Dispatch function for SMM lock box restore.
> +
> +  Caution: This function may receive untrusted input.
> +  Restore buffer and length are external input, so this function will 
> validate
> +  it is in SMRAM.
> +
> +  @param LockBoxParameterRestore  parameter of lock box restore
> +**/
> +VOID
> +SmmLockBoxRestore (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
> *LockBoxParameterRestore
> +  );
> +
> +/**
> +  Dispatch function for SMM lock box restore all in place.
> +
> +  @param LockBoxParameterRestoreAllInPlace  parameter of lock box restore
> all in place
> +**/
> +VOID
> +SmmLockBoxRestoreAllInPlace (
> +  IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
> *LockBoxParameterRestoreAllInPlace
> +  );
> +
> +/**
> +  Dispatch function for a Software SMI handler.
> +
> +  Caution: This function may receive untrusted input.
> +  Communicate buffer and buffer size are external input, so this function 
> will
> do basic validation.
> +
> +  @param DispatchHandle  The unique handle assigned to this handler by
> SmiHandlerRegister().
> +  @param Context         Points to an optional handler context which was
> specified when the
> +                         handler was registered.
> +  @param CommBuffer      A pointer to a collection of data in memory that 
> will
> +                         be conveyed from a non-SMM environment into an SMM
> environment.
> +  @param CommBufferSize  The size of the CommBuffer.
> +
> +  @retval EFI_SUCCESS Command is handled successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmLockBoxHandler (
> +  IN EFI_HANDLE  DispatchHandle,
> +  IN CONST VOID  *Context         OPTIONAL,
> +  IN OUT VOID    *CommBuffer      OPTIONAL,
> +  IN OUT UINTN   *CommBufferSize  OPTIONAL
> +  );
> +
> +/**
> +  Smm Ready To Lock event notification handler.
> +
> +  It sets a flag indicating that SMRAM has been locked.
> +
> +  @param[in] Protocol   Points to the protocol's unique identifier.
> +  @param[in] Interface  Points to the interface instance.
> +  @param[in] Handle     The handle on which the interface was installed.
> +
> +  @retval EFI_SUCCESS   Notification handler runs successfully.
> + **/
> +EFI_STATUS
> +EFIAPI
> +SmmReadyToLockEventNotify (
> +  IN CONST EFI_GUID  *Protocol,
> +  IN VOID            *Interface,
> +  IN EFI_HANDLE      Handle
> +  );
> --
> 2.39.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118709): https://edk2.groups.io/g/devel/message/118709
Mute This Topic: https://groups.io/mt/105955700/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to