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

Therefore we clear the handler table in SEC.

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>
Reviewed-by: Michael Kinney <michael.d.kin...@intel.com>
Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com>
---

Notes:
    v5:
    - condense comment before clearing BaseExtractGuidedSectionLib handler
      table [Jordan]
    - clear table regardless of PcdSmmSmramRequire; update commit message
      accordingly [Mike, Jordan]
    - drop EFI_D_VERBOSE message about clearing the table (which is now
      unconditional) [Jordan]
    - delay addition of PcdSmmSmramRequire to SecMain.inf until "OvmfPkg:
      decompress FVs on S3 resume if SMM_REQUIRE is set"; that patch is the
      one that requires the PCD first now [Laszlo]
    - pick up Jordan's R-b
    
    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 |  2 ++
 OvmfPkg/Sec/SecMain.c   | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index 2f78f3c..415731c 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -68,3 +68,5 @@ [Pcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 4f87059..0cf127a 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -698,6 +698,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);
 
-- 
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