On 2015-07-24 16:00:11, Laszlo Ersek wrote: > 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 <[email protected]> > --- > OvmfPkg/Sec/SecMain.inf | 1 + > OvmfPkg/Sec/SecMain.c | 8 +++ > OvmfPkg/DecomprScratchEnd.fdf.inc | 72 ++++++++++++++++++++ > OvmfPkg/OvmfPkg.dec | 1 + > OvmfPkg/OvmfPkg.fdf.inc | 2 + > OvmfPkg/OvmfPkgIa32.fdf | 4 +- > OvmfPkg/OvmfPkgIa32X64.fdf | 4 +- > OvmfPkg/OvmfPkgX64.fdf | 4 +- > 8 files changed, 93 insertions(+), 3 deletions(-) > > diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf > index fce99fb..0bd9f83 100644 > --- a/OvmfPkg/Sec/SecMain.inf > +++ b/OvmfPkg/Sec/SecMain.inf > @@ -67,3 +67,4 @@ [Pcd] > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize > + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecomprScratchEnd
I think we should just make Decompr => Decompression. It seems a bit odd to add the PCD for 'End' without 'Base'. Another thought is to add PcdOvmfDecompressionBufferBase/End that covers the entire block of RAM used for the decompression process. This is not a big deal to me. > diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c > index 670ad8d..348d2b3 100644 > --- a/OvmfPkg/Sec/SecMain.c > +++ b/OvmfPkg/Sec/SecMain.c > @@ -361,6 +361,14 @@ DecompressMemFvs ( > > OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + > SIZE_1MB); > ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, > SIZE_1MB); > + > + DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x " > + "PcdOvmfDecomprScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer, > + OutputBufferSize, ScratchBuffer, ScratchBufferSize, > + PcdGet32 (PcdOvmfDecomprScratchEnd))); > + ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize == > + PcdGet32 (PcdOvmfDecomprScratchEnd)); > + > Status = ExtractGuidedSectionDecode ( > Section, > &OutputBuffer, > diff --git a/OvmfPkg/DecomprScratchEnd.fdf.inc > b/OvmfPkg/DecomprScratchEnd.fdf.inc > new file mode 100644 > index 0000000..75df974 > --- /dev/null > +++ b/OvmfPkg/DecomprScratchEnd.fdf.inc > @@ -0,0 +1,72 @@ > +## @file > +# This FDF include file computes the end of the scratch buffer used in > +# DecompressMemFvs() [OvmfPkg/Sec/SecMain.c]. It is based on the > decompressed > +# (ie. original) size of the LZMA-compressed section of the one FFS file in > +# the FVMAIN_COMPACT firmware volume. > +# > +# Copyright (C) 2015, Red Hat, Inc. > +# > +# This program and the accompanying materials are licensed and made > available > +# under the terms and conditions of the BSD License which accompanies this > +# distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > +# IMPLIED. > +## > + > +# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompress". > +# The decompressed output will have the following structure (see the file > +# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the > +# Build/Ovmf*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ directory): > +# > +# Size Contents > +# ------------------- > -------------------------------------------------------- > +# 4 EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) and > +# type 0x19 (EFI_SECTION_RAW). The purpose of this > section > +# is to pad the start of PEIFV to 128 bytes. > +# 120 Zero bytes (padding). > +# > +# 4 EFI_COMMON_SECTION_HEADER, stating size > +# (PcdOvmfPeiMemFvSize + 4), and type 0x17 > +# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE). > +# PcdOvmfPeiMemFvSize PEIFV. Note that the above sizes pad the offset of > this > +# object to 128 bytes. See also the "guided.dummy.txt" > +# file in the same directory. > +# > +# 4 EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and > +# type 0x19 (EFI_SECTION_RAW). The purpose of this > section > +# is to pad the start of DXEFV to 16 bytes. > +# 8 Zero bytes (padding). > +# > +# 4 EFI_COMMON_SECTION_HEADER, stating size > +# (PcdOvmfDxeMemFvSize + 4), and type 0x17 > +# (EFI_SECTION_FIRMWARE_VOLUME_IMAGE). > +# PcdOvmfDxeMemFvSize DXEFV. Note that the above sizes pad the offset of > this > +# object to 16 bytes. See also the "guided.dummy.txt" > file > +# in the same directory. > +# > +# The total size after decompression is (128 + PcdOvmfPeiMemFvSize + 16 + > +# PcdOvmfDxeMemFvSize). > + > +DEFINE OUTPUT_SIZE = (128 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize + > 16 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize) > + > +# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see > +# SCRATCH_BUFFER_REQUEST_SIZE in > +# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c". > + > +DEFINE SCRATCH_SIZE = 0x00010000 > + > +# Note: when we use PcdOvmfDxeMemFvBase in this context, BaseTools have not > yet > +# offset it with MEMFD's base address. For that reason we have to do it > manually. > +# > +# The calculation below mirrors DecompressMemFvs() [OvmfPkg/Sec/SecMain.c]. > + > +DEFINE OUTPUT_BASE = ($(MEMFD_BASE_ADDRESS) + > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase + 0x00100000) > +DEFINE SCRATCH_BASE_UNALIGNED = ($(OUTPUT_BASE) + $(OUTPUT_SIZE)) > +DEFINE SCRATCH_BASE_ALIGNMENT = 0x000FFFFF > +DEFINE SCRATCH_BASE_MASK = 0xFFF00000 > +DEFINE SCRATCH_BASE = (($(SCRATCH_BASE_UNALIGNED) + > $(SCRATCH_BASE_ALIGNMENT)) & $(SCRATCH_BASE_MASK)) This 'SCRATCH' name usage is pretty localized, but it is a pretty generic name. Maybe DECOMP_SCRATCH could be used instead. I think the shorter 'DECOMP' is okay here since it is the only file where these defines will be used. Once again, not really a big deal. Reviewed-by: Jordan Justen <[email protected]> > + > +SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecomprScratchEnd = $(SCRATCH_BASE) + > $(SCRATCH_SIZE) > diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec > index 54df0ef..f9422f0 100644 > --- a/OvmfPkg/OvmfPkg.dec > +++ b/OvmfPkg/OvmfPkg.dec > @@ -110,6 +110,7 @@ [PcdsFixedAtBuild] > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|0x0|UINT32|0x18 > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize|0x0|UINT32|0x19 > gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a > + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecomprScratchEnd|0x0|UINT32|0x1f > > [PcdsDynamic, PcdsDynamicEx] > gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2 > diff --git a/OvmfPkg/OvmfPkg.fdf.inc b/OvmfPkg/OvmfPkg.fdf.inc > index 486bbc6..441c35a 100644 > --- a/OvmfPkg/OvmfPkg.fdf.inc > +++ b/OvmfPkg/OvmfPkg.fdf.inc > @@ -60,3 +60,5 @@ > > SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = > gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize > SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x10000 > + > +DEFINE MEMFD_BASE_ADDRESS = 0x800000 > diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf > index 16675f8..efb4a4f 100644 > --- a/OvmfPkg/OvmfPkgIa32.fdf > +++ b/OvmfPkg/OvmfPkgIa32.fdf > @@ -78,7 +78,7 @@ [FD.OVMF_CODE] > > ################################################################################ > > [FD.MEMFD] > -BaseAddress = 0x800000 > +BaseAddress = $(MEMFD_BASE_ADDRESS) > Size = 0x900000 > ErasePolarity = 1 > BlockSize = 0x10000 > @@ -377,6 +377,8 @@ [FV.FVMAIN_COMPACT] > } > } > > +!include DecomprScratchEnd.fdf.inc > + > > ################################################################################ > > [Rule.Common.SEC] > diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf > index e6c525a..67c7b46 100644 > --- a/OvmfPkg/OvmfPkgIa32X64.fdf > +++ b/OvmfPkg/OvmfPkgIa32X64.fdf > @@ -78,7 +78,7 @@ [FD.OVMF_CODE] > > ################################################################################ > > [FD.MEMFD] > -BaseAddress = 0x800000 > +BaseAddress = $(MEMFD_BASE_ADDRESS) > Size = 0x900000 > ErasePolarity = 1 > BlockSize = 0x10000 > @@ -377,6 +377,8 @@ [FV.FVMAIN_COMPACT] > } > } > > +!include DecomprScratchEnd.fdf.inc > + > > ################################################################################ > > [Rule.Common.SEC] > diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf > index 08daf48..eec0559 100644 > --- a/OvmfPkg/OvmfPkgX64.fdf > +++ b/OvmfPkg/OvmfPkgX64.fdf > @@ -78,7 +78,7 @@ [FD.OVMF_CODE] > > ################################################################################ > > [FD.MEMFD] > -BaseAddress = 0x800000 > +BaseAddress = $(MEMFD_BASE_ADDRESS) > Size = 0x900000 > ErasePolarity = 1 > BlockSize = 0x10000 > @@ -377,6 +377,8 @@ [FV.FVMAIN_COMPACT] > } > } > > +!include DecomprScratchEnd.fdf.inc > + > > ################################################################################ > > [Rule.Common.SEC] > -- > 1.8.3.1 > > > _______________________________________________ > edk2-devel mailing list > [email protected] > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

