On 2015-11-03 13:00:38, Laszlo Ersek wrote:
> BaseExtractGuidedSectionLib uses a table at the static physical address
> PcdGuidedExtractHandlerTableAddress, and modules that are linked against
> BaseExtractGuidedSectionLib are expected to work together on that table.
> Namely, some modules can register handlers for GUIDed sections, some other
> modules can decode such sections with the pre-registered handlers. The
> table carries persistent information between these modules.
> 
> BaseExtractGuidedSectionLib checks a table signature whenever it is used
> (by whichever module that is linked against it), and at the first use
> (identified by a signature mismatch) it initializes the table.
> 
> One of the module types that BaseExtractGuidedSectionLib can be used with
> is SEC, if the SEC module in question runs with the platform's RAM already
> available.
> 
> In such cases the question emerges whether the initial contents of the RAM
> (ie. contents that predate the very first signature check) can be trusted.
> Normally RAM starts out with all zeroes (leading to a signature mismatch
> on the first check); however a malicious runtime OS can populate the area
> with some payload, then force a warm platform reset or an S3
> suspend-and-resume. In such cases the signature check in the SEC module
> might not fire, and ExtractGuidedSectionDecode() might run code injected
> by the runtime OS, as part of SEC (ie. with high privileges).
> 
> -D SMM_REQUIRE signals that the firmware should be secure against
> tampering from a malicious OS, therefore we clear the handler table in
> SEC, in such builds.
> 
> See also git commit ad43bc6b2e (SVN rev 15433) -- this patch secures the
> (d) and (e) code paths examined in that commit. Furthermore, a
> non-malicious runtime OS will observe no change in behavior; see case (c)
> in said commit.
> 
> Cc: Michael Kinney <michael.d.kin...@intel.com>
> Cc: Jordan Justen <jordan.l.jus...@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Laszlo Ersek <ler...@redhat.com>
> [michael.d.kin...@intel.com: prevent VS20xx loop intrinsic with volatile]
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Michael Kinney <michael.d.kin...@intel.com>
> ---
> 
> Notes:
>     v3:
>     - volatile-qualify the Table pointer to prevent VS20xx from turning the
>       zeroing loop into a compiler intrinsic [Mike]
>     
>     v2:
>     - This implements option #2 from Jordan's feedback at
>       <http://thread.gmane.org/gmane.comp.bios.edk2.devel/329/focus=1995>.
>       Liming was okay with that option:
>       <http://thread.gmane.org/gmane.comp.bios.edk2.devel/329/focus=2009>.
>     
>     - This patch replaces the following patches from the v1 series:
>     
>       [PATCH 03/58] MdePkg: BaseExtractGuidedSectionLib: allow forced reinit
>                     of handler table
>       <http://thread.gmane.org/gmane.comp.bios.edk2.devel/329/focus=328>
>     
>       [PATCH 04/58] OvmfPkg: set PcdBaseExtractGuidedSectionLibForceInit for
>                     SEC on SMM_REQUIRE
>       <http://thread.gmane.org/gmane.comp.bios.edk2.devel/329/focus=330>
> 
>  OvmfPkg/Sec/SecMain.inf |  5 ++++
>  OvmfPkg/Sec/SecMain.c   | 28 ++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
> index 2f78f3c..8f4d86c 100644
> --- a/OvmfPkg/Sec/SecMain.inf
> +++ b/OvmfPkg/Sec/SecMain.inf
> @@ -68,3 +68,8 @@ [Pcd]
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
>    gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> +  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +
> +[FeaturePcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
> index 4f87059..1556032 100644
> --- a/OvmfPkg/Sec/SecMain.c
> +++ b/OvmfPkg/Sec/SecMain.c
> @@ -699,8 +699,36 @@ SecCoreStartupWithStack (
>    IA32_DESCRIPTOR             IdtDescriptor;
>    UINT32                      Index;
>  
> +  //
> +  // This code may be running on the S3 resume boot path, where RAM has been
> +  // populated by the runtime guest OS. Guarantee the reinitialization of the
> +  // BaseExtractGuidedSectionLib handler table, before the constructor of
> +  // LzmaCustomDecompressLib calls into BaseExtractGuidedSectionLib, due to 
> our
> +  // explicit ProcessLibraryConstructorList() call below.
> +  //
> +  // We must not rely on any libraries before calling
> +  // ProcessLibraryConstructorList(), thus we clear the table with an
> +  // open-coded loop. (The FeaturePcdGet() and FixedPcdGetXX() macro
> +  // invocations are preprocessed to constants.)
> +  //

I think this comment could be more terse. What about:

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

> +  if (FeaturePcdGet (PcdSmmSmramRequire)) {

I agree with Mike. Let's just always zero the table.

> +    volatile UINT8 *Table;
> +
> +    Table = (UINT8*)(UINTN)FixedPcdGet64 
> (PcdGuidedExtractHandlerTableAddress);
> +    for (Index = 0;
> +         Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
> +         ++Index) {
> +      Table[Index] = 0;
> +    }
> +  }
> +
>    ProcessLibraryConstructorList (NULL, NULL);
>  
> +  if (FeaturePcdGet (PcdSmmSmramRequire)) {
> +    DEBUG ((EFI_D_VERBOSE, "%a: cleared BaseExtractGuidedSectionLib table\n",
> +      __FUNCTION__));
> +  }
> +

And drop this.

Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com>

>    DEBUG ((EFI_D_INFO,
>      "SecCoreStartupWithStack(0x%x, 0x%x)\n",
>      (UINT32)(UINTN)BootFv,
> -- 
> 1.8.3.1
> 
> 
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to