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); }