]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/SmmMemLib/SmmMemLib.c
MdePkg/SmmMemLib: Check EFI_MEMORY_RO in UEFI mem attrib table.
[mirror_edk2.git] / MdePkg / Library / SmmMemLib / SmmMemLib.c
index 3f79e46d46dfca9f96235e03f68340cd801bf0e8..3409ddf87c8d4d88af98a0b3cfbeaf070085f375 100644 (file)
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DxeServicesTableLib.h>\r
 #include <Library/SmmServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Protocol/SmmAccess2.h>\r
 #include <Protocol/SmmReadyToLock.h>\r
 #include <Protocol/SmmEndOfDxe.h>\r
+#include <Guid/MemoryAttributesTable.h>\r
 \r
 //\r
 // attributes for reserved memory before it is promoted to system memory\r
@@ -39,9 +41,6 @@
 #define EFI_MEMORY_INITIALIZED  0x0200000000000000ULL\r
 #define EFI_MEMORY_TESTED       0x0400000000000000ULL\r
 \r
-#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
-  ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))\r
-\r
 EFI_SMRAM_DESCRIPTOR *mSmmMemLibInternalSmramRanges;\r
 UINTN                mSmmMemLibInternalSmramCount;\r
 \r
@@ -57,6 +56,8 @@ UINTN                 mDescriptorSize;
 EFI_GCD_MEMORY_SPACE_DESCRIPTOR   *mSmmMemLibGcdMemSpace       = NULL;\r
 UINTN                             mSmmMemLibGcdMemNumberOfDesc = 0;\r
 \r
+EFI_MEMORY_ATTRIBUTES_TABLE  *mSmmMemLibMemoryAttributesTable = NULL;\r
+\r
 VOID                  *mRegistrationEndOfDxe;\r
 VOID                  *mRegistrationReadyToLock;\r
 \r
@@ -204,6 +205,32 @@ SmmIsBufferOutsideSmmValid (
         return FALSE;\r
       }\r
     }\r
+\r
+    //\r
+    // Check UEFI runtime memory with EFI_MEMORY_RO as invalid communication buffer.\r
+    //\r
+    if (mSmmMemLibMemoryAttributesTable != NULL) {\r
+      EFI_MEMORY_DESCRIPTOR *Entry;\r
+\r
+      Entry = (EFI_MEMORY_DESCRIPTOR *)(mSmmMemLibMemoryAttributesTable + 1);\r
+      for (Index = 0; Index < mSmmMemLibMemoryAttributesTable->NumberOfEntries; Index++) {\r
+        if (Entry->Type == EfiRuntimeServicesCode || Entry->Type == EfiRuntimeServicesData) {\r
+          if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {\r
+            if (((Buffer >= Entry->PhysicalStart) && (Buffer < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) ||\r
+                ((Entry->PhysicalStart >= Buffer) && (Entry->PhysicalStart < Buffer + Length))) {\r
+              DEBUG ((\r
+                EFI_D_ERROR,\r
+                "SmmIsBufferOutsideSmmValid: In RuntimeCode Region: Buffer (0x%lx) - Length (0x%lx)\n",\r
+                Buffer,\r
+                Length\r
+                ));\r
+              return FALSE;\r
+            }\r
+          }\r
+        }\r
+        Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mSmmMemLibMemoryAttributesTable->DescriptorSize);\r
+      }\r
+    }\r
   }\r
   return TRUE;\r
 }\r
@@ -399,6 +426,26 @@ SmmMemLibInternalGetGcdMemoryMap (
   gBS->FreePool (MemSpaceMap);\r
 }\r
 \r
+/**\r
+  Get UEFI MemoryAttributesTable.\r
+**/\r
+VOID\r
+SmmMemLibInternalGetUefiMemoryAttributesTable (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_MEMORY_ATTRIBUTES_TABLE  *MemoryAttributesTable;\r
+  UINTN                        MemoryAttributesTableSize;\r
+\r
+  Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);\r
+  if (!EFI_ERROR (Status)) {\r
+    MemoryAttributesTableSize = sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;\r
+    mSmmMemLibMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);\r
+    ASSERT (mSmmMemLibMemoryAttributesTable != NULL);\r
+  }\r
+}\r
+\r
 /**\r
   Notification for SMM EndOfDxe protocol.\r
 \r
@@ -502,6 +549,11 @@ SmmLibInternalEndOfDxeNotify (
   //\r
   SmmMemLibInternalGetGcdMemoryMap ();\r
 \r
+  //\r
+  // Get UEFI memory attributes table.\r
+  //\r
+  SmmMemLibInternalGetUefiMemoryAttributesTable ();\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r