public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Jian J Wang <jian.j.wang@intel.com>
To: edk2-devel@lists.01.org
Cc: Star Zeng <star.zeng@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Liming Gao <liming.gao@intel.com>, Hao Wu <hao.a.wu@intel.com>
Subject: [PATCH 2/3] MdeModulePkg/DxeCore: Ensure FfsFileHeader 8 bytes aligned [CVE-2018-3630]
Date: Wed, 27 Feb 2019 00:04:24 +0800	[thread overview]
Message-ID: <20190226160425.4816-3-jian.j.wang@intel.com> (raw)
In-Reply-To: <20190226160425.4816-1-jian.j.wang@intel.com>

From: Star Zeng <star.zeng@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=864

To follow PI spec, ensure FfsFileHeader 8 bytes aligned.

For the integrity of FV(especially non-MemoryMapped FV) layout,
let CachedFv point to FV beginning, but not (FV + FV header).

And current code only handles (FwVolHeader->ExtHeaderOffset != 0) path,
update code to also handle (FwVolHeader->ExtHeaderOffset == 0) path.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao Wu <hao.a.wu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
---
 MdeModulePkg/Core/Dxe/FwVol/FwVol.c | 65 +++++++----------------------
 1 file changed, 14 insertions(+), 51 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
index 93ddcc3591..28fce46a95 100644
--- a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
+++ b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
@@ -3,7 +3,7 @@
   Layers on top of Firmware Block protocol to produce a file abstraction
   of FV based files.
 
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 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
@@ -329,8 +329,6 @@ FvCheck (
   FFS_FILE_LIST_ENTRY                   *FfsFileEntry;
   EFI_FFS_FILE_HEADER                   *FfsHeader;
   UINT8                                 *CacheLocation;
-  UINTN                                 LbaOffset;
-  UINTN                                 HeaderSize;
   UINTN                                 Index;
   EFI_LBA                               LbaIndex;
   UINTN                                 Size;
@@ -353,11 +351,7 @@ FvCheck (
     return Status;
   }
 
-  //
-  // Size is the size of the FV minus the head. We have already allocated
-  // the header to check to make sure the volume is valid
-  //
-  Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
+  Size = (UINTN) FwVolHeader->FvLength;
   if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
     FvDevice->IsMemoryMapped = TRUE;
 
@@ -369,7 +363,7 @@ FvCheck (
     //
     // Don't cache memory mapped FV really.
     //
-    FvDevice->CachedFv = (UINT8 *) (UINTN) (PhysicalAddress + FwVolHeader->HeaderLength);
+    FvDevice->CachedFv = (UINT8 *) (UINTN) PhysicalAddress;
   } else {
     FvDevice->IsMemoryMapped = FALSE;
     FvDevice->CachedFv = AllocatePool (Size);
@@ -380,52 +374,27 @@ FvCheck (
   }
 
   //
-  // Remember a pointer to the end fo the CachedFv
+  // Remember a pointer to the end of the CachedFv
   //
   FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
 
   if (!FvDevice->IsMemoryMapped) {
     //
-    // Copy FV minus header into memory using the block map we have all ready
-    // read into memory.
+    // Copy FV into memory using the block map.
     //
     BlockMap = FwVolHeader->BlockMap;
     CacheLocation = FvDevice->CachedFv;
     LbaIndex = 0;
-    LbaOffset = 0;
-    HeaderSize = FwVolHeader->HeaderLength;
     while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
-      Index = 0;
-      Size  = BlockMap->Length;
-      if (HeaderSize > 0) {
-        //
-        // Skip header size
-        //
-        for (; Index < BlockMap->NumBlocks && HeaderSize >= BlockMap->Length; Index ++) {
-          HeaderSize -= BlockMap->Length;
-          LbaIndex ++;
-        }
-
-        //
-        // Check whether FvHeader is crossing the multi block range.
-        //
-        if (Index >= BlockMap->NumBlocks) {
-          BlockMap++;
-          continue;
-        } else if (HeaderSize > 0) {
-          LbaOffset = HeaderSize;
-          Size = BlockMap->Length - HeaderSize;
-          HeaderSize = 0;
-        }
-      }
-
       //
       // read the FV data
       //
-      for (; Index < BlockMap->NumBlocks; Index ++) {
-        Status = Fvb->Read (Fvb,
+      Size = BlockMap->Length;
+      for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
+        Status = Fvb->Read (
+                        Fvb,
                         LbaIndex,
-                        LbaOffset,
+                        0,
                         &Size,
                         CacheLocation
                         );
@@ -438,13 +407,7 @@ FvCheck (
         }
 
         LbaIndex++;
-        CacheLocation += Size;
-
-        //
-        // After we skip Fv Header always read from start of block
-        //
-        LbaOffset = 0;
-        Size  = BlockMap->Length;
+        CacheLocation += BlockMap->Length;
       }
 
       BlockMap++;
@@ -475,12 +438,12 @@ FvCheck (
     //
     // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.
     //
-    FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (FvDevice->CachedFv + (FwVolHeader->ExtHeaderOffset - FwVolHeader->HeaderLength));
+    FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (FvDevice->CachedFv + FwVolHeader->ExtHeaderOffset);
     FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);
-    FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8);
   } else {
-    FfsHeader = (EFI_FFS_FILE_HEADER *) (FvDevice->CachedFv);
+    FfsHeader = (EFI_FFS_FILE_HEADER *) (FvDevice->CachedFv + FwVolHeader->HeaderLength);
   }
+  FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8);
   TopFvAddress = FvDevice->EndOfCachedFv;
   while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) {
 
-- 
2.17.1.windows.2



  parent reply	other threads:[~2019-02-26 16:04 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-26 16:04 [PATCH 0/3] Ensure FfsFileHeader 8 bytes aligned [CVE-2018-3630] Jian J Wang
2019-02-26 16:04 ` [PATCH 1/3] MdeModulePkg/PeiCore: " Jian J Wang
2019-02-27  6:56   ` Wang, Jian J
2019-02-26 16:04 ` Jian J Wang [this message]
2019-02-27  6:55   ` [PATCH 2/3] MdeModulePkg/DxeCore: " Wang, Jian J
2019-02-26 16:04 ` [PATCH 3/3] IntelFrameworkModulePkg/FwVolDxe: " Jian J Wang
2019-02-27  6:55   ` Wang, Jian J

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190226160425.4816-3-jian.j.wang@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox