Skip to content

Commit

Permalink
Improve detection of EFI program validity
Browse files Browse the repository at this point in the history
  • Loading branch information
srs5694 committed Mar 11, 2023
1 parent ed4b31a commit 9b125c7
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 14 deletions.
5 changes: 3 additions & 2 deletions EfiLib/BdsConnect.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ BdsLibConnectAllDriversToAllControllers (
VOID
)
{
EFI_STATUS Status;
EFI_STATUS Status = EFI_UNSUPPORTED;

do {
//
Expand All @@ -262,7 +262,8 @@ BdsLibConnectAllDriversToAllControllers (
// If anything is Dispatched Status == EFI_SUCCESS and we will try
// the connect again.
//
Status = gDS->Dispatch ();
if (gDS)
Status = gDS->Dispatch ();

} while (!EFI_ERROR (Status));

Expand Down
6 changes: 5 additions & 1 deletion EfiLib/BdsTianoCore.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ BdsLibConnectDevicePath (
// Status == EFI_SUCCESS means a driver was dispatched
// Status == EFI_NOT_FOUND means no new drivers were dispatched
//
Status = gDS->Dispatch ();
if (gDS) {
Status = gDS->Dispatch ();
} else {
Status = EFI_NOT_FOUND;
}
}
#endif

Expand Down
3 changes: 3 additions & 0 deletions NEWS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

- Fixed a memory leak in JPEG handling code.

- Fixed a bug that could cause some EFI programs (notably Pete Batard's
drivers on ARM64 systems) to be incorrectly marked as invalid.

0.14.0 (3/4/2023):
------------------

Expand Down
2 changes: 1 addition & 1 deletion include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
#ifndef __VERSION_H
#define __VERSION_H

#define REFIND_VERSION L"0.14.0.5"
#define REFIND_VERSION L"0.14.0.6"

#endif
40 changes: 31 additions & 9 deletions refind/launch_efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@

#define FAT_ARCH 0x0ef1fab9 /* ID for Apple "fat" binary */

// Amount of a file to read to search for the EFI identifying signatures....
// I've seen signatures as far in as 3680 (0xE60), so read a bit more than
// that....
#define EFI_HEADER_SIZE 3800

static VOID WarnSecureBootError(CHAR16 *Name, BOOLEAN Verbose) {
if (Name == NULL)
Name = L"the loader";
Expand Down Expand Up @@ -120,10 +125,16 @@ UINTN IsValidLoader(EFI_FILE_PROTOCOL *RootDir, CHAR16 *FileName) {
BOOLEAN IsValid = TRUE;
EFI_STATUS Status;
EFI_FILE_HANDLE FileHandle;
CHAR8 Header[512];
CHAR8 *Header;
CHAR16 *TypeDesc = L"a valid";
UINTN Size = sizeof(Header);
UINTN LoadedSize = EFI_HEADER_SIZE;
UINTN SignaturePos;

Header = AllocatePool(EFI_HEADER_SIZE);
if (!Header) {
LOG(1, LOG_LINE_NORMAL, L"Unable to allocate memory in IsValidLoader()!");
return LOADER_TYPE_INVALID;
}
if ((RootDir == NULL) || (FileName == NULL)) {
// Assume valid here, because Macs produce NULL RootDir (& maybe FileName)
// when launching from a Firewire drive. This should be handled better, but
Expand All @@ -135,18 +146,28 @@ UINTN IsValidLoader(EFI_FILE_PROTOCOL *RootDir, CHAR16 *FileName) {
if (EFI_ERROR(Status))
return LOADER_TYPE_INVALID;

Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &Size, Header);
Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &LoadedSize, Header);
refit_call1_wrapper(FileHandle->Close, FileHandle);

IsValid = !EFI_ERROR(Status) &&
Size == sizeof(Header) &&
if (EFI_ERROR(Status)) {
MyFreePool(Header);
LOG(1, LOG_LINE_NORMAL, L"Error reading %s to determine if it's a valid loader!", FileName);
return LOADER_TYPE_INVALID;
}
SignaturePos = *(UINT32 *)&Header[0x3c];
LOG(4, LOG_LINE_NORMAL, L"In IsValidLoader(), LoadedSize is %lu, SignaturePos is %lu", LoadedSize, SignaturePos);
// Search for the normal signatures for an EFI binary....
IsValid = (LoadedSize == EFI_HEADER_SIZE) &&
((Header[0] == 'M' && Header[1] == 'Z' &&
(Size = *(UINT32 *)&Header[0x3c]) < 0x180 &&
Header[Size] == 'P' && Header[Size+1] == 'E' &&
Header[Size+2] == 0 && Header[Size+3] == 0 &&
*(UINT16 *)&Header[Size+4] == EFI_STUB_ARCH) ||
(SignaturePos < (EFI_HEADER_SIZE - 8)) &&
Header[SignaturePos] == 'P' && Header[SignaturePos+1] == 'E' &&
Header[SignaturePos+2] == 0 && Header[SignaturePos+3] == 0 &&
*(UINT16 *)&Header[SignaturePos+4] == EFI_STUB_ARCH) ||
(*(UINT32 *)&Header == FAT_ARCH));
if (!IsValid) {
// Search for indications that this is a gzipped file. Note, however,
// that we don't dig deeper into gzipped files, so some invalid
// gzipped files could be called valid.
if ((Header[0] == (CHAR8) 0x1F && Header[1] == (CHAR8) 0x8B) && GlobalConfig.GzippedLoaders) {
LoaderType = LOADER_TYPE_GZIP;
TypeDesc = L"a gzipped";
Expand All @@ -156,6 +177,7 @@ UINTN IsValidLoader(EFI_FILE_PROTOCOL *RootDir, CHAR16 *FileName) {
}
}
LOG(1, LOG_LINE_NORMAL, L"'%s' is %s loader file", FileName, TypeDesc);
MyFreePool(Header);
#endif
return LoaderType;
} // UINTN IsValidLoader()
Expand Down
9 changes: 8 additions & 1 deletion refind/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,19 @@ VOID RescanAll(BOOLEAN DisplayMessage, BOOLEAN Reconnect) {

// Minimal initialization function
static VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) {
EFI_STATUS Status;

gST = SystemTable;
// gImageHandle = ImageHandle;
gBS = SystemTable->BootServices;
// gRS = SystemTable->RuntimeServices;
gRT = SystemTable->RuntimeServices; // Some BDS functions need gRT to be set
EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);
if (EFI_ERROR(Status)) {
LOG(1, LOG_LINE_NORMAL, L"WARNING: EfiGetSystemConfigurationTable() returned error status %lu!", Status);
LOG(1, LOG_LINE_NORMAL, L"Some functionality will be impaired!");
gDS = 0;
}
}

#endif
Expand Down

0 comments on commit 9b125c7

Please sign in to comment.