]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
SecurityPkg/DxeImageVerificationLib: refactor db/dbx fetching code (CVE-2019-14575)
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / DxeImageVerificationLib.c
index fe4cdccedd5a1397480a4862973581cd8fa544ba..8739d1fa294612ebb930143bac7d157532ec6550 100644 (file)
@@ -704,7 +704,7 @@ GetImageExeInfoTableSize (
   @param[in]  Name            Input a null-terminated, user-friendly name.\r
   @param[in]  DevicePath      Input device path pointer.\r
   @param[in]  Signature       Input signature info in EFI_SIGNATURE_LIST data structure.\r
-  @param[in]  SignatureSize   Size of signature.\r
+  @param[in]  SignatureSize   Size of signature. Must be zero if Signature is NULL.\r
 \r
 **/\r
 VOID\r
@@ -745,7 +745,7 @@ AddImageExeInfo (
   if (ImageExeInfoTable != NULL) {\r
     //\r
     // The table has been found!\r
-    // We must enlarge the table to accomodate the new exe info entry.\r
+    // We must enlarge the table to accommodate the new exe info entry.\r
     //\r
     ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);\r
   } else {\r
@@ -761,6 +761,7 @@ AddImageExeInfo (
   //\r
   // Signature size can be odd. Pad after signature to ensure next EXECUTION_INFO entry align\r
   //\r
+  ASSERT (Signature != NULL || SignatureSize == 0);\r
   NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;\r
 \r
   NewImageExeInfoTable      = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);\r
@@ -907,6 +908,9 @@ IsCertHashFoundInDatabase (
       goto Done;\r
     }\r
 \r
+    FreePool (HashCtx);\r
+    HashCtx = NULL;\r
+\r
     SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;\r
     CertHash          = (EFI_SIGNATURE_DATA *) ((UINT8 *) DbxList + SiglistHeaderSize);\r
     CertHashCount     = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;\r
@@ -947,7 +951,7 @@ Done:
 \r
   @param[in]  VariableName        Name of database variable that is searched in.\r
   @param[in]  Signature           Pointer to signature that is searched for.\r
-  @param[in]  CertType            Pointer to hash algrithom.\r
+  @param[in]  CertType            Pointer to hash algorithm.\r
   @param[in]  SignatureSize       Size of Signature.\r
 \r
   @return TRUE                    Found the signature in the variable database.\r
@@ -992,7 +996,7 @@ IsSignatureFoundInDatabase (
     goto Done;\r
   }\r
   //\r
-  // Enumerate all signature data in SigDB to check if executable's signature exists.\r
+  // Enumerate all signature data in SigDB to check if signature exists for executable.\r
   //\r
   CertList = (EFI_SIGNATURE_LIST *) Data;\r
   while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
@@ -1322,7 +1326,7 @@ IsForbiddenByDbx (
   //       UINT8  Certn[];\r
   //\r
   Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);\r
-  if ((BufferLength == 0) || (CertBuffer == NULL)) {\r
+  if ((BufferLength == 0) || (CertBuffer == NULL) || (*CertBuffer) == 0) {\r
     IsForbidden = TRUE;\r
     goto Done;\r
   }\r
@@ -1408,64 +1412,92 @@ IsAllowedByDb (
   RootCertSize      = 0;\r
   VerifyStatus      = FALSE;\r
 \r
+  //\r
+  // Fetch 'db' content. If 'db' doesn't exist or encounters problem to get the\r
+  // data, return not-allowed-by-db (FALSE).\r
+  //\r
   DataSize = 0;\r
   Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    Data = (UINT8 *) AllocateZeroPool (DataSize);\r
-    if (Data == NULL) {\r
-      return VerifyStatus;\r
+  ASSERT (EFI_ERROR (Status));\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return VerifyStatus;\r
+  }\r
+\r
+  Data = (UINT8 *) AllocateZeroPool (DataSize);\r
+  if (Data == NULL) {\r
+    return VerifyStatus;\r
+  }\r
+\r
+  Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Fetch 'dbx' content. If 'dbx' doesn't exist, continue to check 'db'.\r
+  // If any other errors occured, no need to check 'db' but just return\r
+  // not-allowed-by-db (FALSE) to avoid bypass.\r
+  //\r
+  DbxDataSize = 0;\r
+  Status      = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
+  ASSERT (EFI_ERROR (Status));\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    if (Status != EFI_NOT_FOUND) {\r
+      goto Done;\r
+    }\r
+    //\r
+    // 'dbx' does not exist. Continue to check 'db'.\r
+    //\r
+  } else {\r
+    //\r
+    // 'dbx' exists. Get its content.\r
+    //\r
+    DbxData = (UINT8 *) AllocateZeroPool (DbxDataSize);\r
+    if (DbxData == NULL) {\r
+      goto Done;\r
     }\r
 \r
-    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);\r
+    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *) DbxData);\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
+  }\r
 \r
-    //\r
-    // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
-    //\r
-    CertList = (EFI_SIGNATURE_LIST *) Data;\r
-    while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
-      if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
-        CertData  = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
-        CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
+  //\r
+  // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.\r
+  //\r
+  CertList = (EFI_SIGNATURE_LIST *) Data;\r
+  while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {\r
+    if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+      CertData  = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
+      CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
 \r
-        for (Index = 0; Index < CertCount; Index++) {\r
-          //\r
-          // Iterate each Signature Data Node within this CertList for verify.\r
-          //\r
-          RootCert     = CertData->SignatureData;\r
-          RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
+      for (Index = 0; Index < CertCount; Index++) {\r
+        //\r
+        // Iterate each Signature Data Node within this CertList for verify.\r
+        //\r
+        RootCert     = CertData->SignatureData;\r
+        RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);\r
 \r
+        //\r
+        // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+        //\r
+        VerifyStatus = AuthenticodeVerify (\r
+                         AuthData,\r
+                         AuthDataSize,\r
+                         RootCert,\r
+                         RootCertSize,\r
+                         mImageDigest,\r
+                         mImageDigestSize\r
+                         );\r
+        if (VerifyStatus) {\r
           //\r
-          // Call AuthenticodeVerify library to Verify Authenticode struct.\r
+          // The image is signed and its signature is found in 'db'.\r
           //\r
-          VerifyStatus = AuthenticodeVerify (\r
-                           AuthData,\r
-                           AuthDataSize,\r
-                           RootCert,\r
-                           RootCertSize,\r
-                           mImageDigest,\r
-                           mImageDigestSize\r
-                           );\r
-          if (VerifyStatus) {\r
+          if (DbxData != NULL) {\r
             //\r
             // Here We still need to check if this RootCert's Hash is revoked\r
             //\r
-            Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);\r
-            if (Status == EFI_BUFFER_TOO_SMALL) {\r
-              goto Done;\r
-            }\r
-            DbxData = (UINT8 *) AllocateZeroPool (DbxDataSize);\r
-            if (DbxData == NULL) {\r
-              goto Done;\r
-            }\r
-\r
-            Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *) DbxData);\r
-            if (EFI_ERROR (Status)) {\r
-              goto Done;\r
-            }\r
-\r
             if (IsCertHashFoundInDatabase (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime)) {\r
               //\r
               // Check the timestamp signature and signing time to determine if the RootCert can be trusted.\r
@@ -1475,17 +1507,23 @@ IsAllowedByDb (
                 DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed and signature is accepted by DB, but its root cert failed the timestamp check.\n"));\r
               }\r
             }\r
-\r
-            goto Done;\r
           }\r
 \r
-          CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+          //\r
+          // There's no 'dbx' to check revocation time against (must-be pass),\r
+          // or, there's revocation time found in 'dbx' and checked againt 'dbt'\r
+          // (maybe pass or fail, depending on timestamp compare result). Either\r
+          // way the verification job has been completed at this point.\r
+          //\r
+          goto Done;\r
         }\r
-      }\r
 \r
-      DataSize -= CertList->SignatureListSize;\r
-      CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
+        CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertData + CertList->SignatureSize);\r
+      }\r
     }\r
+\r
+    DataSize -= CertList->SignatureListSize;\r
+    CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
   }\r
 \r
 Done:\r
@@ -1541,14 +1579,14 @@ Done:
                                  and non-NULL FileBuffer did authenticate, and the platform\r
                                  policy dictates that the DXE Foundation may execute the image in\r
                                  FileBuffer.\r
-  @retval EFI_OUT_RESOURCE       Fail to allocate memory.\r
   @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and\r
                                  the platform policy dictates that File should be placed\r
                                  in the untrusted state. The image has been added to the file\r
                                  execution table.\r
   @retval EFI_ACCESS_DENIED      The file specified by File and FileBuffer did not\r
                                  authenticate, and the platform policy dictates that the DXE\r
-                                 Foundation many not use File.\r
+                                 Foundation may not use File. The image has\r
+                                 been added to the file execution table.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1561,9 +1599,8 @@ DxeImageVerificationHandler (
   IN  BOOLEAN                          BootPolicy\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
   EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
-  EFI_STATUS                           VerifyStatus;\r
+  BOOLEAN                              IsVerified;\r
   EFI_SIGNATURE_LIST                   *SignatureList;\r
   UINTN                                SignatureListSize;\r
   EFI_SIGNATURE_DATA                   *Signature;\r
@@ -1580,6 +1617,8 @@ DxeImageVerificationHandler (
   EFI_IMAGE_DATA_DIRECTORY             *SecDataDir;\r
   UINT32                               OffSet;\r
   CHAR16                               *NameStr;\r
+  RETURN_STATUS                        PeCoffStatus;\r
+  EFI_STATUS                           HashStatus;\r
 \r
   SignatureList     = NULL;\r
   SignatureListSize = 0;\r
@@ -1587,8 +1626,7 @@ DxeImageVerificationHandler (
   SecDataDir        = NULL;\r
   PkcsCertData      = NULL;\r
   Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
-  Status            = EFI_ACCESS_DENIED;\r
-  VerifyStatus      = EFI_ACCESS_DENIED;\r
+  IsVerified        = FALSE;\r
 \r
 \r
   //\r
@@ -1621,7 +1659,8 @@ DxeImageVerificationHandler (
   //\r
   if (Policy == ALWAYS_EXECUTE) {\r
     return EFI_SUCCESS;\r
-  } else if (Policy == NEVER_EXECUTE) {\r
+  }\r
+  if (Policy == NEVER_EXECUTE) {\r
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
@@ -1655,7 +1694,7 @@ DxeImageVerificationHandler (
   // Read the Dos header.\r
   //\r
   if (FileBuffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+    return EFI_ACCESS_DENIED;\r
   }\r
 \r
   mImageBase  = (UINT8 *) FileBuffer;\r
@@ -1668,17 +1707,15 @@ DxeImageVerificationHandler (
   //\r
   // Get information about the image being loaded\r
   //\r
-  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
+  PeCoffStatus = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (RETURN_ERROR (PeCoffStatus)) {\r
     //\r
     // The information can't be got from the invalid PeImage\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: PeImage invalid. Cannot retrieve image information.\n"));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
-  Status = EFI_ACCESS_DENIED;\r
-\r
   DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
   if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
     //\r
@@ -1698,7 +1735,7 @@ DxeImageVerificationHandler (
     // It is not a valid Pe/Coff file.\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Not a valid PE/COFF image.\n"));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
   if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
@@ -1729,7 +1766,7 @@ DxeImageVerificationHandler (
     //\r
     if (!HashPeImage (HASHALG_SHA256)) {\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHashTypeStr));\r
-      goto Done;\r
+      goto Failed;\r
     }\r
 \r
     if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
@@ -1737,7 +1774,7 @@ DxeImageVerificationHandler (
       // Image Hash is in forbidden database (DBX).\r
       //\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));\r
-      goto Done;\r
+      goto Failed;\r
     }\r
 \r
     if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
@@ -1751,7 +1788,7 @@ DxeImageVerificationHandler (
     // Image Hash is not found in both forbidden and allowed database.\r
     //\r
     DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
-    goto Done;\r
+    goto Failed;\r
   }\r
 \r
   //\r
@@ -1802,8 +1839,8 @@ DxeImageVerificationHandler (
       continue;\r
     }\r
 \r
-    Status = HashPeImageByType (AuthData, AuthDataSize);\r
-    if (EFI_ERROR (Status)) {\r
+    HashStatus = HashPeImageByType (AuthData, AuthDataSize);\r
+    if (EFI_ERROR (HashStatus)) {\r
       continue;\r
     }\r
 \r
@@ -1812,16 +1849,16 @@ DxeImageVerificationHandler (
     //\r
     if (IsForbiddenByDbx (AuthData, AuthDataSize)) {\r
       Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;\r
-      VerifyStatus = EFI_ACCESS_DENIED;\r
+      IsVerified = FALSE;\r
       break;\r
     }\r
 \r
     //\r
     // Check the digital signature against the valid certificate in allowed database (db).\r
     //\r
-    if (EFI_ERROR (VerifyStatus)) {\r
+    if (!IsVerified) {\r
       if (IsAllowedByDb (AuthData, AuthDataSize)) {\r
-        VerifyStatus = EFI_SUCCESS;\r
+        IsVerified = TRUE;\r
       }\r
     }\r
 \r
@@ -1831,11 +1868,12 @@ DxeImageVerificationHandler (
     if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, mImageDigest, &mCertType, mImageDigestSize)) {\r
       Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;\r
       DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but %s hash of image is found in DBX.\n", mHashTypeStr));\r
-      VerifyStatus = EFI_ACCESS_DENIED;\r
+      IsVerified = FALSE;\r
       break;\r
-    } else if (EFI_ERROR (VerifyStatus)) {\r
+    }\r
+    if (!IsVerified) {\r
       if (IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, mImageDigest, &mCertType, mImageDigestSize)) {\r
-        VerifyStatus = EFI_SUCCESS;\r
+        IsVerified = TRUE;\r
       } else {\r
         DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));\r
       }\r
@@ -1844,53 +1882,52 @@ DxeImageVerificationHandler (
 \r
   if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size)) {\r
     //\r
-    // The Size in Certificate Table or the attribute certicate table is corrupted.\r
+    // The Size in Certificate Table or the attribute certificate table is corrupted.\r
     //\r
-    VerifyStatus = EFI_ACCESS_DENIED;\r
+    IsVerified = FALSE;\r
   }\r
 \r
-  if (!EFI_ERROR (VerifyStatus)) {\r
+  if (IsVerified) {\r
     return EFI_SUCCESS;\r
-  } else {\r
-    Status = EFI_ACCESS_DENIED;\r
-    if (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED || Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {\r
-      //\r
-      // Get image hash value as executable's signature.\r
-      //\r
-      SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
-      SignatureList     = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
-      if (SignatureList == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      SignatureList->SignatureHeaderSize  = 0;\r
-      SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
-      SignatureList->SignatureSize        = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
-      CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
-      Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
-      CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
-    }\r
   }\r
-\r
-Done:\r
-  if (Status != EFI_SUCCESS) {\r
+  if (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED || Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {\r
     //\r
-    // Policy decides to defer or reject the image; add its information in image executable information table.\r
+    // Get image hash value as signature of executable.\r
     //\r
-    NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
-    AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
-    if (NameStr != NULL) {\r
-      DEBUG((EFI_D_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
-      FreePool(NameStr);\r
+    SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;\r
+    SignatureList     = (EFI_SIGNATURE_LIST *) AllocateZeroPool (SignatureListSize);\r
+    if (SignatureList == NULL) {\r
+      SignatureListSize = 0;\r
+      goto Failed;\r
     }\r
-    Status = EFI_SECURITY_VIOLATION;\r
+    SignatureList->SignatureHeaderSize  = 0;\r
+    SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
+    SignatureList->SignatureSize        = (UINT32) (sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);\r
+    CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));\r
+    Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));\r
+    CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
+  }\r
+\r
+Failed:\r
+  //\r
+  // Policy decides to defer or reject the image; add its information in image\r
+  // executable information table in either case.\r
+  //\r
+  NameStr = ConvertDevicePathToText (File, FALSE, TRUE);\r
+  AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);\r
+  if (NameStr != NULL) {\r
+    DEBUG ((DEBUG_INFO, "The image doesn't pass verification: %s\n", NameStr));\r
+    FreePool(NameStr);\r
   }\r
 \r
   if (SignatureList != NULL) {\r
     FreePool (SignatureList);\r
   }\r
 \r
-  return Status;\r
+  if (Policy == DEFER_EXECUTE_ON_SECURITY_VIOLATION) {\r
+    return EFI_SECURITY_VIOLATION;\r
+  }\r
+  return EFI_ACCESS_DENIED;\r
 }\r
 \r
 /**\r