]> git.proxmox.com Git - mirror_edk2.git/commitdiff
StandaloneMmPkg: Fix check buffer address failed issue from TF-A
authorMing Huang <huangming@linux.alibaba.com>
Fri, 31 Dec 2021 11:06:23 +0000 (19:06 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 7 Jul 2022 10:20:06 +0000 (10:20 +0000)
There are two scene communicate with StandaloneMm(MM):
1 edk2 -> TF-A -> MM, communicate MM use non-secure buffer which
  specify by EFI_SECURE_PARTITION_BOOT_INFO.SpNsCommBufBase;
2 RAS scene: fiq -> TF-A -> MM, use secure buffer which
  specify by EFI_SECURE_PARTITION_BOOT_INFO.SpShareBufBase;

For now, the second scene will failed because check buffer address.
This patch add CheckBufferAddr() to support check address for secure
buffer.

Signed-off-by: Ming Huang <huangming@linux.alibaba.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
StandaloneMmPkg/Drivers/StandaloneMmCpu/EventHandle.c
StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.c
StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.h

index 556fd21451dab7ac3a2d9d4cfa51b001aa92faec..818e147f874c26d4bce8c1ed1c0a0848a564815e 100644 (file)
@@ -49,6 +49,7 @@ EFI_MM_COMMUNICATE_HEADER  **PerCpuGuidedEventContext = NULL;
 \r
 // Descriptor with whereabouts of memory used for communication with the normal world\r
 EFI_MMRAM_DESCRIPTOR  mNsCommBuffer;\r
+EFI_MMRAM_DESCRIPTOR  mSCommBuffer;\r
 \r
 MP_INFORMATION_HOB_DATA  *mMpInformationHobData;\r
 \r
@@ -59,6 +60,53 @@ EFI_MM_CONFIGURATION_PROTOCOL  mMmConfig = {
 \r
 STATIC EFI_MM_ENTRY_POINT  mMmEntryPoint = NULL;\r
 \r
+/**\r
+  Perform bounds check on the common buffer.\r
+\r
+  @param  [in] BufferAddr   Address of the common buffer.\r
+\r
+  @retval   EFI_SUCCESS             Success.\r
+  @retval   EFI_ACCESS_DENIED       Access not permitted.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+CheckBufferAddr (\r
+  IN UINTN  BufferAddr\r
+  )\r
+{\r
+  UINT64  NsCommBufferEnd;\r
+  UINT64  SCommBufferEnd;\r
+  UINT64  CommBufferEnd;\r
+\r
+  NsCommBufferEnd = mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize;\r
+  SCommBufferEnd  = mSCommBuffer.PhysicalStart + mSCommBuffer.PhysicalSize;\r
+\r
+  if ((BufferAddr >= mNsCommBuffer.PhysicalStart) &&\r
+      (BufferAddr < NsCommBufferEnd))\r
+  {\r
+    CommBufferEnd = NsCommBufferEnd;\r
+  } else if ((BufferAddr >= mSCommBuffer.PhysicalStart) &&\r
+             (BufferAddr < SCommBufferEnd))\r
+  {\r
+    CommBufferEnd = SCommBufferEnd;\r
+  } else {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  if ((CommBufferEnd - BufferAddr) < sizeof (EFI_MM_COMMUNICATE_HEADER)) {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  // perform bounds check.\r
+  if ((CommBufferEnd - BufferAddr - sizeof (EFI_MM_COMMUNICATE_HEADER)) <\r
+      ((EFI_MM_COMMUNICATE_HEADER *)BufferAddr)->MessageLength)\r
+  {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   The PI Standalone MM entry point for the TF-A CPU driver.\r
 \r
@@ -104,27 +152,16 @@ PiMmStandaloneArmTfCpuDriverEntry (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (NsCommBufferAddr < mNsCommBuffer.PhysicalStart) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-\r
-  if ((NsCommBufferAddr + sizeof (EFI_MM_COMMUNICATE_HEADER)) >=\r
-      (mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize))\r
-  {\r
-    return EFI_INVALID_PARAMETER;\r
+  Status = CheckBufferAddr (NsCommBufferAddr);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Check Buffer failed: %r\n", Status));\r
+    return Status;\r
   }\r
 \r
   // Find out the size of the buffer passed\r
   NsCommBufferSize = ((EFI_MM_COMMUNICATE_HEADER *)NsCommBufferAddr)->MessageLength +\r
                      sizeof (EFI_MM_COMMUNICATE_HEADER);\r
 \r
-  // perform bounds check.\r
-  if (NsCommBufferAddr + NsCommBufferSize >=\r
-      mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize)\r
-  {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-\r
   GuidedEventContext = NULL;\r
   // Now that the secure world can see the normal world buffer, allocate\r
   // memory to copy the communication buffer to the secure world.\r
index d8bfba263ae26b6da683d4297ab41d0142db7547..3d1dc6181bd9fe8f83f5b4cdd5679555d0cd83d9 100644 (file)
@@ -106,6 +106,7 @@ StandaloneMmCpuInitialize (
   UINTN                            Index;\r
   UINTN                            ArraySize;\r
   VOID                             *HobStart;\r
+  EFI_MMRAM_HOB_DESCRIPTOR_BLOCK   *MmramRangesHob;\r
 \r
   ASSERT (SystemTable != NULL);\r
   mMmst = SystemTable;\r
@@ -188,6 +189,26 @@ StandaloneMmCpuInitialize (
   CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof (EFI_MMRAM_DESCRIPTOR));\r
   DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));\r
 \r
+  Status = GetGuidedHobData (\r
+             HobStart,\r
+             &gEfiMmPeiMmramMemoryReserveGuid,\r
+             (VOID **)&MmramRangesHob\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "MmramRangesHob data extraction failed - 0x%x\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // As CreateHobListFromBootInfo(), the base and size of buffer shared with\r
+  // privileged Secure world software is in second one.\r
+  //\r
+  CopyMem (\r
+    &mSCommBuffer,\r
+    &MmramRangesHob->Descriptor[0] + 1,\r
+    sizeof (EFI_MMRAM_DESCRIPTOR)\r
+    );\r
+\r
   //\r
   // Extract the MP information from the Hoblist\r
   //\r
index 251765eddfa85650a8525da0756f4f7895d2348a..3d4698ec19578daf74dc06f6373795d51720447b 100644 (file)
@@ -30,6 +30,7 @@ extern EFI_MM_CPU_PROTOCOL  mMmCpuState;
 //\r
 extern EFI_MM_COMMUNICATE_HEADER      **PerCpuGuidedEventContext;\r
 extern EFI_MMRAM_DESCRIPTOR           mNsCommBuffer;\r
+extern EFI_MMRAM_DESCRIPTOR           mSCommBuffer;\r
 extern MP_INFORMATION_HOB_DATA        *mMpInformationHobData;\r
 extern EFI_MM_CONFIGURATION_PROTOCOL  mMmConfig;\r
 \r