mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/DxeCore: Ensure FfsFileHeader 8 bytes aligned
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=864 REF: CVE-2018-3630 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> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
This commit is contained in:
parent
467e1ffa76
commit
9aef515648
|
@ -3,7 +3,7 @@
|
||||||
Layers on top of Firmware Block protocol to produce a file abstraction
|
Layers on top of Firmware Block protocol to produce a file abstraction
|
||||||
of FV based files.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -329,8 +329,6 @@ FvCheck (
|
||||||
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
FFS_FILE_LIST_ENTRY *FfsFileEntry;
|
||||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||||
UINT8 *CacheLocation;
|
UINT8 *CacheLocation;
|
||||||
UINTN LbaOffset;
|
|
||||||
UINTN HeaderSize;
|
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_LBA LbaIndex;
|
EFI_LBA LbaIndex;
|
||||||
UINTN Size;
|
UINTN Size;
|
||||||
|
@ -353,11 +351,7 @@ FvCheck (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
Size = (UINTN) FwVolHeader->FvLength;
|
||||||
// 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);
|
|
||||||
if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
|
if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
|
||||||
FvDevice->IsMemoryMapped = TRUE;
|
FvDevice->IsMemoryMapped = TRUE;
|
||||||
|
|
||||||
|
@ -369,7 +363,7 @@ FvCheck (
|
||||||
//
|
//
|
||||||
// Don't cache memory mapped FV really.
|
// Don't cache memory mapped FV really.
|
||||||
//
|
//
|
||||||
FvDevice->CachedFv = (UINT8 *) (UINTN) (PhysicalAddress + FwVolHeader->HeaderLength);
|
FvDevice->CachedFv = (UINT8 *) (UINTN) PhysicalAddress;
|
||||||
} else {
|
} else {
|
||||||
FvDevice->IsMemoryMapped = FALSE;
|
FvDevice->IsMemoryMapped = FALSE;
|
||||||
FvDevice->CachedFv = AllocatePool (Size);
|
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;
|
FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
|
||||||
|
|
||||||
if (!FvDevice->IsMemoryMapped) {
|
if (!FvDevice->IsMemoryMapped) {
|
||||||
//
|
//
|
||||||
// Copy FV minus header into memory using the block map we have all ready
|
// Copy FV into memory using the block map.
|
||||||
// read into memory.
|
|
||||||
//
|
//
|
||||||
BlockMap = FwVolHeader->BlockMap;
|
BlockMap = FwVolHeader->BlockMap;
|
||||||
CacheLocation = FvDevice->CachedFv;
|
CacheLocation = FvDevice->CachedFv;
|
||||||
LbaIndex = 0;
|
LbaIndex = 0;
|
||||||
LbaOffset = 0;
|
|
||||||
HeaderSize = FwVolHeader->HeaderLength;
|
|
||||||
while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) {
|
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
|
// read the FV data
|
||||||
//
|
//
|
||||||
for (; Index < BlockMap->NumBlocks; Index ++) {
|
Size = BlockMap->Length;
|
||||||
Status = Fvb->Read (Fvb,
|
for (Index = 0; Index < BlockMap->NumBlocks; Index++) {
|
||||||
|
Status = Fvb->Read (
|
||||||
|
Fvb,
|
||||||
LbaIndex,
|
LbaIndex,
|
||||||
LbaOffset,
|
0,
|
||||||
&Size,
|
&Size,
|
||||||
CacheLocation
|
CacheLocation
|
||||||
);
|
);
|
||||||
|
@ -438,13 +407,7 @@ FvCheck (
|
||||||
}
|
}
|
||||||
|
|
||||||
LbaIndex++;
|
LbaIndex++;
|
||||||
CacheLocation += Size;
|
CacheLocation += BlockMap->Length;
|
||||||
|
|
||||||
//
|
|
||||||
// After we skip Fv Header always read from start of block
|
|
||||||
//
|
|
||||||
LbaOffset = 0;
|
|
||||||
Size = BlockMap->Length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockMap++;
|
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.
|
// 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 *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);
|
||||||
FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8);
|
|
||||||
} else {
|
} 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;
|
TopFvAddress = FvDevice->EndOfCachedFv;
|
||||||
while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) {
|
while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue