diff options
author | Oliver Smith-Denny <osde@microsoft.com> | 2025-02-13 12:52:00 -0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-02-14 06:58:07 +0000 |
commit | bc664d1830c9446cb1d33b10a41e6b3d207997f1 (patch) | |
tree | 8c0c5a332052487aaef27ed02244a5e52e83d250 /FatPkg/FatPei/FatLiteAccess.c | |
parent | 523dbb6d597b63181bba85a337d1f53e511f4822 (diff) | |
download | edk2-bc664d1830c9446cb1d33b10a41e6b3d207997f1.tar.gz |
Revert "FatPkg: Validate Reserved FAT Entries on Volume Open"
This reverts commit 58766a472932c485d41163b1746fb1d9e7984f07.
In edk2 commit 58766a4, validation of the two reserved FAT entries
was added.
However, it also checked the return of FatGetFatEntry to MAX_UINT32,
which is what FatGetFatEntry returns when it encounters an error,
e.g. not being able to read the disk. However, MAX_UINT32 is also a
valid value for the reserved FAT entries and under some conditions
these will be returned in the success case.
A FAT volume formatted with these valid values of the reserved FAT
entries will fail to boot an OS because the opening of the volume
will fail.
However, the reason FatGetFatEntry returns MAX_UINT32 is that most
other uses of the function are comparing it against the END_OF_CHAIN
mark, which MAX_UINT32 will trip and those functions will fail out.
Because this is a critical bug that can prevent OS booting and the
bug the original commit was solving was accounting for a bad FAT
filesystem formatting tool, this commit is reverted for now.
Future work will clean up FatGetFatEntry so that it returns an
EFI_STATUS, but that involves more work and this bug needs to be
resolved in the meantime.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Diffstat (limited to 'FatPkg/FatPei/FatLiteAccess.c')
-rw-r--r-- | FatPkg/FatPei/FatLiteAccess.c | 69 |
1 files changed, 0 insertions, 69 deletions
diff --git a/FatPkg/FatPei/FatLiteAccess.c b/FatPkg/FatPei/FatLiteAccess.c index 46a7563ab6..10df4516b2 100644 --- a/FatPkg/FatPei/FatLiteAccess.c +++ b/FatPkg/FatPei/FatLiteAccess.c @@ -43,7 +43,6 @@ FatGetBpbInfo ( UINT64 FatLba;
UINT64 RootLba;
UINT64 FirstClusterLba;
- UINT32 ReservedFatEntries[2];
//
// Read in the BPB
@@ -168,74 +167,6 @@ FatGetBpbInfo ( Volume->FatType = Volume->MaxCluster < 4085 ? Fat12 : Fat16;
}
- //
- // Read reserved FAT entries which are the first two entries from FatPos
- //
- Status = FatReadDisk (
- PrivateData,
- Volume->BlockDeviceNo,
- Volume->FatPos,
- (Volume->FatType == Fat32) ? sizeof (UINT32) * 2 : sizeof (UINT16) * 2,
- ReservedFatEntries
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Reserved FAT entry 0 should contain the BPB_MEDIA byte value in the low 8 bits with all other bits set to 1
- // Reserved FAT entry 1 should contain the end of chain mark. On FAT16 and FAT32, the high 2 bits may be used as
- // dirty and hardware error bits, so are ignored in this check
- //
- switch (Volume->FatType) {
- case Fat12:
- // we read two entries and in FAT12, each entry is 12 bits, so we need to shift the first entry by 20 bits to
- // only read it and not the second entry and beyond
- if (((ReservedFatEntries[0] >> 20) & FAT_CLUSTER_MASK_FAT12) != ((UINTN)Bpb.Media | 0xF00)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- // the second entry starts 12 bits in and is 12 bits in length, so we shift by 8 bits to remove the start of the
- // third entry and then mask to only read the second entry
- if (!FAT_CLUSTER_END_OF_CHAIN (ReservedFatEntries[0] >> 8)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- break;
-
- case Fat16:
- // in FAT16, each entry is 16 bits, so the first entry is the upper 16 bits of ReservedFatEntries[0]
- if (((ReservedFatEntries[0] >> 16) & FAT_CLUSTER_MASK_FAT16) != ((UINTN)Bpb.Media | 0xFF00)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- // the second entry is simply the lower 16 bits of ReservedFatEntries[0], however, we must ignore the upper two
- // bits. For the purposes of checking if the EOC mark exists, we treat those two bits as 1
- if (!FAT_CLUSTER_END_OF_CHAIN ((ReservedFatEntries[0] & 0x3FFF) | 0xC000)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- break;
-
- case Fat32:
- // the upper 4 bits of a FAT32 entry are reserved, so are unchecked here
- // FAT32 has 32 bit entries, so the first entry is ReservedFatEntries[0]
- if ((ReservedFatEntries[0] & FAT_CLUSTER_MASK_FAT32) != ((UINTN)Bpb.Media | 0x0FFFFF00)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- // the second entry is simply ReservedFatEntries[1], but we must ignore the upper two bits. For the purposes of
- // checking if the EOC mark exists, we treat those two bits as 1
- if (!FAT_CLUSTER_END_OF_CHAIN ((ReservedFatEntries[1] & 0x3FFFFFFF) | 0xC0000000)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- break;
-
- default:
- return EFI_VOLUME_CORRUPTED;
- }
-
return EFI_SUCCESS;
}
|