]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Sec: assert the build-time calculated end of the scratch buffer
authorLaszlo Ersek <lersek@redhat.com>
Mon, 30 Nov 2015 18:41:20 +0000 (18:41 +0000)
committerlersek <lersek@Edk2>
Mon, 30 Nov 2015 18:41:20 +0000 (18:41 +0000)
The DecompressMemFvs() function in "OvmfPkg/Sec/SecMain.c" uses more
memory, temporarily, than what PEIFV and DXEFV will ultimately need.
First, it uses an output buffer for decompression, second, the
decompression itself needs a scratch buffer (and this scratch buffer is
the highest area that SEC uses).

DecompressMemFvs() used to be called on normal boots only (ie. not on S3
resume), which is why the decompression output buffer and the scratch
buffer were allowed to scribble over RAM. However, we'll soon start to
worry during S3 resume that the runtime OS might tamper with the
pre-decompressed PEIFV, and we'll decompress the firmware volumes on S3
resume too, from pristine flash. For this we'll need to know the end of
the scratch buffer in advance, so we can prepare a non-malicious OS for
it.

Calculate the end of the scratch buffer statically in the FDF files, and
assert in DecompressMemFvs() that the runtime decompression will match it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19036 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/DecomprScratchEnd.fdf.inc [new file with mode: 0644]
OvmfPkg/OvmfPkg.dec
OvmfPkg/OvmfPkg.fdf.inc
OvmfPkg/OvmfPkgIa32.fdf
OvmfPkg/OvmfPkgIa32X64.fdf
OvmfPkg/OvmfPkgX64.fdf
OvmfPkg/Sec/SecMain.c
OvmfPkg/Sec/SecMain.inf

diff --git a/OvmfPkg/DecomprScratchEnd.fdf.inc b/OvmfPkg/DecomprScratchEnd.fdf.inc
new file mode 100644 (file)
index 0000000..eb5cd49
--- /dev/null
@@ -0,0 +1,72 @@
+## @file\r
+#  This FDF include file computes the end of the scratch buffer used in\r
+#  DecompressMemFvs() [OvmfPkg/Sec/SecMain.c]. It is based on the decompressed\r
+#  (ie. original) size of the LZMA-compressed section of the one FFS file in\r
+#  the FVMAIN_COMPACT firmware volume.\r
+#\r
+#  Copyright (C) 2015, Red Hat, Inc.\r
+#\r
+#  This program and the accompanying materials are licensed and made available\r
+#  under the terms and conditions of the BSD License which accompanies this\r
+#  distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR\r
+#  IMPLIED.\r
+##\r
+\r
+# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompress".\r
+# The decompressed output will have the following structure (see the file\r
+# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the\r
+# Build/Ovmf*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ directory):\r
+#\r
+# Size                 Contents\r
+# -------------------  --------------------------------------------------------\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) and\r
+#                      type 0x19 (EFI_SECTION_RAW). The purpose of this section\r
+#                      is to pad the start of PEIFV to 128 bytes.\r
+#                 120  Zero bytes (padding).\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size\r
+#                      (PcdOvmfPeiMemFvSize + 4), and type 0x17\r
+#                      (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).\r
+# PcdOvmfPeiMemFvSize  PEIFV. Note that the above sizes pad the offset of this\r
+#                      object to 128 bytes. See also the "guided.dummy.txt"\r
+#                      file in the same directory.\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and\r
+#                      type 0x19 (EFI_SECTION_RAW). The purpose of this section\r
+#                      is to pad the start of DXEFV to 16 bytes.\r
+#                   8  Zero bytes (padding).\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size\r
+#                      (PcdOvmfDxeMemFvSize + 4), and type 0x17\r
+#                      (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).\r
+# PcdOvmfDxeMemFvSize  DXEFV. Note that the above sizes pad the offset of this\r
+#                      object to 16 bytes. See also the "guided.dummy.txt" file\r
+#                      in the same directory.\r
+#\r
+# The total size after decompression is (128 + PcdOvmfPeiMemFvSize + 16 +\r
+# PcdOvmfDxeMemFvSize).\r
+\r
+DEFINE OUTPUT_SIZE = (128 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize + 16 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize)\r
+\r
+# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see\r
+# SCRATCH_BUFFER_REQUEST_SIZE in\r
+# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c".\r
+\r
+DEFINE DECOMP_SCRATCH_SIZE = 0x00010000\r
+\r
+# Note: when we use PcdOvmfDxeMemFvBase in this context, BaseTools have not yet\r
+# offset it with MEMFD's base address. For that reason we have to do it manually.\r
+#\r
+# The calculation below mirrors DecompressMemFvs() [OvmfPkg/Sec/SecMain.c].\r
+\r
+DEFINE OUTPUT_BASE                   = ($(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase + 0x00100000)\r
+DEFINE DECOMP_SCRATCH_BASE_UNALIGNED = ($(OUTPUT_BASE) + $(OUTPUT_SIZE))\r
+DEFINE DECOMP_SCRATCH_BASE_ALIGNMENT = 0x000FFFFF\r
+DEFINE DECOMP_SCRATCH_BASE_MASK      = 0xFFF00000\r
+DEFINE DECOMP_SCRATCH_BASE           = (($(DECOMP_SCRATCH_BASE_UNALIGNED) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK))\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)\r
index 47b0e696292847af66235b8c4e892c400ef13d07..1c9f8312b560d56858ebad7825d5264517369ca0 100644 (file)
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|0x0|UINT32|0x18\r
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize|0x0|UINT32|0x19\r
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd|0x0|UINT32|0x1f\r
 \r
 [PcdsDynamic, PcdsDynamicEx]\r
   gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2\r
index 486bbc61eadb47f7a818310bae5e8ec64fad7a37..441c35acfa5cf10bcfc71e4944d0a83b07400fc0 100644 (file)
@@ -60,3 +60,5 @@ SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZ
 \r
 SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize\r
 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x10000\r
+\r
+DEFINE MEMFD_BASE_ADDRESS = 0x800000\r
index d4ae2f98acd0d50aac2e3ac0b425474b2508e2d4..30bd3bc79f6ba600a3d83e3bda752632f7173477 100644 (file)
@@ -78,7 +78,7 @@ FV = SECFV
 ################################################################################\r
 \r
 [FD.MEMFD]\r
-BaseAddress   = 0x800000\r
+BaseAddress   = $(MEMFD_BASE_ADDRESS)\r
 Size          = 0xA00000\r
 ErasePolarity = 1\r
 BlockSize     = 0x10000\r
@@ -384,6 +384,8 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
    }\r
  }\r
 \r
+!include DecomprScratchEnd.fdf.inc\r
+\r
 ################################################################################\r
 \r
 [Rule.Common.SEC]\r
index 5b4d9dc464b9dd9a4a6b122f1b7b49b989c699f8..59c3362950b83660ad126e85745f945872d458c7 100644 (file)
@@ -78,7 +78,7 @@ FV = SECFV
 ################################################################################\r
 \r
 [FD.MEMFD]\r
-BaseAddress   = 0x800000\r
+BaseAddress   = $(MEMFD_BASE_ADDRESS)\r
 Size          = 0xA00000\r
 ErasePolarity = 1\r
 BlockSize     = 0x10000\r
@@ -384,6 +384,8 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
    }\r
  }\r
 \r
+!include DecomprScratchEnd.fdf.inc\r
+\r
 ################################################################################\r
 \r
 [Rule.Common.SEC]\r
index 8b4dd60605f942682d549048f0a5817e0414adce..6ba1948faa165113bbf596179af92e3e8231e520 100644 (file)
@@ -78,7 +78,7 @@ FV = SECFV
 ################################################################################\r
 \r
 [FD.MEMFD]\r
-BaseAddress   = 0x800000\r
+BaseAddress   = $(MEMFD_BASE_ADDRESS)\r
 Size          = 0xA00000\r
 ErasePolarity = 1\r
 BlockSize     = 0x10000\r
@@ -384,6 +384,8 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
    }\r
  }\r
 \r
+!include DecomprScratchEnd.fdf.inc\r
+\r
 ################################################################################\r
 \r
 [Rule.Common.SEC]\r
index 0cf127af8486cd5077164846e137ee8a9854c742..93e3594e29aa6d0c39eefea3165b38c698e2ca65 100644 (file)
@@ -362,6 +362,14 @@ DecompressMemFvs (
 \r
   OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);\r
   ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);\r
+\r
+  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "\r
+    "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,\r
+    OutputBufferSize, ScratchBuffer, ScratchBufferSize,\r
+    PcdGet32 (PcdOvmfDecompressionScratchEnd)));\r
+  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==\r
+    PcdGet32 (PcdOvmfDecompressionScratchEnd));\r
+\r
   Status = ExtractGuidedSectionDecode (\r
              Section,\r
              &OutputBuffer,\r
index 415731ce546b51d5e637d1e160ec7b5bdfbc654b..9e8571dddd7f46998af2205121ba46e2c153f8de 100644 (file)
@@ -70,3 +70,4 @@
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize\r
   gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress\r
   gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd\r