]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Image/Image.c
MdeModulePkg DxeCore/PiSmmCore: Add UEFI memory and SMRAM profile support.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Image / Image.c
index 32f3898ec28589831a76bd50b967409a439f309e..5b441f03fbbf089edb78a32a83d3fe63eb661d2a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Core image handling services to load and unload PeImage.\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -389,7 +389,10 @@ GetPeCoffImageFixLoadingAssignedAddress(
      if (EFI_ERROR (Status)) {\r
        return Status;\r
      }\r
-     \r
+     if (Size != sizeof (EFI_IMAGE_SECTION_HEADER)) {\r
+       return EFI_NOT_FOUND;\r
+     }\r
+\r
      Status = EFI_NOT_FOUND;\r
      \r
      if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
@@ -851,6 +854,9 @@ CoreUnloadAndCloseImage (
   UINTN                               OpenInfoCount;\r
   UINTN                               OpenInfoIndex;\r
 \r
+  HandleBuffer = NULL;\r
+  ProtocolGuidArray = NULL;\r
+\r
   if (Image->Ebc != NULL) {\r
     //\r
     // If EBC protocol exists we must perform cleanups for this image.\r
@@ -1044,6 +1050,7 @@ CoreLoadImageCommon (
   EFI_DEVICE_PATH_PROTOCOL   *OriginalFilePath;\r
   EFI_DEVICE_PATH_PROTOCOL   *HandleFilePath;\r
   UINTN                      FilePathSize;\r
+  BOOLEAN                    ImageIsFromFv;\r
 \r
   SecurityStatus = EFI_SUCCESS;\r
 \r
@@ -1070,13 +1077,18 @@ CoreLoadImageCommon (
   DeviceHandle     = NULL;\r
   Status           = EFI_SUCCESS;\r
   AuthenticationStatus = 0;\r
+  ImageIsFromFv    = FALSE;\r
+\r
   //\r
   // If the caller passed a copy of the file, then just use it\r
   //\r
   if (SourceBuffer != NULL) {\r
     FHand.Source     = SourceBuffer;\r
     FHand.SourceSize = SourceSize;\r
-    CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+    Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      DeviceHandle = NULL;\r
+    }\r
     if (SourceSize > 0) {\r
       Status = EFI_SUCCESS;\r
     } else {\r
@@ -1103,7 +1115,9 @@ CoreLoadImageCommon (
       //\r
       FHand.FreeBuffer = TRUE;\r
       Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);\r
-      if (EFI_ERROR (Status)) {\r
+      if (!EFI_ERROR (Status)) {\r
+        ImageIsFromFv = TRUE;\r
+      } else {\r
         HandleFilePath = FilePath;\r
         Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle);\r
         if (EFI_ERROR (Status)) {\r
@@ -1120,43 +1134,72 @@ CoreLoadImageCommon (
     }\r
   }\r
 \r
-  if (Status == EFI_ALREADY_STARTED) {\r
+  if (EFI_ERROR (Status)) {\r
     Image = NULL;\r
     goto Done;\r
-  } else if (EFI_ERROR (Status)) {\r
-    return Status;\r
   }\r
 \r
-  //\r
-  // Verify the Authentication Status through the Security Architectural Protocol\r
-  //\r
-  if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {\r
+  if (gSecurity2 != NULL) {\r
+    //\r
+    // Verify File Authentication through the Security2 Architectural Protocol\r
+    //\r
+    SecurityStatus = gSecurity2->FileAuthentication (\r
+                                  gSecurity2,\r
+                                  OriginalFilePath,\r
+                                  FHand.Source,\r
+                                  FHand.SourceSize,\r
+                                  BootPolicy\r
+                                  );\r
+    if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) {\r
+      //\r
+      // When Security2 is installed, Security Architectural Protocol must be published.\r
+      //\r
+      ASSERT (gSecurity != NULL);\r
+\r
+      //\r
+      // Verify the Authentication Status through the Security Architectural Protocol\r
+      // Only on images that have been read using Firmware Volume protocol.\r
+      //\r
+      SecurityStatus = gSecurity->FileAuthenticationState (\r
+                                    gSecurity,\r
+                                    AuthenticationStatus,\r
+                                    OriginalFilePath\r
+                                    );\r
+    }\r
+  } else if ((gSecurity != NULL) && (OriginalFilePath != NULL)) {\r
+    //\r
+    // Verify the Authentication Status through the Security Architectural Protocol\r
+    //\r
     SecurityStatus = gSecurity->FileAuthenticationState (\r
                                   gSecurity,\r
                                   AuthenticationStatus,\r
                                   OriginalFilePath\r
                                   );\r
-    if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {\r
-      if (SecurityStatus == EFI_ACCESS_DENIED) {\r
-        //\r
-        // Image was not loaded because the platform policy prohibits the image from being loaded.\r
-        // It's the only place we could meet EFI_ACCESS_DENIED.\r
-        //\r
-        *ImageHandle = NULL;\r
-      }\r
-      Status = SecurityStatus;\r
-      Image = NULL;\r
-      goto Done;\r
-    }\r
   }\r
 \r
+  //\r
+  // Check Security Status.\r
+  //\r
+  if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {\r
+    if (SecurityStatus == EFI_ACCESS_DENIED) {\r
+      //\r
+      // Image was not loaded because the platform policy prohibits the image from being loaded.\r
+      // It's the only place we could meet EFI_ACCESS_DENIED.\r
+      //\r
+      *ImageHandle = NULL;\r
+    }\r
+    Status = SecurityStatus;\r
+    Image = NULL;\r
+    goto Done;\r
+  }\r
 \r
   //\r
   // Allocate a new image structure\r
   //\r
   Image = AllocateZeroPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));\r
   if (Image == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
   }\r
 \r
   //\r
@@ -1295,11 +1338,19 @@ Done:
   if (EFI_ERROR (Status)) {\r
     if (Image != NULL) {\r
       CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));\r
+      Image = NULL;\r
     }\r
   } else if (EFI_ERROR (SecurityStatus)) {\r
     Status = SecurityStatus;\r
   }\r
 \r
+  //\r
+  // Track the return status from LoadImage.\r
+  //\r
+  if (Image != NULL) {\r
+    Image->LoadImageStatus = Status;\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -1492,6 +1543,7 @@ CoreLoadImageEx (
 \r
   @retval EFI_INVALID_PARAMETER   Invalid parameter\r
   @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate\r
+  @retval EFI_SECURITY_VIOLATION  The current platform policy specifies that the image should not be started.\r
   @retval EFI_SUCCESS             Successfully transfer control to the image's\r
                                   entry point.\r
 \r
@@ -1519,6 +1571,9 @@ CoreStartImage (
   if (Image == NULL  ||  Image->Started) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+  if (EFI_ERROR (Image->LoadImageStatus)) {\r
+    return Image->LoadImageStatus;\r
+  }\r
 \r
   //\r
   // The image to be started must have the machine type supported by DxeCore.\r
@@ -1571,6 +1626,7 @@ CoreStartImage (
   // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().\r
   //\r
   if (SetJumpFlag == 0) {\r
+    RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));\r
     //\r
     // Call the image's entry point\r
     //\r
@@ -1796,6 +1852,7 @@ CoreUnloadImage (
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
+  UnregisterMemoryProfileImage (Image);\r
 \r
   if (Image->Started) {\r
     //\r