On 09/06/15 21:56, Jordan Justen wrote:
> 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.

Okay, will update.

> 
> 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.

I'd like to stick with "End only" -- the calculation works it way up
from PcdOvmfDxeMemFvBase, so we already have a base address.

> 
>> 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.

I'll update it to DECOMP_SCRATCH. I'd like to keep SCRATCH as a
connection to "OvmfPkg/Sec/SecMain.c".

> Reviewed-by: Jordan Justen <[email protected]>

Thank you!
Laszlo

> 
>> +
>> +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

Reply via email to