public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing
@ 2024-02-13 21:09 Laszlo Ersek
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes Laszlo Ersek
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-13 21:09 UTC (permalink / raw)
  To: devel
  Cc: Dun Tan, Gerd Hoffmann, Liming Gao, Michael D Kinney, Rahul Kumar,
	Ray Ni

Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4682

Personal CI run (in progress):
https://github.com/tianocore/edk2/pull/5370

Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
2023-12-12) introduced a NULL pointer dereference to PiSmmCpuDxeSmm on
such platforms that do not produce the "gSmmBaseHobGuid" GUID HOB at
all.

Please see the multi-step analysis in the following thread:

  [edk2-devel] [PATCH 1/1] OvmfPkg/QemuVideoDxe: purge VbeShim
  https://edk2.groups.io/g/devel/message/115377
  message-id: <20240213085925.687848-1-kraxel@redhat.com>

This issue needs to be fixed for edk2-stable202402.

Cc: Dun Tan <dun.tan@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>

Best regards,
Laszlo

Laszlo Ersek (2):
  UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is
    missing

 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 47 +++++++++++++++-----
 1 file changed, 35 insertions(+), 12 deletions(-)


base-commit: 8801c75b4d77c2e6e06b3ddc8560e0db590f6342


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115416): https://edk2.groups.io/g/devel/message/115416
Mute This Topic: https://groups.io/mt/104341340/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-13 21:09 [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
@ 2024-02-13 21:09 ` Laszlo Ersek
  2024-02-13 21:35   ` Laszlo Ersek
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
  2024-02-14  9:01 ` [edk2-devel] [edk2-stable202402 PATCH 0/2] " Gerd Hoffmann
  2 siblings, 1 reply; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-13 21:09 UTC (permalink / raw)
  To: devel; +Cc: Dun Tan, Gerd Hoffmann, Rahul Kumar, Ray Ni

Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
2023-12-12) introduced a helper function called GetSmBase(), replacing the
lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with iterated
lookups plus memory allocation.

This introduced a new failure mode for setting "mCpuHotPlugData.SmBase".
Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be set
to NULL if and only if the GUID HOB was absent. After the commit, a NULL
assignment would be possible if the GUID HOB was absent, *or* one of the
memory allocations inside GetSmBase() failed.

In relation to this conflation of distinct failure modes, commit
725acd0b9cc0 actually introduced a NULL pointer dereference. Namely, a
NULL "mCpuHotPlugData.SmBase" is not handled properly at all now. We're
going to fix that NULL pointer dereference in a subsequent patch; however,
as a pre-requisite for that we need to tell apart the failure modes of
GetSmBase().

For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
"assertion" that SMRAM cannot be exhausted happen out to the caller
(PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop() if
(NumberOfProcessors != MaxNumberOfCpus).)

For the absence of the GUID HOB, return EFI_NOT_FOUND.

For good measure, make GetSmBase() STATIC (it should have been STATIC from
the start).

This is just a refactoring, no behavioral difference is intended (beyond
the explicit CpuDeadLoop() upon SMRAM exhaustion).

Cc: Dun Tan <dun.tan@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    context:-U4

 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index cd394826ffcf..09382945ddb4 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -619,16 +619,23 @@ SmBaseHobCompare (
 
 /**
   Extract SmBase for all CPU from SmmBase HOB.
 
-  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
+  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
 
-  @retval SmBaseBuffer          Pointer to SmBase Buffer.
-  @retval NULL                  gSmmBaseHobGuid was not been created.
+  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer allocated
+                                     by this function. Only set if the
+                                     function returns EFI_SUCCESS.
+
+  @retval EFI_SUCCESS           SmBase Buffer output successfully.
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
 **/
-UINTN *
+STATIC
+EFI_STATUS
 GetSmBase (
-  IN  UINTN  MaxNumberOfCpus
+  IN  UINTN  MaxNumberOfCpus,
+  OUT UINTN  **AllocatedSmBaseBuffer
   )
 {
   UINTN              HobCount;
   EFI_HOB_GUID_TYPE  *GuidHob;
@@ -649,9 +656,9 @@ GetSmBase (
   NumberOfProcessors = 0;
 
   FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
   if (FirstSmmBaseGuidHob == NULL) {
-    return NULL;
+    return EFI_NOT_FOUND;
   }
 
   GuidHob = FirstSmmBaseGuidHob;
   while (GuidHob != NULL) {
@@ -671,11 +678,10 @@ GetSmBase (
     CpuDeadLoop ();
   }
 
   SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
-  ASSERT (SmBaseHobs != NULL);
   if (SmBaseHobs == NULL) {
-    return NULL;
+    return EFI_OUT_OF_RESOURCES;
   }
 
   //
   // Record each SmmBaseHob pointer in the SmBaseHobs.
@@ -691,9 +697,9 @@ GetSmBase (
   SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus));
   ASSERT (SmBaseBuffer != NULL);
   if (SmBaseBuffer == NULL) {
     FreePool (SmBaseHobs);
-    return NULL;
+    return EFI_OUT_OF_RESOURCES;
   }
 
   QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
   PrevProcessorIndex = 0;
@@ -713,9 +719,10 @@ GetSmBase (
     PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
   }
 
   FreePool (SmBaseHobs);
-  return SmBaseBuffer;
+  *AllocatedSmBaseBuffer = SmBaseBuffer;
+  return EFI_SUCCESS;
 }
 
 /**
   Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
@@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
   //
   // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
   // means the SmBase relocation has been done.
   //
-  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
-  if (mCpuHotPlugData.SmBase != NULL) {
+  mCpuHotPlugData.SmBase = NULL;
+  Status                 = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
+  if (Status == EFI_OUT_OF_RESOURCES) {
+    ASSERT (Status != EFI_OUT_OF_RESOURCES);
+    CpuDeadLoop ();
+  }
+
+  if (!EFI_ERROR (Status)) {
+    ASSERT (mCpuHotPlugData.SmBase != NULL);
     //
     // Check whether the Required TileSize is enough.
     //
     if (TileSize > SIZE_8KB) {
@@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
     }
 
     mSmmRelocated = TRUE;
   } else {
+    ASSERT (Status == EFI_NOT_FOUND);
+    ASSERT (mCpuHotPlugData.SmBase == NULL);
     //
     // When the HOB doesn't exist, allocate new SMBASE itself.
     //
     DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not found!\n"));



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115417): https://edk2.groups.io/g/devel/message/115417
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [edk2-stable202402 PATCH 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing
  2024-02-13 21:09 [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes Laszlo Ersek
@ 2024-02-13 21:09 ` Laszlo Ersek
  2024-02-14  9:01 ` [edk2-devel] [edk2-stable202402 PATCH 0/2] " Gerd Hoffmann
  2 siblings, 0 replies; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-13 21:09 UTC (permalink / raw)
  To: devel; +Cc: Dun Tan, Gerd Hoffmann, Rahul Kumar, Ray Ni

Before commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
smmbasehob", 2023-12-12), PiCpuSmmEntry() used to look up
"gSmmBaseHobGuid", and allocate "mCpuHotPlugData.SmBase" regardless of the
GUID's presence:

> -  mCpuHotPlugData.SmBase = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
> -  ASSERT (mCpuHotPlugData.SmBase != NULL);

After commit 725acd0b9cc0, PiCpuSmmEntry() -> GetSmBase() would allocate
"mCpuHotPlugData.SmBase" only on the success path, and no allocation would
be performed on *any* of the error paths.

This caused a problem: if "mCpuHotPlugData.SmBase" was left NULL because
the GUID HOB was missing, PiCpuSmmEntry() would still be supposed to
allocate "mCpuHotPlugData.SmBase", just like earlier. However, because
commit 725acd0b9cc0 conflated the two possible error modes (out of SMRAM,
and no GUID HOB), PiCpuSmmEntry() could not decide whether it should
allocate "mCpuHotPlugData.SmBase", or not. Currently, we never allocate if
GetSmBase() fails -- for any reason --, which means that on platforms that
don't produce the GUID HOB, "mCpuHotPlugData.SmBase" is left NULL, leading
to null pointer dereferences later, in PiCpuSmmEntry().

Now that a prior patch in the series distinguishes the two error modes
from each other, we can tell exactly when the GUID HOB is not found, and
reinstate the earlier "mCpuHotPlugData.SmBase" allocation for that case.
(With an actual error check thrown in, in addition to the original
"assertion".)

Cc: Dun Tan <dun.tan@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
Fixes: 725acd0b9cc0
Reported-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---

Notes:
    context:-U7

 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 09382945ddb4..499f979d34e2 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -1142,14 +1142,21 @@ PiCpuSmmEntry (
   } else {
     ASSERT (Status == EFI_NOT_FOUND);
     ASSERT (mCpuHotPlugData.SmBase == NULL);
     //
     // When the HOB doesn't exist, allocate new SMBASE itself.
     //
     DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not found!\n"));
+
+    mCpuHotPlugData.SmBase = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
+    if (mCpuHotPlugData.SmBase == NULL) {
+      ASSERT (mCpuHotPlugData.SmBase != NULL);
+      CpuDeadLoop ();
+    }
+
     //
     // very old processors (i486 + pentium) need 32k not 4k alignment, exclude them.
     //
     ASSERT (FamilyId >= 6);
     //
     // Allocate buffer for all of the tiles.
     //


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115418): https://edk2.groups.io/g/devel/message/115418
Mute This Topic: https://groups.io/mt/104341426/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes Laszlo Ersek
@ 2024-02-13 21:35   ` Laszlo Ersek
  2024-02-14  3:43     ` Michael D Kinney
  0 siblings, 1 reply; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-13 21:35 UTC (permalink / raw)
  To: devel; +Cc: Dun Tan, Gerd Hoffmann, Rahul Kumar, Ray Ni

On 2/13/24 22:09, Laszlo Ersek wrote:
> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
> 2023-12-12) introduced a helper function called GetSmBase(), replacing the
> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with iterated
> lookups plus memory allocation.
> 
> This introduced a new failure mode for setting "mCpuHotPlugData.SmBase".
> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be set
> to NULL if and only if the GUID HOB was absent. After the commit, a NULL
> assignment would be possible if the GUID HOB was absent, *or* one of the
> memory allocations inside GetSmBase() failed.

Sorry, these two paragraphs are not precise. A better version:

----------
Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
2023-12-12) introduced a helper function called GetSmBase(), replacing
the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
unconditional "mCpuHotPlugData.SmBase" allocation, with iterated lookups
plus conditional memory allocation.

This introduced a new failure mode for setting "mCpuHotPlugData.SmBase".
Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
allocated regardless of the GUID HOB being absent. After the commit,
"mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was absent,
*or* one of the memory allocations inside GetSmBase() failed; and in the
former case, we'd even proceed to the rest of PiCpuSmmEntry().
----------

Sorry, it's late.

If this patch set is accepted otherwise, then Mike or Liming, can you
please update the first two paragraphs of the commit message upon merge?

Thanks
Laszlo

> 
> In relation to this conflation of distinct failure modes, commit
> 725acd0b9cc0 actually introduced a NULL pointer dereference. Namely, a
> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now. We're
> going to fix that NULL pointer dereference in a subsequent patch; however,
> as a pre-requisite for that we need to tell apart the failure modes of
> GetSmBase().
> 
> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
> "assertion" that SMRAM cannot be exhausted happen out to the caller
> (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
> CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop() if
> (NumberOfProcessors != MaxNumberOfCpus).)
> 
> For the absence of the GUID HOB, return EFI_NOT_FOUND.
> 
> For good measure, make GetSmBase() STATIC (it should have been STATIC from
> the start).
> 
> This is just a refactoring, no behavioral difference is intended (beyond
> the explicit CpuDeadLoop() upon SMRAM exhaustion).
> 
> Cc: Dun Tan <dun.tan@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
> 
> Notes:
>     context:-U4
> 
>  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++------
>  1 file changed, 28 insertions(+), 12 deletions(-)
> 
> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> index cd394826ffcf..09382945ddb4 100644
> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> @@ -619,16 +619,23 @@ SmBaseHobCompare (
>  
>  /**
>    Extract SmBase for all CPU from SmmBase HOB.
>  
> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
>  
> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
> -  @retval NULL                  gSmmBaseHobGuid was not been created.
> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer allocated
> +                                     by this function. Only set if the
> +                                     function returns EFI_SUCCESS.
> +
> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
>  **/
> -UINTN *
> +STATIC
> +EFI_STATUS
>  GetSmBase (
> -  IN  UINTN  MaxNumberOfCpus
> +  IN  UINTN  MaxNumberOfCpus,
> +  OUT UINTN  **AllocatedSmBaseBuffer
>    )
>  {
>    UINTN              HobCount;
>    EFI_HOB_GUID_TYPE  *GuidHob;
> @@ -649,9 +656,9 @@ GetSmBase (
>    NumberOfProcessors = 0;
>  
>    FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
>    if (FirstSmmBaseGuidHob == NULL) {
> -    return NULL;
> +    return EFI_NOT_FOUND;
>    }
>  
>    GuidHob = FirstSmmBaseGuidHob;
>    while (GuidHob != NULL) {
> @@ -671,11 +678,10 @@ GetSmBase (
>      CpuDeadLoop ();
>    }
>  
>    SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
> -  ASSERT (SmBaseHobs != NULL);
>    if (SmBaseHobs == NULL) {
> -    return NULL;
> +    return EFI_OUT_OF_RESOURCES;
>    }
>  
>    //
>    // Record each SmmBaseHob pointer in the SmBaseHobs.
> @@ -691,9 +697,9 @@ GetSmBase (
>    SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus));
>    ASSERT (SmBaseBuffer != NULL);
>    if (SmBaseBuffer == NULL) {
>      FreePool (SmBaseHobs);
> -    return NULL;
> +    return EFI_OUT_OF_RESOURCES;
>    }
>  
>    QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
>    PrevProcessorIndex = 0;
> @@ -713,9 +719,10 @@ GetSmBase (
>      PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
>    }
>  
>    FreePool (SmBaseHobs);
> -  return SmBaseBuffer;
> +  *AllocatedSmBaseBuffer = SmBaseBuffer;
> +  return EFI_SUCCESS;
>  }
>  
>  /**
>    Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
>    //
>    // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
>    // means the SmBase relocation has been done.
>    //
> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
> -  if (mCpuHotPlugData.SmBase != NULL) {
> +  mCpuHotPlugData.SmBase = NULL;
> +  Status                 = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
> +  if (Status == EFI_OUT_OF_RESOURCES) {
> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
> +    CpuDeadLoop ();
> +  }
> +
> +  if (!EFI_ERROR (Status)) {
> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
>      //
>      // Check whether the Required TileSize is enough.
>      //
>      if (TileSize > SIZE_8KB) {
> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
>      }
>  
>      mSmmRelocated = TRUE;
>    } else {
> +    ASSERT (Status == EFI_NOT_FOUND);
> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
>      //
>      // When the HOB doesn't exist, allocate new SMBASE itself.
>      //
>      DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not found!\n"));
> 
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115419): https://edk2.groups.io/g/devel/message/115419
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-13 21:35   ` Laszlo Ersek
@ 2024-02-14  3:43     ` Michael D Kinney
  2024-02-14 11:22       ` Laszlo Ersek
  2024-02-14 13:08       ` Leif Lindholm
  0 siblings, 2 replies; 12+ messages in thread
From: Michael D Kinney @ 2024-02-14  3:43 UTC (permalink / raw)
  To: devel@edk2.groups.io, lersek@redhat.com, Leif Lindholm,
	Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Tan, Dun, Gerd Hoffmann, Kumar, Rahul R, Ni, Ray,
	Kinney, Michael D

Hi Laszlo,

Thank you for the quick fix.

I have reviewed the changes.  I agree they fix the issue at hand.

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>

I have adjusted the commit message with your suggested changes in
the PR I have prepared:

https://github.com/tianocore/edk2/pull/5373

There may be better ways to organize this code in general to make
it easier to understand and maintain in the future, but we can
let Ray review that when he returns.  That will also likely be a 
much bugger change that can be accepted just before a release.

I also approve this as a critical fix for edk2-stable202402

I will wait till tomorrow morning my time to see if Gerd and 
Rahul and Leif can also provide their reviews/approvals and
to give me some time to run some tests.

I do not expect Ray Ni or Dun Tan to be available this week.

Best regards,

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo
> Ersek
> Sent: Tuesday, February 13, 2024 1:36 PM
> To: devel@edk2.groups.io
> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
> 
> On 2/13/24 22:09, Laszlo Ersek wrote:
> > Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
> smmbasehob",
> > 2023-12-12) introduced a helper function called GetSmBase(),
> replacing the
> > lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
> iterated
> > lookups plus memory allocation.
> >
> > This introduced a new failure mode for setting
> "mCpuHotPlugData.SmBase".
> > Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
> set
> > to NULL if and only if the GUID HOB was absent. After the commit, a
> NULL
> > assignment would be possible if the GUID HOB was absent, *or* one of
> the
> > memory allocations inside GetSmBase() failed.
> 
> Sorry, these two paragraphs are not precise. A better version:
> 
> ----------
> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
> 2023-12-12) introduced a helper function called GetSmBase(), replacing
> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated
> lookups
> plus conditional memory allocation.
> 
> This introduced a new failure mode for setting
> "mCpuHotPlugData.SmBase".
> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
> allocated regardless of the GUID HOB being absent. After the commit,
> "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was absent,
> *or* one of the memory allocations inside GetSmBase() failed; and in
> the
> former case, we'd even proceed to the rest of PiCpuSmmEntry().
> ----------
> 
> Sorry, it's late.
> 
> If this patch set is accepted otherwise, then Mike or Liming, can you
> please update the first two paragraphs of the commit message upon
> merge?
> 
> Thanks
> Laszlo
> 
> >
> > In relation to this conflation of distinct failure modes, commit
> > 725acd0b9cc0 actually introduced a NULL pointer dereference. Namely,
> a
> > NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
> We're
> > going to fix that NULL pointer dereference in a subsequent patch;
> however,
> > as a pre-requisite for that we need to tell apart the failure modes
> of
> > GetSmBase().
> >
> > For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
> > "assertion" that SMRAM cannot be exhausted happen out to the caller
> > (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
> > CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop()
> if
> > (NumberOfProcessors != MaxNumberOfCpus).)
> >
> > For the absence of the GUID HOB, return EFI_NOT_FOUND.
> >
> > For good measure, make GetSmBase() STATIC (it should have been STATIC
> from
> > the start).
> >
> > This is just a refactoring, no behavioral difference is intended
> (beyond
> > the explicit CpuDeadLoop() upon SMRAM exhaustion).
> >
> > Cc: Dun Tan <dun.tan@intel.com>
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: Rahul Kumar <rahul1.kumar@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
> > Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> > ---
> >
> > Notes:
> >     context:-U4
> >
> >  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++------
> >  1 file changed, 28 insertions(+), 12 deletions(-)
> >
> > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> > index cd394826ffcf..09382945ddb4 100644
> > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> > @@ -619,16 +619,23 @@ SmBaseHobCompare (
> >
> >  /**
> >    Extract SmBase for all CPU from SmmBase HOB.
> >
> > -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
> > +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
> >
> > -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
> > -  @retval NULL                  gSmmBaseHobGuid was not been
> created.
> > +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
> allocated
> > +                                     by this function. Only set if
> the
> > +                                     function returns EFI_SUCCESS.
> > +
> > +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
> > +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> > +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
> >  **/
> > -UINTN *
> > +STATIC
> > +EFI_STATUS
> >  GetSmBase (
> > -  IN  UINTN  MaxNumberOfCpus
> > +  IN  UINTN  MaxNumberOfCpus,
> > +  OUT UINTN  **AllocatedSmBaseBuffer
> >    )
> >  {
> >    UINTN              HobCount;
> >    EFI_HOB_GUID_TYPE  *GuidHob;
> > @@ -649,9 +656,9 @@ GetSmBase (
> >    NumberOfProcessors = 0;
> >
> >    FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
> >    if (FirstSmmBaseGuidHob == NULL) {
> > -    return NULL;
> > +    return EFI_NOT_FOUND;
> >    }
> >
> >    GuidHob = FirstSmmBaseGuidHob;
> >    while (GuidHob != NULL) {
> > @@ -671,11 +678,10 @@ GetSmBase (
> >      CpuDeadLoop ();
> >    }
> >
> >    SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
> HobCount);
> > -  ASSERT (SmBaseHobs != NULL);
> >    if (SmBaseHobs == NULL) {
> > -    return NULL;
> > +    return EFI_OUT_OF_RESOURCES;
> >    }
> >
> >    //
> >    // Record each SmmBaseHob pointer in the SmBaseHobs.
> > @@ -691,9 +697,9 @@ GetSmBase (
> >    SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
> (MaxNumberOfCpus));
> >    ASSERT (SmBaseBuffer != NULL);
> >    if (SmBaseBuffer == NULL) {
> >      FreePool (SmBaseHobs);
> > -    return NULL;
> > +    return EFI_OUT_OF_RESOURCES;
> >    }
> >
> >    QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
> >    PrevProcessorIndex = 0;
> > @@ -713,9 +719,10 @@ GetSmBase (
> >      PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
> >    }
> >
> >    FreePool (SmBaseHobs);
> > -  return SmBaseBuffer;
> > +  *AllocatedSmBaseBuffer = SmBaseBuffer;
> > +  return EFI_SUCCESS;
> >  }
> >
> >  /**
> >    Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on
> ProcessorIndex.
> > @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
> >    //
> >    // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
> >    // means the SmBase relocation has been done.
> >    //
> > -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
> > -  if (mCpuHotPlugData.SmBase != NULL) {
> > +  mCpuHotPlugData.SmBase = NULL;
> > +  Status                 = GetSmBase (mMaxNumberOfCpus,
> &mCpuHotPlugData.SmBase);
> > +  if (Status == EFI_OUT_OF_RESOURCES) {
> > +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
> > +    CpuDeadLoop ();
> > +  }
> > +
> > +  if (!EFI_ERROR (Status)) {
> > +    ASSERT (mCpuHotPlugData.SmBase != NULL);
> >      //
> >      // Check whether the Required TileSize is enough.
> >      //
> >      if (TileSize > SIZE_8KB) {
> > @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
> >      }
> >
> >      mSmmRelocated = TRUE;
> >    } else {
> > +    ASSERT (Status == EFI_NOT_FOUND);
> > +    ASSERT (mCpuHotPlugData.SmBase == NULL);
> >      //
> >      // When the HOB doesn't exist, allocate new SMBASE itself.
> >      //
> >      DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
> found!\n"));
> >
> >
> >
> >
> >
> >
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115427): https://edk2.groups.io/g/devel/message/115427
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing
  2024-02-13 21:09 [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes Laszlo Ersek
  2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
@ 2024-02-14  9:01 ` Gerd Hoffmann
  2024-02-14  9:40   ` rahul.r.kumar
  2 siblings, 1 reply; 12+ messages in thread
From: Gerd Hoffmann @ 2024-02-14  9:01 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: devel, Dun Tan, Liming Gao, Michael D Kinney, Rahul Kumar, Ray Ni

On Tue, Feb 13, 2024 at 10:09:16PM +0100, Laszlo Ersek wrote:
> Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
> 
> Personal CI run (in progress):
> https://github.com/tianocore/edk2/pull/5370
> 
> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
> 2023-12-12) introduced a NULL pointer dereference to PiSmmCpuDxeSmm on
> such platforms that do not produce the "gSmmBaseHobGuid" GUID HOB at
> all.
> 
> Please see the multi-step analysis in the following thread:
> 
>   [edk2-devel] [PATCH 1/1] OvmfPkg/QemuVideoDxe: purge VbeShim
>   https://edk2.groups.io/g/devel/message/115377
>   message-id: <20240213085925.687848-1-kraxel@redhat.com>
> 
> This issue needs to be fixed for edk2-stable202402.
> 
> Cc: Dun Tan <dun.tan@intel.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>

Series:
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>

take care,
  Gerd



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115433): https://edk2.groups.io/g/devel/message/115433
Mute This Topic: https://groups.io/mt/104341340/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing
  2024-02-14  9:01 ` [edk2-devel] [edk2-stable202402 PATCH 0/2] " Gerd Hoffmann
@ 2024-02-14  9:40   ` rahul.r.kumar
  0 siblings, 0 replies; 12+ messages in thread
From: rahul.r.kumar @ 2024-02-14  9:40 UTC (permalink / raw)
  To: Gerd Hoffmann, devel

[-- Attachment #1: Type: text/plain, Size: 376 bytes --]

Approved


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115435): https://edk2.groups.io/g/devel/message/115435
Mute This Topic: https://groups.io/mt/104341340/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



[-- Attachment #2: Type: text/html, Size: 794 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-14  3:43     ` Michael D Kinney
@ 2024-02-14 11:22       ` Laszlo Ersek
  2024-02-14 13:08       ` Leif Lindholm
  1 sibling, 0 replies; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-14 11:22 UTC (permalink / raw)
  To: devel, michael.d.kinney, Leif Lindholm,
	Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Tan, Dun, Gerd Hoffmann, Kumar, Rahul R, Ni, Ray

On 2/14/24 04:43, Michael D Kinney wrote:
> Hi Laszlo,
> 
> Thank you for the quick fix.
> 
> I have reviewed the changes.  I agree they fix the issue at hand.
> 
> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> 
> I have adjusted the commit message with your suggested changes in
> the PR I have prepared:
> 
> https://github.com/tianocore/edk2/pull/5373
> 
> There may be better ways to organize this code in general to make
> it easier to understand and maintain in the future, but we can
> let Ray review that when he returns.  That will also likely be a 
> much bugger change that can be accepted just before a release.
> 
> I also approve this as a critical fix for edk2-stable202402
> 
> I will wait till tomorrow morning my time to see if Gerd and 
> Rahul and Leif can also provide their reviews/approvals and
> to give me some time to run some tests.
> 
> I do not expect Ray Ni or Dun Tan to be available this week.

Thank you all very much for the feedback!
Laszlo

> 
> Best regards,
> 
> Mike
> 
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo
>> Ersek
>> Sent: Tuesday, February 13, 2024 1:36 PM
>> To: devel@edk2.groups.io
>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
>> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>
>> On 2/13/24 22:09, Laszlo Ersek wrote:
>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>> smmbasehob",
>>> 2023-12-12) introduced a helper function called GetSmBase(),
>> replacing the
>>> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
>> iterated
>>> lookups plus memory allocation.
>>>
>>> This introduced a new failure mode for setting
>> "mCpuHotPlugData.SmBase".
>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
>> set
>>> to NULL if and only if the GUID HOB was absent. After the commit, a
>> NULL
>>> assignment would be possible if the GUID HOB was absent, *or* one of
>> the
>>> memory allocations inside GetSmBase() failed.
>>
>> Sorry, these two paragraphs are not precise. A better version:
>>
>> ----------
>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
>> 2023-12-12) introduced a helper function called GetSmBase(), replacing
>> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
>> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated
>> lookups
>> plus conditional memory allocation.
>>
>> This introduced a new failure mode for setting
>> "mCpuHotPlugData.SmBase".
>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
>> allocated regardless of the GUID HOB being absent. After the commit,
>> "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was absent,
>> *or* one of the memory allocations inside GetSmBase() failed; and in
>> the
>> former case, we'd even proceed to the rest of PiCpuSmmEntry().
>> ----------
>>
>> Sorry, it's late.
>>
>> If this patch set is accepted otherwise, then Mike or Liming, can you
>> please update the first two paragraphs of the commit message upon
>> merge?
>>
>> Thanks
>> Laszlo
>>
>>>
>>> In relation to this conflation of distinct failure modes, commit
>>> 725acd0b9cc0 actually introduced a NULL pointer dereference. Namely,
>> a
>>> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
>> We're
>>> going to fix that NULL pointer dereference in a subsequent patch;
>> however,
>>> as a pre-requisite for that we need to tell apart the failure modes
>> of
>>> GetSmBase().
>>>
>>> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
>>> "assertion" that SMRAM cannot be exhausted happen out to the caller
>>> (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
>>> CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop()
>> if
>>> (NumberOfProcessors != MaxNumberOfCpus).)
>>>
>>> For the absence of the GUID HOB, return EFI_NOT_FOUND.
>>>
>>> For good measure, make GetSmBase() STATIC (it should have been STATIC
>> from
>>> the start).
>>>
>>> This is just a refactoring, no behavioral difference is intended
>> (beyond
>>> the explicit CpuDeadLoop() upon SMRAM exhaustion).
>>>
>>> Cc: Dun Tan <dun.tan@intel.com>
>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>> Cc: Rahul Kumar <rahul1.kumar@intel.com>
>>> Cc: Ray Ni <ray.ni@intel.com>
>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>> ---
>>>
>>> Notes:
>>>     context:-U4
>>>
>>>  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++------
>>>  1 file changed, 28 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> index cd394826ffcf..09382945ddb4 100644
>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> @@ -619,16 +619,23 @@ SmBaseHobCompare (
>>>
>>>  /**
>>>    Extract SmBase for all CPU from SmmBase HOB.
>>>
>>> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
>>> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
>>>
>>> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
>>> -  @retval NULL                  gSmmBaseHobGuid was not been
>> created.
>>> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
>> allocated
>>> +                                     by this function. Only set if
>> the
>>> +                                     function returns EFI_SUCCESS.
>>> +
>>> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
>>> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
>>> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
>>>  **/
>>> -UINTN *
>>> +STATIC
>>> +EFI_STATUS
>>>  GetSmBase (
>>> -  IN  UINTN  MaxNumberOfCpus
>>> +  IN  UINTN  MaxNumberOfCpus,
>>> +  OUT UINTN  **AllocatedSmBaseBuffer
>>>    )
>>>  {
>>>    UINTN              HobCount;
>>>    EFI_HOB_GUID_TYPE  *GuidHob;
>>> @@ -649,9 +656,9 @@ GetSmBase (
>>>    NumberOfProcessors = 0;
>>>
>>>    FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
>>>    if (FirstSmmBaseGuidHob == NULL) {
>>> -    return NULL;
>>> +    return EFI_NOT_FOUND;
>>>    }
>>>
>>>    GuidHob = FirstSmmBaseGuidHob;
>>>    while (GuidHob != NULL) {
>>> @@ -671,11 +678,10 @@ GetSmBase (
>>>      CpuDeadLoop ();
>>>    }
>>>
>>>    SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
>> HobCount);
>>> -  ASSERT (SmBaseHobs != NULL);
>>>    if (SmBaseHobs == NULL) {
>>> -    return NULL;
>>> +    return EFI_OUT_OF_RESOURCES;
>>>    }
>>>
>>>    //
>>>    // Record each SmmBaseHob pointer in the SmBaseHobs.
>>> @@ -691,9 +697,9 @@ GetSmBase (
>>>    SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
>> (MaxNumberOfCpus));
>>>    ASSERT (SmBaseBuffer != NULL);
>>>    if (SmBaseBuffer == NULL) {
>>>      FreePool (SmBaseHobs);
>>> -    return NULL;
>>> +    return EFI_OUT_OF_RESOURCES;
>>>    }
>>>
>>>    QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
>> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
>>>    PrevProcessorIndex = 0;
>>> @@ -713,9 +719,10 @@ GetSmBase (
>>>      PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
>>>    }
>>>
>>>    FreePool (SmBaseHobs);
>>> -  return SmBaseBuffer;
>>> +  *AllocatedSmBaseBuffer = SmBaseBuffer;
>>> +  return EFI_SUCCESS;
>>>  }
>>>
>>>  /**
>>>    Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on
>> ProcessorIndex.
>>> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
>>>    //
>>>    // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
>>>    // means the SmBase relocation has been done.
>>>    //
>>> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
>>> -  if (mCpuHotPlugData.SmBase != NULL) {
>>> +  mCpuHotPlugData.SmBase = NULL;
>>> +  Status                 = GetSmBase (mMaxNumberOfCpus,
>> &mCpuHotPlugData.SmBase);
>>> +  if (Status == EFI_OUT_OF_RESOURCES) {
>>> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
>>> +    CpuDeadLoop ();
>>> +  }
>>> +
>>> +  if (!EFI_ERROR (Status)) {
>>> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
>>>      //
>>>      // Check whether the Required TileSize is enough.
>>>      //
>>>      if (TileSize > SIZE_8KB) {
>>> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
>>>      }
>>>
>>>      mSmmRelocated = TRUE;
>>>    } else {
>>> +    ASSERT (Status == EFI_NOT_FOUND);
>>> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
>>>      //
>>>      // When the HOB doesn't exist, allocate new SMBASE itself.
>>>      //
>>>      DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
>> found!\n"));
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>>
> 
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115444): https://edk2.groups.io/g/devel/message/115444
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-14  3:43     ` Michael D Kinney
  2024-02-14 11:22       ` Laszlo Ersek
@ 2024-02-14 13:08       ` Leif Lindholm
  2024-02-14 17:26         ` Michael D Kinney
  1 sibling, 1 reply; 12+ messages in thread
From: Leif Lindholm @ 2024-02-14 13:08 UTC (permalink / raw)
  To: devel, michael.d.kinney, lersek@redhat.com, Leif Lindholm,
	Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Tan, Dun, Gerd Hoffmann, Kumar, Rahul R, Ni, Ray

On 2024-02-14 03:43, Michael D Kinney wrote:
> Hi Laszlo,
> 
> Thank you for the quick fix.
> 
> I have reviewed the changes.  I agree they fix the issue at hand.
> 
> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> 
> I have adjusted the commit message with your suggested changes in
> the PR I have prepared:
> 
> https://github.com/tianocore/edk2/pull/5373
> 
> There may be better ways to organize this code in general to make
> it easier to understand and maintain in the future, but we can
> let Ray review that when he returns.  That will also likely be a
> much bugger change that can be accepted just before a release.
> 
> I also approve this as a critical fix for edk2-stable202402
> 
> I will wait till tomorrow morning my time to see if Gerd and
> Rahul and Leif can also provide their reviews/approvals and
> to give me some time to run some tests.

For the series:
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
I'm happy for this to go into the stable tag.

/
     Leif

> I do not expect Ray Ni or Dun Tan to be available this week.
> 
> Best regards,
> 
> Mike
> 
>> -----Original Message-----
>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo
>> Ersek
>> Sent: Tuesday, February 13, 2024 1:36 PM
>> To: devel@edk2.groups.io
>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
>> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>
>> On 2/13/24 22:09, Laszlo Ersek wrote:
>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>> smmbasehob",
>>> 2023-12-12) introduced a helper function called GetSmBase(),
>> replacing the
>>> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
>> iterated
>>> lookups plus memory allocation.
>>>
>>> This introduced a new failure mode for setting
>> "mCpuHotPlugData.SmBase".
>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
>> set
>>> to NULL if and only if the GUID HOB was absent. After the commit, a
>> NULL
>>> assignment would be possible if the GUID HOB was absent, *or* one of
>> the
>>> memory allocations inside GetSmBase() failed.
>>
>> Sorry, these two paragraphs are not precise. A better version:
>>
>> ----------
>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
>> 2023-12-12) introduced a helper function called GetSmBase(), replacing
>> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
>> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated
>> lookups
>> plus conditional memory allocation.
>>
>> This introduced a new failure mode for setting
>> "mCpuHotPlugData.SmBase".
>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
>> allocated regardless of the GUID HOB being absent. After the commit,
>> "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was absent,
>> *or* one of the memory allocations inside GetSmBase() failed; and in
>> the
>> former case, we'd even proceed to the rest of PiCpuSmmEntry().
>> ----------
>>
>> Sorry, it's late.
>>
>> If this patch set is accepted otherwise, then Mike or Liming, can you
>> please update the first two paragraphs of the commit message upon
>> merge?
>>
>> Thanks
>> Laszlo
>>
>>>
>>> In relation to this conflation of distinct failure modes, commit
>>> 725acd0b9cc0 actually introduced a NULL pointer dereference. Namely,
>> a
>>> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
>> We're
>>> going to fix that NULL pointer dereference in a subsequent patch;
>> however,
>>> as a pre-requisite for that we need to tell apart the failure modes
>> of
>>> GetSmBase().
>>>
>>> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
>>> "assertion" that SMRAM cannot be exhausted happen out to the caller
>>> (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
>>> CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop()
>> if
>>> (NumberOfProcessors != MaxNumberOfCpus).)
>>>
>>> For the absence of the GUID HOB, return EFI_NOT_FOUND.
>>>
>>> For good measure, make GetSmBase() STATIC (it should have been STATIC
>> from
>>> the start).
>>>
>>> This is just a refactoring, no behavioral difference is intended
>> (beyond
>>> the explicit CpuDeadLoop() upon SMRAM exhaustion).
>>>
>>> Cc: Dun Tan <dun.tan@intel.com>
>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>> Cc: Rahul Kumar <rahul1.kumar@intel.com>
>>> Cc: Ray Ni <ray.ni@intel.com>
>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>> ---
>>>
>>> Notes:
>>>      context:-U4
>>>
>>>   UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++------
>>>   1 file changed, 28 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> index cd394826ffcf..09382945ddb4 100644
>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>> @@ -619,16 +619,23 @@ SmBaseHobCompare (
>>>
>>>   /**
>>>     Extract SmBase for all CPU from SmmBase HOB.
>>>
>>> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
>>> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
>>>
>>> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
>>> -  @retval NULL                  gSmmBaseHobGuid was not been
>> created.
>>> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
>> allocated
>>> +                                     by this function. Only set if
>> the
>>> +                                     function returns EFI_SUCCESS.
>>> +
>>> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
>>> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
>>> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
>>>   **/
>>> -UINTN *
>>> +STATIC
>>> +EFI_STATUS
>>>   GetSmBase (
>>> -  IN  UINTN  MaxNumberOfCpus
>>> +  IN  UINTN  MaxNumberOfCpus,
>>> +  OUT UINTN  **AllocatedSmBaseBuffer
>>>     )
>>>   {
>>>     UINTN              HobCount;
>>>     EFI_HOB_GUID_TYPE  *GuidHob;
>>> @@ -649,9 +656,9 @@ GetSmBase (
>>>     NumberOfProcessors = 0;
>>>
>>>     FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
>>>     if (FirstSmmBaseGuidHob == NULL) {
>>> -    return NULL;
>>> +    return EFI_NOT_FOUND;
>>>     }
>>>
>>>     GuidHob = FirstSmmBaseGuidHob;
>>>     while (GuidHob != NULL) {
>>> @@ -671,11 +678,10 @@ GetSmBase (
>>>       CpuDeadLoop ();
>>>     }
>>>
>>>     SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
>> HobCount);
>>> -  ASSERT (SmBaseHobs != NULL);
>>>     if (SmBaseHobs == NULL) {
>>> -    return NULL;
>>> +    return EFI_OUT_OF_RESOURCES;
>>>     }
>>>
>>>     //
>>>     // Record each SmmBaseHob pointer in the SmBaseHobs.
>>> @@ -691,9 +697,9 @@ GetSmBase (
>>>     SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
>> (MaxNumberOfCpus));
>>>     ASSERT (SmBaseBuffer != NULL);
>>>     if (SmBaseBuffer == NULL) {
>>>       FreePool (SmBaseHobs);
>>> -    return NULL;
>>> +    return EFI_OUT_OF_RESOURCES;
>>>     }
>>>
>>>     QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
>> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
>>>     PrevProcessorIndex = 0;
>>> @@ -713,9 +719,10 @@ GetSmBase (
>>>       PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
>>>     }
>>>
>>>     FreePool (SmBaseHobs);
>>> -  return SmBaseBuffer;
>>> +  *AllocatedSmBaseBuffer = SmBaseBuffer;
>>> +  return EFI_SUCCESS;
>>>   }
>>>
>>>   /**
>>>     Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on
>> ProcessorIndex.
>>> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
>>>     //
>>>     // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
>>>     // means the SmBase relocation has been done.
>>>     //
>>> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
>>> -  if (mCpuHotPlugData.SmBase != NULL) {
>>> +  mCpuHotPlugData.SmBase = NULL;
>>> +  Status                 = GetSmBase (mMaxNumberOfCpus,
>> &mCpuHotPlugData.SmBase);
>>> +  if (Status == EFI_OUT_OF_RESOURCES) {
>>> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
>>> +    CpuDeadLoop ();
>>> +  }
>>> +
>>> +  if (!EFI_ERROR (Status)) {
>>> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
>>>       //
>>>       // Check whether the Required TileSize is enough.
>>>       //
>>>       if (TileSize > SIZE_8KB) {
>>> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
>>>       }
>>>
>>>       mSmmRelocated = TRUE;
>>>     } else {
>>> +    ASSERT (Status == EFI_NOT_FOUND);
>>> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
>>>       //
>>>       // When the HOB doesn't exist, allocate new SMBASE itself.
>>>       //
>>>       DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
>> found!\n"));
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>>
> 
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115453): https://edk2.groups.io/g/devel/message/115453
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-14 13:08       ` Leif Lindholm
@ 2024-02-14 17:26         ` Michael D Kinney
  2024-02-15  8:44           ` Laszlo Ersek
  0 siblings, 1 reply; 12+ messages in thread
From: Michael D Kinney @ 2024-02-14 17:26 UTC (permalink / raw)
  To: Leif Lindholm, devel@edk2.groups.io, lersek@redhat.com,
	Leif Lindholm, Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Tan, Dun, Gerd Hoffmann, Kumar, Rahul R, Ni, Ray,
	Kinney, Michael D

Merged: https://github.com/tianocore/edk2/pull/5373

> -----Original Message-----
> From: Leif Lindholm <quic_llindhol@quicinc.com>
> Sent: Wednesday, February 14, 2024 5:08 AM
> To: devel@edk2.groups.io; Kinney, Michael D
> <michael.d.kinney@intel.com>; lersek@redhat.com; Leif Lindholm
> <llindhol@qti.qualcomm.com>; Andrew Fish (afish@apple.com)
> <afish@apple.com>; Gao, Liming <gaoliming@byosoft.com.cn>
> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
> 
> On 2024-02-14 03:43, Michael D Kinney wrote:
> > Hi Laszlo,
> >
> > Thank you for the quick fix.
> >
> > I have reviewed the changes.  I agree they fix the issue at hand.
> >
> > Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> >
> > I have adjusted the commit message with your suggested changes in
> > the PR I have prepared:
> >
> > https://github.com/tianocore/edk2/pull/5373
> >
> > There may be better ways to organize this code in general to make
> > it easier to understand and maintain in the future, but we can
> > let Ray review that when he returns.  That will also likely be a
> > much bugger change that can be accepted just before a release.
> >
> > I also approve this as a critical fix for edk2-stable202402
> >
> > I will wait till tomorrow morning my time to see if Gerd and
> > Rahul and Leif can also provide their reviews/approvals and
> > to give me some time to run some tests.
> 
> For the series:
> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
> I'm happy for this to go into the stable tag.
> 
> /
>      Leif
> 
> > I do not expect Ray Ni or Dun Tan to be available this week.
> >
> > Best regards,
> >
> > Mike
> >
> >> -----Original Message-----
> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Laszlo
> >> Ersek
> >> Sent: Tuesday, February 13, 2024 1:36 PM
> >> To: devel@edk2.groups.io
> >> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
> >> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
> >> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
> >> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
> >>
> >> On 2/13/24 22:09, Laszlo Ersek wrote:
> >>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
> >> smmbasehob",
> >>> 2023-12-12) introduced a helper function called GetSmBase(),
> >> replacing the
> >>> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
> >> iterated
> >>> lookups plus memory allocation.
> >>>
> >>> This introduced a new failure mode for setting
> >> "mCpuHotPlugData.SmBase".
> >>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
> be
> >> set
> >>> to NULL if and only if the GUID HOB was absent. After the commit, a
> >> NULL
> >>> assignment would be possible if the GUID HOB was absent, *or* one
> of
> >> the
> >>> memory allocations inside GetSmBase() failed.
> >>
> >> Sorry, these two paragraphs are not precise. A better version:
> >>
> >> ----------
> >> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
> smmbasehob",
> >> 2023-12-12) introduced a helper function called GetSmBase(),
> replacing
> >> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
> >> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated
> >> lookups
> >> plus conditional memory allocation.
> >>
> >> This introduced a new failure mode for setting
> >> "mCpuHotPlugData.SmBase".
> >> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
> be
> >> allocated regardless of the GUID HOB being absent. After the commit,
> >> "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was
> absent,
> >> *or* one of the memory allocations inside GetSmBase() failed; and in
> >> the
> >> former case, we'd even proceed to the rest of PiCpuSmmEntry().
> >> ----------
> >>
> >> Sorry, it's late.
> >>
> >> If this patch set is accepted otherwise, then Mike or Liming, can
> you
> >> please update the first two paragraphs of the commit message upon
> >> merge?
> >>
> >> Thanks
> >> Laszlo
> >>
> >>>
> >>> In relation to this conflation of distinct failure modes, commit
> >>> 725acd0b9cc0 actually introduced a NULL pointer dereference.
> Namely,
> >> a
> >>> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
> >> We're
> >>> going to fix that NULL pointer dereference in a subsequent patch;
> >> however,
> >>> as a pre-requisite for that we need to tell apart the failure modes
> >> of
> >>> GetSmBase().
> >>>
> >>> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move
> the
> >>> "assertion" that SMRAM cannot be exhausted happen out to the caller
> >>> (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
> >>> CpuDeadLoop() call. (Note: GetSmBase() *already* calls
> CpuDeadLoop()
> >> if
> >>> (NumberOfProcessors != MaxNumberOfCpus).)
> >>>
> >>> For the absence of the GUID HOB, return EFI_NOT_FOUND.
> >>>
> >>> For good measure, make GetSmBase() STATIC (it should have been
> STATIC
> >> from
> >>> the start).
> >>>
> >>> This is just a refactoring, no behavioral difference is intended
> >> (beyond
> >>> the explicit CpuDeadLoop() upon SMRAM exhaustion).
> >>>
> >>> Cc: Dun Tan <dun.tan@intel.com>
> >>> Cc: Gerd Hoffmann <kraxel@redhat.com>
> >>> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> >>> Cc: Ray Ni <ray.ni@intel.com>
> >>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
> >>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> >>> ---
> >>>
> >>> Notes:
> >>>      context:-U4
> >>>
> >>>   UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++---
> ---
> >>>   1 file changed, 28 insertions(+), 12 deletions(-)
> >>>
> >>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> >> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> >>> index cd394826ffcf..09382945ddb4 100644
> >>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> >>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
> >>> @@ -619,16 +619,23 @@ SmBaseHobCompare (
> >>>
> >>>   /**
> >>>     Extract SmBase for all CPU from SmmBase HOB.
> >>>
> >>> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
> >>> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
> >>>
> >>> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
> >>> -  @retval NULL                  gSmmBaseHobGuid was not been
> >> created.
> >>> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
> >> allocated
> >>> +                                     by this function. Only set if
> >> the
> >>> +                                     function returns EFI_SUCCESS.
> >>> +
> >>> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
> >>> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> >>> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
> >>>   **/
> >>> -UINTN *
> >>> +STATIC
> >>> +EFI_STATUS
> >>>   GetSmBase (
> >>> -  IN  UINTN  MaxNumberOfCpus
> >>> +  IN  UINTN  MaxNumberOfCpus,
> >>> +  OUT UINTN  **AllocatedSmBaseBuffer
> >>>     )
> >>>   {
> >>>     UINTN              HobCount;
> >>>     EFI_HOB_GUID_TYPE  *GuidHob;
> >>> @@ -649,9 +656,9 @@ GetSmBase (
> >>>     NumberOfProcessors = 0;
> >>>
> >>>     FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
> >>>     if (FirstSmmBaseGuidHob == NULL) {
> >>> -    return NULL;
> >>> +    return EFI_NOT_FOUND;
> >>>     }
> >>>
> >>>     GuidHob = FirstSmmBaseGuidHob;
> >>>     while (GuidHob != NULL) {
> >>> @@ -671,11 +678,10 @@ GetSmBase (
> >>>       CpuDeadLoop ();
> >>>     }
> >>>
> >>>     SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
> >> HobCount);
> >>> -  ASSERT (SmBaseHobs != NULL);
> >>>     if (SmBaseHobs == NULL) {
> >>> -    return NULL;
> >>> +    return EFI_OUT_OF_RESOURCES;
> >>>     }
> >>>
> >>>     //
> >>>     // Record each SmmBaseHob pointer in the SmBaseHobs.
> >>> @@ -691,9 +697,9 @@ GetSmBase (
> >>>     SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
> >> (MaxNumberOfCpus));
> >>>     ASSERT (SmBaseBuffer != NULL);
> >>>     if (SmBaseBuffer == NULL) {
> >>>       FreePool (SmBaseHobs);
> >>> -    return NULL;
> >>> +    return EFI_OUT_OF_RESOURCES;
> >>>     }
> >>>
> >>>     QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
> >> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
> >>>     PrevProcessorIndex = 0;
> >>> @@ -713,9 +719,10 @@ GetSmBase (
> >>>       PrevProcessorIndex += SmBaseHobs[HobIndex]-
> >NumberOfProcessors;
> >>>     }
> >>>
> >>>     FreePool (SmBaseHobs);
> >>> -  return SmBaseBuffer;
> >>> +  *AllocatedSmBaseBuffer = SmBaseBuffer;
> >>> +  return EFI_SUCCESS;
> >>>   }
> >>>
> >>>   /**
> >>>     Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on
> >> ProcessorIndex.
> >>> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
> >>>     //
> >>>     // Retrive the allocated SmmBase from gSmmBaseHobGuid. If
> found,
> >>>     // means the SmBase relocation has been done.
> >>>     //
> >>> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
> >>> -  if (mCpuHotPlugData.SmBase != NULL) {
> >>> +  mCpuHotPlugData.SmBase = NULL;
> >>> +  Status                 = GetSmBase (mMaxNumberOfCpus,
> >> &mCpuHotPlugData.SmBase);
> >>> +  if (Status == EFI_OUT_OF_RESOURCES) {
> >>> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
> >>> +    CpuDeadLoop ();
> >>> +  }
> >>> +
> >>> +  if (!EFI_ERROR (Status)) {
> >>> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
> >>>       //
> >>>       // Check whether the Required TileSize is enough.
> >>>       //
> >>>       if (TileSize > SIZE_8KB) {
> >>> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
> >>>       }
> >>>
> >>>       mSmmRelocated = TRUE;
> >>>     } else {
> >>> +    ASSERT (Status == EFI_NOT_FOUND);
> >>> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
> >>>       //
> >>>       // When the HOB doesn't exist, allocate new SMBASE itself.
> >>>       //
> >>>       DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
> >> found!\n"));
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>
> >>
> >>
> >>
> >>
> >
> >
> >
> > 
> >
> >



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115469): https://edk2.groups.io/g/devel/message/115469
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-14 17:26         ` Michael D Kinney
@ 2024-02-15  8:44           ` Laszlo Ersek
  2024-02-19  9:12             ` duntan
  0 siblings, 1 reply; 12+ messages in thread
From: Laszlo Ersek @ 2024-02-15  8:44 UTC (permalink / raw)
  To: Kinney, Michael D, Leif Lindholm, devel@edk2.groups.io,
	Leif Lindholm, Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Tan, Dun, Gerd Hoffmann, Kumar, Rahul R, Ni, Ray

On 2/14/24 18:26, Kinney, Michael D wrote:
> Merged: https://github.com/tianocore/edk2/pull/5373

Thanks!
Laszlo

> 
>> -----Original Message-----
>> From: Leif Lindholm <quic_llindhol@quicinc.com>
>> Sent: Wednesday, February 14, 2024 5:08 AM
>> To: devel@edk2.groups.io; Kinney, Michael D
>> <michael.d.kinney@intel.com>; lersek@redhat.com; Leif Lindholm
>> <llindhol@qti.qualcomm.com>; Andrew Fish (afish@apple.com)
>> <afish@apple.com>; Gao, Liming <gaoliming@byosoft.com.cn>
>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
>> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>
>> On 2024-02-14 03:43, Michael D Kinney wrote:
>>> Hi Laszlo,
>>>
>>> Thank you for the quick fix.
>>>
>>> I have reviewed the changes.  I agree they fix the issue at hand.
>>>
>>> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
>>>
>>> I have adjusted the commit message with your suggested changes in
>>> the PR I have prepared:
>>>
>>> https://github.com/tianocore/edk2/pull/5373
>>>
>>> There may be better ways to organize this code in general to make
>>> it easier to understand and maintain in the future, but we can
>>> let Ray review that when he returns.  That will also likely be a
>>> much bugger change that can be accepted just before a release.
>>>
>>> I also approve this as a critical fix for edk2-stable202402
>>>
>>> I will wait till tomorrow morning my time to see if Gerd and
>>> Rahul and Leif can also provide their reviews/approvals and
>>> to give me some time to run some tests.
>>
>> For the series:
>> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
>> I'm happy for this to go into the stable tag.
>>
>> /
>>      Leif
>>
>>> I do not expect Ray Ni or Dun Tan to be available this week.
>>>
>>> Best regards,
>>>
>>> Mike
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Laszlo
>>>> Ersek
>>>> Sent: Tuesday, February 13, 2024 1:36 PM
>>>> To: devel@edk2.groups.io
>>>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>;
>>>> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
>>>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>>>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>>>
>>>> On 2/13/24 22:09, Laszlo Ersek wrote:
>>>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>>>> smmbasehob",
>>>>> 2023-12-12) introduced a helper function called GetSmBase(),
>>>> replacing the
>>>>> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
>>>> iterated
>>>>> lookups plus memory allocation.
>>>>>
>>>>> This introduced a new failure mode for setting
>>>> "mCpuHotPlugData.SmBase".
>>>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
>> be
>>>> set
>>>>> to NULL if and only if the GUID HOB was absent. After the commit, a
>>>> NULL
>>>>> assignment would be possible if the GUID HOB was absent, *or* one
>> of
>>>> the
>>>>> memory allocations inside GetSmBase() failed.
>>>>
>>>> Sorry, these two paragraphs are not precise. A better version:
>>>>
>>>> ----------
>>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>> smmbasehob",
>>>> 2023-12-12) introduced a helper function called GetSmBase(),
>> replacing
>>>> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
>>>> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated
>>>> lookups
>>>> plus conditional memory allocation.
>>>>
>>>> This introduced a new failure mode for setting
>>>> "mCpuHotPlugData.SmBase".
>>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
>> be
>>>> allocated regardless of the GUID HOB being absent. After the commit,
>>>> "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was
>> absent,
>>>> *or* one of the memory allocations inside GetSmBase() failed; and in
>>>> the
>>>> former case, we'd even proceed to the rest of PiCpuSmmEntry().
>>>> ----------
>>>>
>>>> Sorry, it's late.
>>>>
>>>> If this patch set is accepted otherwise, then Mike or Liming, can
>> you
>>>> please update the first two paragraphs of the commit message upon
>>>> merge?
>>>>
>>>> Thanks
>>>> Laszlo
>>>>
>>>>>
>>>>> In relation to this conflation of distinct failure modes, commit
>>>>> 725acd0b9cc0 actually introduced a NULL pointer dereference.
>> Namely,
>>>> a
>>>>> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
>>>> We're
>>>>> going to fix that NULL pointer dereference in a subsequent patch;
>>>> however,
>>>>> as a pre-requisite for that we need to tell apart the failure modes
>>>> of
>>>>> GetSmBase().
>>>>>
>>>>> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move
>> the
>>>>> "assertion" that SMRAM cannot be exhausted happen out to the caller
>>>>> (PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
>>>>> CpuDeadLoop() call. (Note: GetSmBase() *already* calls
>> CpuDeadLoop()
>>>> if
>>>>> (NumberOfProcessors != MaxNumberOfCpus).)
>>>>>
>>>>> For the absence of the GUID HOB, return EFI_NOT_FOUND.
>>>>>
>>>>> For good measure, make GetSmBase() STATIC (it should have been
>> STATIC
>>>> from
>>>>> the start).
>>>>>
>>>>> This is just a refactoring, no behavioral difference is intended
>>>> (beyond
>>>>> the explicit CpuDeadLoop() upon SMRAM exhaustion).
>>>>>
>>>>> Cc: Dun Tan <dun.tan@intel.com>
>>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>>>> Cc: Rahul Kumar <rahul1.kumar@intel.com>
>>>>> Cc: Ray Ni <ray.ni@intel.com>
>>>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>>>> ---
>>>>>
>>>>> Notes:
>>>>>      context:-U4
>>>>>
>>>>>   UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 ++++++++++++++---
>> ---
>>>>>   1 file changed, 28 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> index cd394826ffcf..09382945ddb4 100644
>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> @@ -619,16 +619,23 @@ SmBaseHobCompare (
>>>>>
>>>>>   /**
>>>>>     Extract SmBase for all CPU from SmmBase HOB.
>>>>>
>>>>> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
>>>>> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
>>>>>
>>>>> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
>>>>> -  @retval NULL                  gSmmBaseHobGuid was not been
>>>> created.
>>>>> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
>>>> allocated
>>>>> +                                     by this function. Only set if
>>>> the
>>>>> +                                     function returns EFI_SUCCESS.
>>>>> +
>>>>> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
>>>>> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
>>>>> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
>>>>>   **/
>>>>> -UINTN *
>>>>> +STATIC
>>>>> +EFI_STATUS
>>>>>   GetSmBase (
>>>>> -  IN  UINTN  MaxNumberOfCpus
>>>>> +  IN  UINTN  MaxNumberOfCpus,
>>>>> +  OUT UINTN  **AllocatedSmBaseBuffer
>>>>>     )
>>>>>   {
>>>>>     UINTN              HobCount;
>>>>>     EFI_HOB_GUID_TYPE  *GuidHob;
>>>>> @@ -649,9 +656,9 @@ GetSmBase (
>>>>>     NumberOfProcessors = 0;
>>>>>
>>>>>     FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
>>>>>     if (FirstSmmBaseGuidHob == NULL) {
>>>>> -    return NULL;
>>>>> +    return EFI_NOT_FOUND;
>>>>>     }
>>>>>
>>>>>     GuidHob = FirstSmmBaseGuidHob;
>>>>>     while (GuidHob != NULL) {
>>>>> @@ -671,11 +678,10 @@ GetSmBase (
>>>>>       CpuDeadLoop ();
>>>>>     }
>>>>>
>>>>>     SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
>>>> HobCount);
>>>>> -  ASSERT (SmBaseHobs != NULL);
>>>>>     if (SmBaseHobs == NULL) {
>>>>> -    return NULL;
>>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>>     }
>>>>>
>>>>>     //
>>>>>     // Record each SmmBaseHob pointer in the SmBaseHobs.
>>>>> @@ -691,9 +697,9 @@ GetSmBase (
>>>>>     SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
>>>> (MaxNumberOfCpus));
>>>>>     ASSERT (SmBaseBuffer != NULL);
>>>>>     if (SmBaseBuffer == NULL) {
>>>>>       FreePool (SmBaseHobs);
>>>>> -    return NULL;
>>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>>     }
>>>>>
>>>>>     QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
>>>> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
>>>>>     PrevProcessorIndex = 0;
>>>>> @@ -713,9 +719,10 @@ GetSmBase (
>>>>>       PrevProcessorIndex += SmBaseHobs[HobIndex]-
>>> NumberOfProcessors;
>>>>>     }
>>>>>
>>>>>     FreePool (SmBaseHobs);
>>>>> -  return SmBaseBuffer;
>>>>> +  *AllocatedSmBaseBuffer = SmBaseBuffer;
>>>>> +  return EFI_SUCCESS;
>>>>>   }
>>>>>
>>>>>   /**
>>>>>     Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on
>>>> ProcessorIndex.
>>>>> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
>>>>>     //
>>>>>     // Retrive the allocated SmmBase from gSmmBaseHobGuid. If
>> found,
>>>>>     // means the SmBase relocation has been done.
>>>>>     //
>>>>> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
>>>>> -  if (mCpuHotPlugData.SmBase != NULL) {
>>>>> +  mCpuHotPlugData.SmBase = NULL;
>>>>> +  Status                 = GetSmBase (mMaxNumberOfCpus,
>>>> &mCpuHotPlugData.SmBase);
>>>>> +  if (Status == EFI_OUT_OF_RESOURCES) {
>>>>> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
>>>>> +    CpuDeadLoop ();
>>>>> +  }
>>>>> +
>>>>> +  if (!EFI_ERROR (Status)) {
>>>>> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
>>>>>       //
>>>>>       // Check whether the Required TileSize is enough.
>>>>>       //
>>>>>       if (TileSize > SIZE_8KB) {
>>>>> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
>>>>>       }
>>>>>
>>>>>       mSmmRelocated = TRUE;
>>>>>     } else {
>>>>> +    ASSERT (Status == EFI_NOT_FOUND);
>>>>> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
>>>>>       //
>>>>>       // When the HOB doesn't exist, allocate new SMBASE itself.
>>>>>       //
>>>>>       DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
>>>> found!\n"));
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>> 
>>>
>>>
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115493): https://edk2.groups.io/g/devel/message/115493
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
  2024-02-15  8:44           ` Laszlo Ersek
@ 2024-02-19  9:12             ` duntan
  0 siblings, 0 replies; 12+ messages in thread
From: duntan @ 2024-02-19  9:12 UTC (permalink / raw)
  To: Laszlo Ersek, Kinney, Michael D, Leif Lindholm,
	devel@edk2.groups.io, Leif Lindholm,
	Andrew Fish (afish@apple.com), Gao, Liming
  Cc: Gerd Hoffmann, Kumar, Rahul R, Ni, Ray

Laszlo,

Sorry for the late reply. Thanks for your code refactoring patch and bugfix patch!

Thanks,
Dun

-----Original Message-----
From: Laszlo Ersek <lersek@redhat.com> 
Sent: Thursday, February 15, 2024 4:45 PM
To: Kinney, Michael D <michael.d.kinney@intel.com>; Leif Lindholm <quic_llindhol@quicinc.com>; devel@edk2.groups.io; Leif Lindholm <llindhol@qti.qualcomm.com>; Andrew Fish (afish@apple.com) <afish@apple.com>; Gao, Liming <gaoliming@byosoft.com.cn>
Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes

On 2/14/24 18:26, Kinney, Michael D wrote:
> Merged: https://github.com/tianocore/edk2/pull/5373

Thanks!
Laszlo

> 
>> -----Original Message-----
>> From: Leif Lindholm <quic_llindhol@quicinc.com>
>> Sent: Wednesday, February 14, 2024 5:08 AM
>> To: devel@edk2.groups.io; Kinney, Michael D 
>> <michael.d.kinney@intel.com>; lersek@redhat.com; Leif Lindholm 
>> <llindhol@qti.qualcomm.com>; Andrew Fish (afish@apple.com) 
>> <afish@apple.com>; Gao, Liming <gaoliming@byosoft.com.cn>
>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann <kraxel@redhat.com>; 
>> Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, Ray <ray.ni@intel.com>
>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>
>> On 2024-02-14 03:43, Michael D Kinney wrote:
>>> Hi Laszlo,
>>>
>>> Thank you for the quick fix.
>>>
>>> I have reviewed the changes.  I agree they fix the issue at hand.
>>>
>>> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
>>>
>>> I have adjusted the commit message with your suggested changes in 
>>> the PR I have prepared:
>>>
>>> https://github.com/tianocore/edk2/pull/5373
>>>
>>> There may be better ways to organize this code in general to make it 
>>> easier to understand and maintain in the future, but we can let Ray 
>>> review that when he returns.  That will also likely be a much bugger 
>>> change that can be accepted just before a release.
>>>
>>> I also approve this as a critical fix for edk2-stable202402
>>>
>>> I will wait till tomorrow morning my time to see if Gerd and Rahul 
>>> and Leif can also provide their reviews/approvals and to give me 
>>> some time to run some tests.
>>
>> For the series:
>> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com> I'm happy for 
>> this to go into the stable tag.
>>
>> /
>>      Leif
>>
>>> I do not expect Ray Ni or Dun Tan to be available this week.
>>>
>>> Best regards,
>>>
>>> Mike
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
>> Laszlo
>>>> Ersek
>>>> Sent: Tuesday, February 13, 2024 1:36 PM
>>>> To: devel@edk2.groups.io
>>>> Cc: Tan, Dun <dun.tan@intel.com>; Gerd Hoffmann 
>>>> <kraxel@redhat.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>; Ni, 
>>>> Ray <ray.ni@intel.com>
>>>> Subject: Re: [edk2-devel] [edk2-stable202402 PATCH 1/2]
>>>> UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
>>>>
>>>> On 2/13/24 22:09, Laszlo Ersek wrote:
>>>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>>>> smmbasehob",
>>>>> 2023-12-12) introduced a helper function called GetSmBase(),
>>>> replacing the
>>>>> lookup of the first and only "gSmmBaseHobGuid" GUID HOB, with
>>>> iterated
>>>>> lookups plus memory allocation.
>>>>>
>>>>> This introduced a new failure mode for setting
>>>> "mCpuHotPlugData.SmBase".
>>>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
>> be
>>>> set
>>>>> to NULL if and only if the GUID HOB was absent. After the commit, 
>>>>> a
>>>> NULL
>>>>> assignment would be possible if the GUID HOB was absent, *or* one
>> of
>>>> the
>>>>> memory allocations inside GetSmBase() failed.
>>>>
>>>> Sorry, these two paragraphs are not precise. A better version:
>>>>
>>>> ----------
>>>> Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one
>> smmbasehob",
>>>> 2023-12-12) introduced a helper function called GetSmBase(),
>> replacing
>>>> the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and 
>>>> unconditional "mCpuHotPlugData.SmBase" allocation, with iterated 
>>>> lookups plus conditional memory allocation.
>>>>
>>>> This introduced a new failure mode for setting 
>>>> "mCpuHotPlugData.SmBase".
>>>> Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would
>> be
>>>> allocated regardless of the GUID HOB being absent. After the 
>>>> commit, "mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB 
>>>> was
>> absent,
>>>> *or* one of the memory allocations inside GetSmBase() failed; and 
>>>> in the former case, we'd even proceed to the rest of 
>>>> PiCpuSmmEntry().
>>>> ----------
>>>>
>>>> Sorry, it's late.
>>>>
>>>> If this patch set is accepted otherwise, then Mike or Liming, can
>> you
>>>> please update the first two paragraphs of the commit message upon 
>>>> merge?
>>>>
>>>> Thanks
>>>> Laszlo
>>>>
>>>>>
>>>>> In relation to this conflation of distinct failure modes, commit
>>>>> 725acd0b9cc0 actually introduced a NULL pointer dereference.
>> Namely,
>>>> a
>>>>> NULL "mCpuHotPlugData.SmBase" is not handled properly at all now.
>>>> We're
>>>>> going to fix that NULL pointer dereference in a subsequent patch;
>>>> however,
>>>>> as a pre-requisite for that we need to tell apart the failure 
>>>>> modes
>>>> of
>>>>> GetSmBase().
>>>>>
>>>>> For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move
>> the
>>>>> "assertion" that SMRAM cannot be exhausted happen out to the 
>>>>> caller (PiCpuSmmEntry()). Strengthen the assertion by adding an 
>>>>> explicit
>>>>> CpuDeadLoop() call. (Note: GetSmBase() *already* calls
>> CpuDeadLoop()
>>>> if
>>>>> (NumberOfProcessors != MaxNumberOfCpus).)
>>>>>
>>>>> For the absence of the GUID HOB, return EFI_NOT_FOUND.
>>>>>
>>>>> For good measure, make GetSmBase() STATIC (it should have been
>> STATIC
>>>> from
>>>>> the start).
>>>>>
>>>>> This is just a refactoring, no behavioral difference is intended
>>>> (beyond
>>>>> the explicit CpuDeadLoop() upon SMRAM exhaustion).
>>>>>
>>>>> Cc: Dun Tan <dun.tan@intel.com>
>>>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>>>> Cc: Rahul Kumar <rahul1.kumar@intel.com>
>>>>> Cc: Ray Ni <ray.ni@intel.com>
>>>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
>>>>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>>>>> ---
>>>>>
>>>>> Notes:
>>>>>      context:-U4
>>>>>
>>>>>   UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 
>>>>> ++++++++++++++---
>> ---
>>>>>   1 file changed, 28 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>> b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> index cd394826ffcf..09382945ddb4 100644
>>>>> --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
>>>>> @@ -619,16 +619,23 @@ SmBaseHobCompare (
>>>>>
>>>>>   /**
>>>>>     Extract SmBase for all CPU from SmmBase HOB.
>>>>>
>>>>> -  @param[in]  MaxNumberOfCpus   Max NumberOfCpus.
>>>>> +  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
>>>>>
>>>>> -  @retval SmBaseBuffer          Pointer to SmBase Buffer.
>>>>> -  @retval NULL                  gSmmBaseHobGuid was not been
>>>> created.
>>>>> +  @param[out] AllocatedSmBaseBuffer  Pointer to SmBase Buffer
>>>> allocated
>>>>> +                                     by this function. Only set 
>>>>> + if
>>>> the
>>>>> +                                     function returns EFI_SUCCESS.
>>>>> +
>>>>> +  @retval EFI_SUCCESS           SmBase Buffer output successfully.
>>>>> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
>>>>> +  @retval EFI_NOT_FOUND         gSmmBaseHobGuid was never created.
>>>>>   **/
>>>>> -UINTN *
>>>>> +STATIC
>>>>> +EFI_STATUS
>>>>>   GetSmBase (
>>>>> -  IN  UINTN  MaxNumberOfCpus
>>>>> +  IN  UINTN  MaxNumberOfCpus,
>>>>> +  OUT UINTN  **AllocatedSmBaseBuffer
>>>>>     )
>>>>>   {
>>>>>     UINTN              HobCount;
>>>>>     EFI_HOB_GUID_TYPE  *GuidHob;
>>>>> @@ -649,9 +656,9 @@ GetSmBase (
>>>>>     NumberOfProcessors = 0;
>>>>>
>>>>>     FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
>>>>>     if (FirstSmmBaseGuidHob == NULL) {
>>>>> -    return NULL;
>>>>> +    return EFI_NOT_FOUND;
>>>>>     }
>>>>>
>>>>>     GuidHob = FirstSmmBaseGuidHob;
>>>>>     while (GuidHob != NULL) {
>>>>> @@ -671,11 +678,10 @@ GetSmBase (
>>>>>       CpuDeadLoop ();
>>>>>     }
>>>>>
>>>>>     SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) *
>>>> HobCount);
>>>>> -  ASSERT (SmBaseHobs != NULL);
>>>>>     if (SmBaseHobs == NULL) {
>>>>> -    return NULL;
>>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>>     }
>>>>>
>>>>>     //
>>>>>     // Record each SmmBaseHob pointer in the SmBaseHobs.
>>>>> @@ -691,9 +697,9 @@ GetSmBase (
>>>>>     SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) *
>>>> (MaxNumberOfCpus));
>>>>>     ASSERT (SmBaseBuffer != NULL);
>>>>>     if (SmBaseBuffer == NULL) {
>>>>>       FreePool (SmBaseHobs);
>>>>> -    return NULL;
>>>>> +    return EFI_OUT_OF_RESOURCES;
>>>>>     }
>>>>>
>>>>>     QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *),
>>>> (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
>>>>>     PrevProcessorIndex = 0;
>>>>> @@ -713,9 +719,10 @@ GetSmBase (
>>>>>       PrevProcessorIndex += SmBaseHobs[HobIndex]-
>>> NumberOfProcessors;
>>>>>     }
>>>>>
>>>>>     FreePool (SmBaseHobs);
>>>>> -  return SmBaseBuffer;
>>>>> +  *AllocatedSmBaseBuffer = SmBaseBuffer;  return EFI_SUCCESS;
>>>>>   }
>>>>>
>>>>>   /**
>>>>>     Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based 
>>>>> on
>>>> ProcessorIndex.
>>>>> @@ -1110,10 +1117,17 @@ PiCpuSmmEntry (
>>>>>     //
>>>>>     // Retrive the allocated SmmBase from gSmmBaseHobGuid. If
>> found,
>>>>>     // means the SmBase relocation has been done.
>>>>>     //
>>>>> -  mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
>>>>> -  if (mCpuHotPlugData.SmBase != NULL) {
>>>>> +  mCpuHotPlugData.SmBase = NULL;
>>>>> +  Status                 = GetSmBase (mMaxNumberOfCpus,
>>>> &mCpuHotPlugData.SmBase);
>>>>> +  if (Status == EFI_OUT_OF_RESOURCES) {
>>>>> +    ASSERT (Status != EFI_OUT_OF_RESOURCES);
>>>>> +    CpuDeadLoop ();
>>>>> +  }
>>>>> +
>>>>> +  if (!EFI_ERROR (Status)) {
>>>>> +    ASSERT (mCpuHotPlugData.SmBase != NULL);
>>>>>       //
>>>>>       // Check whether the Required TileSize is enough.
>>>>>       //
>>>>>       if (TileSize > SIZE_8KB) {
>>>>> @@ -1125,8 +1139,10 @@ PiCpuSmmEntry (
>>>>>       }
>>>>>
>>>>>       mSmmRelocated = TRUE;
>>>>>     } else {
>>>>> +    ASSERT (Status == EFI_NOT_FOUND);
>>>>> +    ASSERT (mCpuHotPlugData.SmBase == NULL);
>>>>>       //
>>>>>       // When the HOB doesn't exist, allocate new SMBASE itself.
>>>>>       //
>>>>>       DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not
>>>> found!\n"));
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>> 
>>>
>>>
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#115586): https://edk2.groups.io/g/devel/message/115586
Mute This Topic: https://groups.io/mt/104341342/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-02-19  9:12 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-13 21:09 [edk2-devel] [edk2-stable202402 PATCH 0/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 1/2] UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes Laszlo Ersek
2024-02-13 21:35   ` Laszlo Ersek
2024-02-14  3:43     ` Michael D Kinney
2024-02-14 11:22       ` Laszlo Ersek
2024-02-14 13:08       ` Leif Lindholm
2024-02-14 17:26         ` Michael D Kinney
2024-02-15  8:44           ` Laszlo Ersek
2024-02-19  9:12             ` duntan
2024-02-13 21:09 ` [edk2-devel] [edk2-stable202402 PATCH 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: fix NULL deref when gSmmBaseHobGuid is missing Laszlo Ersek
2024-02-14  9:01 ` [edk2-devel] [edk2-stable202402 PATCH 0/2] " Gerd Hoffmann
2024-02-14  9:40   ` rahul.r.kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox