]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
SecurityPkg/DxeImageVerificationLib: Differentiate error/search result (1) (CVE-2019...
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / DxeImageVerificationLib.c
index 5cc82c1b3b224f41041932255dddde6beaf27102..85261ba7f2ae853c7cb67e846bda5297c98c2ef2 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
@@ -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
@@ -821,22 +822,23 @@ AddImageExeInfo (
   @param[in]  SignatureList     Pointer to the Signature List in forbidden database.\r
   @param[in]  SignatureListSize Size of Signature List.\r
   @param[out] RevocationTime    Return the time that the certificate was revoked.\r
+  @param[out] IsFound           Search result. Only valid if EFI_SUCCESS returned.\r
 \r
-  @return TRUE   The certificate hash is found in the forbidden database.\r
-  @return FALSE  The certificate hash is not found in the forbidden database.\r
+  @retval EFI_SUCCESS           Finished the search without any error.\r
+  @retval Others                Error occurred in the search of database.\r
 \r
 **/\r
-BOOLEAN\r
+EFI_STATUS\r
 IsCertHashFoundInDatabase (\r
   IN  UINT8               *Certificate,\r
   IN  UINTN               CertSize,\r
   IN  EFI_SIGNATURE_LIST  *SignatureList,\r
   IN  UINTN               SignatureListSize,\r
-  OUT EFI_TIME            *RevocationTime\r
+  OUT EFI_TIME            *RevocationTime,\r
+  OUT BOOLEAN             *IsFound\r
   )\r
 {\r
-  BOOLEAN             IsFound;\r
-  BOOLEAN             Status;\r
+  EFI_STATUS          Status;\r
   EFI_SIGNATURE_LIST  *DbxList;\r
   UINTN               DbxSize;\r
   EFI_SIGNATURE_DATA  *CertHash;\r
@@ -850,21 +852,22 @@ IsCertHashFoundInDatabase (
   UINT8               *TBSCert;\r
   UINTN               TBSCertSize;\r
 \r
-  IsFound  = FALSE;\r
+  Status   = EFI_ABORTED;\r
+  *IsFound = FALSE;\r
   DbxList  = SignatureList;\r
   DbxSize  = SignatureListSize;\r
   HashCtx  = NULL;\r
   HashAlg  = HASHALG_MAX;\r
 \r
   if ((RevocationTime == NULL) || (DbxList == NULL)) {\r
-    return FALSE;\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Retrieve the TBSCertificate from the X.509 Certificate.\r
   //\r
   if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {\r
-    return FALSE;\r
+    return Status;\r
   }\r
 \r
   while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {\r
@@ -894,19 +897,19 @@ IsCertHashFoundInDatabase (
     if (HashCtx == NULL) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashInit (HashCtx);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashInit (HashCtx)) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize)) {\r
       goto Done;\r
     }\r
-    Status = mHash[HashAlg].HashFinal (HashCtx, CertDigest);\r
-    if (!Status) {\r
+    if (!mHash[HashAlg].HashFinal (HashCtx, CertDigest)) {\r
       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
@@ -919,7 +922,8 @@ IsCertHashFoundInDatabase (
         //\r
         // Hash of Certificate is found in forbidden database.\r
         //\r
-        IsFound = TRUE;\r
+        Status   = EFI_SUCCESS;\r
+        *IsFound = TRUE;\r
 \r
         //\r
         // Return the revocation time.\r
@@ -934,12 +938,14 @@ IsCertHashFoundInDatabase (
     DbxList  = (EFI_SIGNATURE_LIST *) ((UINT8 *) DbxList + DbxList->SignatureListSize);\r
   }\r
 \r
+  Status = EFI_SUCCESS;\r
+\r
 Done:\r
   if (HashCtx != NULL) {\r
     FreePool (HashCtx);\r
   }\r
 \r
-  return IsFound;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -1212,6 +1218,7 @@ IsForbiddenByDbx (
 {\r
   EFI_STATUS                Status;\r
   BOOLEAN                   IsForbidden;\r
+  BOOLEAN                   IsFound;\r
   UINT8                     *Data;\r
   UINTN                     DataSize;\r
   EFI_SIGNATURE_LIST        *CertList;\r
@@ -1322,7 +1329,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
@@ -1340,20 +1347,29 @@ IsForbiddenByDbx (
     //\r
     CertPtr = CertPtr + sizeof (UINT32) + CertSize;\r
 \r
-    if (IsCertHashFoundInDatabase (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime)) {\r
+    Status = IsCertHashFoundInDatabase (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime, &IsFound);\r
+    if (EFI_ERROR (Status)) {\r
       //\r
-      // Check the timestamp signature and signing time to determine if the image can be trusted.\r
+      // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+      // not be valid in such situation.\r
       //\r
       IsForbidden = TRUE;\r
+    } else if (IsFound) {\r
+      //\r
+      // Found Cert in dbx successfully. Check the timestamp signature and\r
+      // signing time to determine if the image can be trusted.\r
+      //\r
       if (PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime)) {\r
         IsForbidden = FALSE;\r
         //\r
         // Pass DBT check. Continue to check other certs in image signer's cert list against DBX, DBT\r
         //\r
         continue;\r
+      } else {\r
+        IsForbidden = TRUE;\r
+        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
+        goto Done;\r
       }\r
-      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));\r
-      goto Done;\r
     }\r
 \r
   }\r
@@ -1388,6 +1404,7 @@ IsAllowedByDb (
 {\r
   EFI_STATUS                Status;\r
   BOOLEAN                   VerifyStatus;\r
+  BOOLEAN                   IsFound;\r
   EFI_SIGNATURE_LIST        *CertList;\r
   EFI_SIGNATURE_DATA        *CertData;\r
   UINTN                     DataSize;\r
@@ -1408,65 +1425,100 @@ 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
+            Status = IsCertHashFoundInDatabase (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime, &IsFound);\r
             if (EFI_ERROR (Status)) {\r
-              goto Done;\r
-            }\r
-\r
-            if (IsCertHashFoundInDatabase (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime)) {\r
+              //\r
+              // Error in searching dbx. Consider it as 'found'. RevocationTime might\r
+              // not be valid in such situation.\r
+              //\r
+              VerifyStatus = FALSE;\r
+            } else if (IsFound) {\r
               //\r
               // Check the timestamp signature and signing time to determine if the RootCert can be trusted.\r
               //\r
@@ -1475,17 +1527,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 +1599,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,7 +1619,6 @@ DxeImageVerificationHandler (
   IN  BOOLEAN                          BootPolicy\r
   )\r
 {\r
-  EFI_STATUS                           Status;\r
   EFI_IMAGE_DOS_HEADER                 *DosHdr;\r
   BOOLEAN                              IsVerified;\r
   EFI_SIGNATURE_LIST                   *SignatureList;\r
@@ -1589,7 +1646,6 @@ DxeImageVerificationHandler (
   SecDataDir        = NULL;\r
   PkcsCertData      = NULL;\r
   Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;\r
-  Status            = EFI_ACCESS_DENIED;\r
   IsVerified        = FALSE;\r
 \r
 \r
@@ -1658,7 +1714,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
@@ -1677,7 +1733,7 @@ DxeImageVerificationHandler (
     // 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
   DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;\r
@@ -1699,7 +1755,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
@@ -1730,7 +1786,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
@@ -1738,7 +1794,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
@@ -1752,7 +1808,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
@@ -1854,7 +1910,6 @@ DxeImageVerificationHandler (
   if (IsVerified) {\r
     return EFI_SUCCESS;\r
   }\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 signature of executable.\r
@@ -1862,8 +1917,8 @@ DxeImageVerificationHandler (
     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
+      SignatureListSize = 0;\r
+      goto Failed;\r
     }\r
     SignatureList->SignatureHeaderSize  = 0;\r
     SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
@@ -1873,25 +1928,26 @@ DxeImageVerificationHandler (
     CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);\r
   }\r
 \r
-Done:\r
-  if (Status != EFI_SUCCESS) {\r
-    //\r
-    // Policy decides to defer or reject the image; add its information in image executable information table.\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
-    }\r
-    Status = EFI_SECURITY_VIOLATION;\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