X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FSec%2FSecMain.c;h=f7fec3d8c03b93d73042e480e4400be41f22ce32;hp=4f87059e1755f463b805be924cca732c5180bd8b;hb=89796c69d9fdaa9bd13d37b6b1687df5e0104ed5;hpb=f3e34b9d8ceca130a14905df9a6a3eaad17f3674
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 4f87059e17..f7fec3d8c0 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -2,6 +2,7 @@
Main SEC phase code. Transitions to PEI.
Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -332,11 +333,13 @@ DecompressMemFvs (
UINT32 AuthenticationStatus;
VOID *OutputBuffer;
VOID *ScratchBuffer;
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FvSection;
+ EFI_COMMON_SECTION_HEADER *FvSection;
EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;
EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;
+ UINT32 FvHeaderSize;
+ UINT32 FvSectionSize;
- FvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL;
+ FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
Status = FindFfsFileAndSection (
*Fv,
@@ -362,6 +365,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 "
+ "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,
+ OutputBufferSize, ScratchBuffer, ScratchBufferSize,
+ PcdGet32 (PcdOvmfDecompressionScratchEnd)));
+ ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
+ PcdGet32 (PcdOvmfDecompressionScratchEnd));
+
Status = ExtractGuidedSectionDecode (
Section,
&OutputBuffer,
@@ -378,7 +389,7 @@ DecompressMemFvs (
OutputBufferSize,
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
0,
- (EFI_COMMON_SECTION_HEADER**) &FvSection
+ &FvSection
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
@@ -403,7 +414,7 @@ DecompressMemFvs (
OutputBufferSize,
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
1,
- (EFI_COMMON_SECTION_HEADER**) &FvSection
+ &FvSection
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
@@ -411,11 +422,19 @@ DecompressMemFvs (
}
ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
- ASSERT (SECTION_SIZE (FvSection) ==
- (PcdGet32 (PcdOvmfDxeMemFvSize) + sizeof (*FvSection)));
+
+ if (IS_SECTION2 (FvSection)) {
+ FvSectionSize = SECTION2_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ FvSectionSize = SECTION_SIZE (FvSection);
+ FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+
+ ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize));
DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase);
- CopyMem (DxeMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfDxeMemFvSize));
+ CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize));
if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
@@ -531,13 +550,25 @@ FindPeiCoreImageBase (
OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
)
{
+ BOOLEAN S3Resume;
+
*PeiCoreImageBase = 0;
- if (IsS3Resume ()) {
+ S3Resume = IsS3Resume ();
+ if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+ //
+ // A malicious runtime OS may have injected something into our previously
+ // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+ //
DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
GetS3ResumePeiFv (BootFv);
} else {
- DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n"));
+ //
+ // We're either not resuming, or resuming "securely" -- we'll decompress
+ // both PEI FV and DXE FV from pristine flash.
+ //
+ DEBUG ((EFI_D_VERBOSE, "SEC: %a\n",
+ S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
FindMainFv (BootFv);
DecompressMemFvs (BootFv);
@@ -638,7 +669,7 @@ FindImageBase (
/*
Find and return Pei Core entry point.
- It also find SEC and PEI Core file debug inforamtion. It will report them if
+ It also find SEC and PEI Core file debug information. It will report them if
remote debug is enabled.
**/
@@ -698,6 +729,19 @@ SecCoreStartupWithStack (
SEC_IDT_TABLE IdtTableInStack;
IA32_DESCRIPTOR IdtDescriptor;
UINT32 Index;
+ volatile UINT8 *Table;
+
+ //
+ // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+ // the BaseExtractGuidedSectionLib. Since this is before library contructors
+ // are called, we must use a loop rather than SetMem.
+ //
+ Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+ for (Index = 0;
+ Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+ ++Index) {
+ Table[Index] = 0;
+ }
ProcessLibraryConstructorList (NULL, NULL);
@@ -887,9 +931,11 @@ TemporaryRamMigration (
if (SetJump (&JumpBuffer) == 0) {
#if defined (MDE_CPU_IA32)
JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+ JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;
#endif
#if defined (MDE_CPU_X64)
JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+ JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;
#endif
LongJump (&JumpBuffer, (UINTN)-1);
}