]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
SecurityPkg/DxeImageVerificationLib: reject CertStack.CertNumber==0 per DBX (CVE...
[mirror_edk2.git] / SecurityPkg / Library / DxeImageVerificationLib / DxeImageVerificationLib.c
index 6ccce1f35843a7e609871e1068198f0aef1f9ca1..5dcd6efed534668acf0c402c35afeee095ae3147 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
@@ -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
@@ -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
@@ -1547,7 +1551,8 @@ Done:
                                  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
@@ -1560,7 +1565,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
@@ -1588,7 +1592,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
@@ -1657,7 +1660,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
@@ -1676,7 +1679,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
@@ -1698,7 +1701,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 +1732,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 +1740,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 +1754,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
@@ -1860,7 +1863,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
-      goto Done;\r
+      SignatureListSize = 0;\r
+      goto Failed;\r
     }\r
     SignatureList->SignatureHeaderSize  = 0;\r
     SignatureList->SignatureListSize    = (UINT32) SignatureListSize;\r
@@ -1870,25 +1874,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