]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Pool.c
MdeModulePkg/PiSmmCore: Implement heap guard feature for SMM mode
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Pool.c
index 36317563c419e325c3e14ad04e323315bf53ea29..e77caa88538b7f399670f4cccb8cc1ee96faee0b 100644 (file)
@@ -144,7 +144,9 @@ InternalAllocPoolByIndex (
   Status = EFI_SUCCESS;\r
   Hdr = NULL;\r
   if (PoolIndex == MAX_POOL_INDEX) {\r
   Status = EFI_SUCCESS;\r
   Hdr = NULL;\r
   if (PoolIndex == MAX_POOL_INDEX) {\r
-    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address);\r
+    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType,
+                                       EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1),
+                                       &Address, FALSE);
     if (EFI_ERROR (Status)) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
@@ -243,6 +245,9 @@ SmmInternalAllocatePool (
   EFI_STATUS            Status;\r
   EFI_PHYSICAL_ADDRESS  Address;\r
   UINTN                 PoolIndex;\r
   EFI_STATUS            Status;\r
   EFI_PHYSICAL_ADDRESS  Address;\r
   UINTN                 PoolIndex;\r
+  BOOLEAN               HasPoolTail;
+  BOOLEAN               NeedGuard;
+  UINTN                 NoPages;
 \r
   Address = 0;\r
 \r
 \r
   Address = 0;\r
 \r
@@ -251,25 +256,47 @@ SmmInternalAllocatePool (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  NeedGuard   = IsPoolTypeToGuard (PoolType);
+  HasPoolTail = !(NeedGuard &&
+                  ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+
   //\r
   // Adjust the size by the pool header & tail overhead\r
   //\r
   Size += POOL_OVERHEAD;\r
   //\r
   // Adjust the size by the pool header & tail overhead\r
   //\r
   Size += POOL_OVERHEAD;\r
-  if (Size > MAX_POOL_SIZE) {\r
-    Size = EFI_SIZE_TO_PAGES (Size);\r
-    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, Size, &Address);\r
+  if (Size > MAX_POOL_SIZE || NeedGuard) {
+    if (!HasPoolTail) {
+      Size -= sizeof (POOL_TAIL);
+    }
+
+    NoPages = EFI_SIZE_TO_PAGES (Size);
+    Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, NoPages,
+                                       &Address, NeedGuard);
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
+    if (NeedGuard) {
+      ASSERT (VerifyMemoryGuard (Address, NoPages) == TRUE);
+      Address = (EFI_PHYSICAL_ADDRESS)(UINTN)AdjustPoolHeadA (
+                                               Address,
+                                               NoPages,
+                                               Size
+                                               );
+    }
+
     PoolHdr = (POOL_HEADER*)(UINTN)Address;\r
     PoolHdr->Signature = POOL_HEAD_SIGNATURE;\r
     PoolHdr = (POOL_HEADER*)(UINTN)Address;\r
     PoolHdr->Signature = POOL_HEAD_SIGNATURE;\r
-    PoolHdr->Size = EFI_PAGES_TO_SIZE (Size);\r
+    PoolHdr->Size = Size;
     PoolHdr->Available = FALSE;\r
     PoolHdr->Type = PoolType;\r
     PoolHdr->Available = FALSE;\r
     PoolHdr->Type = PoolType;\r
-    PoolTail = HEAD_TO_TAIL(PoolHdr);\r
-    PoolTail->Signature = POOL_TAIL_SIGNATURE;\r
-    PoolTail->Size = PoolHdr->Size;\r
+
+    if (HasPoolTail) {
+      PoolTail = HEAD_TO_TAIL (PoolHdr);
+      PoolTail->Signature = POOL_TAIL_SIGNATURE;
+      PoolTail->Size = PoolHdr->Size;
+    }
+
     *Buffer = PoolHdr + 1;\r
     return Status;\r
   }\r
     *Buffer = PoolHdr + 1;\r
     return Status;\r
   }\r
@@ -341,28 +368,47 @@ SmmInternalFreePool (
 {\r
   FREE_POOL_HEADER  *FreePoolHdr;\r
   POOL_TAIL         *PoolTail;\r
 {\r
   FREE_POOL_HEADER  *FreePoolHdr;\r
   POOL_TAIL         *PoolTail;\r
+  BOOLEAN           HasPoolTail;
+  BOOLEAN           MemoryGuarded;
 \r
   if (Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
 \r
   if (Buffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  MemoryGuarded = IsHeapGuardEnabled () &&
+                  IsMemoryGuarded ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer);
+  HasPoolTail   = !(MemoryGuarded &&
+                    ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));
+
   FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1);\r
   ASSERT (FreePoolHdr->Header.Signature == POOL_HEAD_SIGNATURE);\r
   ASSERT (!FreePoolHdr->Header.Available);\r
   FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1);\r
   ASSERT (FreePoolHdr->Header.Signature == POOL_HEAD_SIGNATURE);\r
   ASSERT (!FreePoolHdr->Header.Available);\r
-  PoolTail = HEAD_TO_TAIL(&FreePoolHdr->Header);\r
-  ASSERT (PoolTail->Signature == POOL_TAIL_SIGNATURE);\r
-  ASSERT (FreePoolHdr->Header.Size == PoolTail->Size);\r
-\r
   if (FreePoolHdr->Header.Signature != POOL_HEAD_SIGNATURE) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if (FreePoolHdr->Header.Signature != POOL_HEAD_SIGNATURE) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (PoolTail->Signature != POOL_TAIL_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
+  if (HasPoolTail) {
+    PoolTail = HEAD_TO_TAIL (&FreePoolHdr->Header);
+    ASSERT (PoolTail->Signature == POOL_TAIL_SIGNATURE);
+    ASSERT (FreePoolHdr->Header.Size == PoolTail->Size);
+    if (PoolTail->Signature != POOL_TAIL_SIGNATURE) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (FreePoolHdr->Header.Size != PoolTail->Size) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } else {
+    PoolTail = NULL;
   }\r
 \r
   }\r
 \r
-  if (FreePoolHdr->Header.Size != PoolTail->Size) {\r
-    return EFI_INVALID_PARAMETER;\r
+  if (MemoryGuarded) {
+    Buffer = AdjustPoolHeadF ((EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr);
+    return SmmInternalFreePages (
+             (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer,
+             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),
+             TRUE
+             );
   }\r
 \r
   if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {\r
   }\r
 \r
   if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {\r
@@ -370,7 +416,8 @@ SmmInternalFreePool (
     ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);\r
     return SmmInternalFreePages (\r
              (EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,\r
     ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);\r
     return SmmInternalFreePages (\r
              (EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,\r
-             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size)\r
+             EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size),
+             FALSE
              );\r
   }\r
   return InternalFreePoolByIndex (FreePoolHdr, PoolTail);\r
              );\r
   }\r
   return InternalFreePoolByIndex (FreePoolHdr, PoolTail);\r