Add more checks to BlLoadModule() and make it more verbose
This commit is contained in:
parent
ea06286a8b
commit
aa03fc9cb2
@ -169,7 +169,10 @@ EFI_STATUS
|
|||||||
BlLoadModules(IN PWCHAR ModulesList)
|
BlLoadModules(IN PWCHAR ModulesList)
|
||||||
{
|
{
|
||||||
PWCHAR LastModule, Module;
|
PWCHAR LastModule, Module;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS ReturnStatus, Status;
|
||||||
|
|
||||||
|
/* Set default return value */
|
||||||
|
ReturnStatus = STATUS_EFI_SUCCESS;
|
||||||
|
|
||||||
if(ModulesList != NULL)
|
if(ModulesList != NULL)
|
||||||
{
|
{
|
||||||
@ -182,9 +185,9 @@ BlLoadModules(IN PWCHAR ModulesList)
|
|||||||
Status = BlLoadModule(Module);
|
Status = BlLoadModule(Module);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to load module, print error message and return status code */
|
/* Failed to load module, print error message and set new return value */
|
||||||
BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status);
|
BlDebugPrint(L"Failed to load module '%S', status = 0x%lx\n", Module, Status);
|
||||||
// return Status;
|
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take next module from the list */
|
/* Take next module from the list */
|
||||||
@ -193,14 +196,16 @@ BlLoadModules(IN PWCHAR ModulesList)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BlLoadModule(IN PWCHAR ModuleName)
|
BlLoadModule(IN PWCHAR ModuleName)
|
||||||
{
|
{
|
||||||
|
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
||||||
|
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||||
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||||
EFI_HANDLE DiskHandle, ModuleHandle;
|
EFI_HANDLE DiskHandle, ModuleHandle;
|
||||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||||
@ -224,7 +229,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
||||||
{
|
{
|
||||||
/* Module already loaded */
|
/* Module already loaded */
|
||||||
BlDebugPrint(L"Module '%S' already loaded\n", ModuleName);
|
BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName);
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +275,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate memory for new option */
|
/* Allocate memory for module information block */
|
||||||
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -278,6 +283,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Zero module information block */
|
||||||
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
||||||
|
|
||||||
/* Setup PE/COFF EFI image headers */
|
/* Setup PE/COFF EFI image headers */
|
||||||
@ -286,7 +292,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
||||||
PeHeader->FileHeader.SizeOfOptionalHeader);
|
PeHeader->FileHeader.SizeOfOptionalHeader);
|
||||||
|
|
||||||
/* Look for .moddeps section */
|
/* Look for .moddeps and .modinfo sections */
|
||||||
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||||
{
|
{
|
||||||
/* Check section name */
|
/* Check section name */
|
||||||
@ -305,7 +311,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to load module, print error message and return status code */
|
/* Failed to load module, print error message and return status code */
|
||||||
BlDebugPrint(L"Failed to load dependency module '%S', status = 0x%lx\n", DepsData, Status);
|
BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status);
|
||||||
return STATUS_EFI_UNSUPPORTED;
|
return STATUS_EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +330,7 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store module name */
|
/* Finally, store module name */
|
||||||
ModuleInfo->ModuleName = ModuleName;
|
ModuleInfo->ModuleName = ModuleName;
|
||||||
|
|
||||||
/* Setup module device path */
|
/* Setup module device path */
|
||||||
@ -345,15 +351,51 @@ BlLoadModule(IN PWCHAR ModuleName)
|
|||||||
ModuleData, ModuleSize, &ModuleHandle);
|
ModuleData, ModuleSize, &ModuleHandle);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to load module image */
|
/* Check if caused by secure boot */
|
||||||
|
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
|
||||||
|
{
|
||||||
|
/* SecureBoot signature validation failed */
|
||||||
|
BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Failed to load module */
|
||||||
|
BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return error status code */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Access module interface for further module type check */
|
||||||
|
Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,
|
||||||
|
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open LoadedImage protocol */
|
||||||
|
BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */
|
||||||
|
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
|
||||||
|
{
|
||||||
|
/* Different type set, probably 'runtime driver', refuse to load it */
|
||||||
|
BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n");
|
||||||
|
|
||||||
|
/* Close protocol and skip module */
|
||||||
|
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close loaded image protocol */
|
||||||
|
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||||
|
|
||||||
/* Start EFI image */
|
/* Start EFI image */
|
||||||
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Failed to start module image */
|
/* Failed to start module image */
|
||||||
|
BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user