/** @file
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOLEAN
IsRuntimeImage (
IN VOID *Pe32Data
)
{
EFI_IMAGE_DOS_HEADER *DosHdr;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
UINT16 Magic;
UINT16 Subsystem;
ASSERT (Pe32Data != NULL);
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
//
// DOS image header is present, so read the PE header after the DOS image header.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
} else {
//
// DOS image header is not present, so PE header is at the image base.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
}
if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
//
// NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
// It is due to backward-compatibility, for some system might
// generate PE32+ image with PE32 Magic.
//
switch (Hdr.Pe32->FileHeader.Machine) {
case IMAGE_FILE_MACHINE_I386:
//
// Assume PE32 image with IA32 Machine field.
//
Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
break;
case IMAGE_FILE_MACHINE_X64:
case IMAGE_FILE_MACHINE_IA64:
//
// Assume PE32+ image with x64 or IA64 Machine field
//
Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
break;
default:
//
// For unknow Machine field, use Magic in optional Header
//
Magic = Hdr.Pe32->OptionalHeader.Magic;
}
Subsystem = 0;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
Subsystem = Hdr.Pe32->OptionalHeader.Subsystem;
} else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
Subsystem = Hdr.Pe32Plus->OptionalHeader.Subsystem;
} else {
ASSERT (FALSE);
}
if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
return TRUE;
}
}
return FALSE;
}
VOID
DumpLoadedImage (
IN UINTN Index,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
)
{
CHAR16 *Str;
CHAR8 *PdbPointer;
DEBUG ((DEBUG_INFO, "[0x%04x]:", Index));
if (IsRuntimeImage (LoadedImage->ImageBase)) {
DEBUG ((DEBUG_INFO, " (RT)"));
} else {
DEBUG ((DEBUG_INFO, " "));
}
DEBUG ((DEBUG_INFO, " 0x%016lx-0x%016lx", (UINT64)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize));
if (LoadedImageDevicePath != NULL) {
Str = ConvertDevicePathToText(LoadedImageDevicePath, TRUE, TRUE);
DEBUG ((DEBUG_INFO, " LoadedImageDevicePath=%s", Str));
if (Str != NULL) {
FreePool (Str);
}
} else {
if (LoadedImage->FilePath != NULL) {
Str = ConvertDevicePathToText(LoadedImage->FilePath, TRUE, TRUE);
DEBUG ((DEBUG_INFO, " FilePath=%s", Str));
if (Str != NULL) {
FreePool (Str);
}
}
if (DevicePath != NULL) {
Str = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
DEBUG ((DEBUG_INFO, " DevicePath=%s", Str));
if (Str != NULL) {
FreePool (Str);
}
}
}
PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_INFO, " (pdb - %a)", PdbPointer));
}
DEBUG ((DEBUG_INFO, "\n"));
}
EFI_STATUS
TestPointCheckNon3rdPartyImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
)
{
if (LoadedImageDevicePath != NULL) {
// LoadedImageDevicePath should be Fv()/FvFile()
if (DevicePathType (LoadedImageDevicePath) == MEDIA_DEVICE_PATH &&
DevicePathSubType (LoadedImageDevicePath) == MEDIA_PIWG_FW_VOL_DP) {
return EFI_SUCCESS;
}
} else {
if (LoadedImage->FilePath != NULL) {
// LoadedImage->FilePath should be FvFile()
if (DevicePathType (LoadedImage->FilePath) == MEDIA_DEVICE_PATH &&
DevicePathSubType (LoadedImage->FilePath) == MEDIA_PIWG_FW_FILE_DP) {
return EFI_SUCCESS;
}
}
if (DevicePath != NULL) {
// DevicePath should be Fv()
if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&
DevicePathSubType (DevicePath) == MEDIA_PIWG_FW_VOL_DP) {
return EFI_SUCCESS;
}
}
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
TestPointCheckLoadedImage (
VOID
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
UINTN Index;
EFI_HANDLE *HandleBuf;
UINTN HandleCount;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
EFI_STATUS ReturnStatus;
ReturnStatus = EFI_SUCCESS;
DEBUG ((DEBUG_INFO, "==== TestPointCheckLoadedImage - Enter\n"));
HandleBuf = NULL;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiLoadedImageProtocolGuid,
NULL,
&HandleCount,
&HandleBuf
);
if (EFI_ERROR (Status)) {
goto Done ;
}
DEBUG ((DEBUG_INFO, "LoadedImage (%d):\n", HandleCount));
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuf[Index],
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
);
if (EFI_ERROR(Status)) {
continue;
}
Status = gBS->HandleProtocol (LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
if (EFI_ERROR(Status)) {
DevicePath = NULL;
}
Status = gBS->HandleProtocol (HandleBuf[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&LoadedImageDevicePath);
if (EFI_ERROR(Status)) {
LoadedImageDevicePath = NULL;
}
DumpLoadedImage (Index, LoadedImage, DevicePath, LoadedImageDevicePath);
Status = TestPointCheckNon3rdPartyImage (LoadedImage, DevicePath, LoadedImageDevicePath);
if (EFI_ERROR(Status)) {
ReturnStatus = Status;
DEBUG ((DEBUG_ERROR, "3rd Party Image found - Index (%d)\n", Index));
TestPointLibAppendErrorString (
PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV,
NULL,
TEST_POINT_BYTE3_END_OF_DXE_NO_THIRD_PARTY_PCI_OPTION_ROM_ERROR_CODE \
TEST_POINT_END_OF_DXE \
TEST_POINT_BYTE3_END_OF_DXE_NO_THIRD_PARTY_PCI_OPTION_ROM_ERROR_STRING
);
}
}
Done:
if (HandleBuf != NULL) {
FreePool (HandleBuf);
}
DEBUG ((DEBUG_INFO, "==== TestPointCheckLoadedImage - Exit\n"));
return ReturnStatus;
}