efi-boot-shim/lib/configtable.c
Matthew Garrett 17857eb8b5 Port MokManager to Linux Foundation loader UI code
This is the first stage of porting the MokManager UI to the UI code used
by the Linux Foundation UEFI loader.
2013-09-26 11:57:59 -04:00

145 lines
4.5 KiB
C

/*
* Copyright 2013 <James.Bottomley@HansenPartnership.com>
*
* see COPYING file
*
* read some platform configuration tables
*/
#include <efi.h>
#include <efilib.h>
#include <guid.h>
#include <configtable.h>
void *
configtable_get_table(EFI_GUID *guid)
{
int i;
for (i = 0; i < ST->NumberOfTableEntries; i++) {
EFI_CONFIGURATION_TABLE *CT = &ST->ConfigurationTable[i];
if (CompareGuid(guid, &CT->VendorGuid) == 0) {
return CT->VendorTable;
}
}
return NULL;
}
EFI_IMAGE_EXECUTION_INFO_TABLE *
configtable_get_image_table(void)
{
return configtable_get_table(&SIG_DB);
}
EFI_IMAGE_EXECUTION_INFO *
configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
{
EFI_IMAGE_EXECUTION_INFO_TABLE *t = configtable_get_image_table();
if (!t)
return NULL;
int entries = t->NumberOfImages;
EFI_IMAGE_EXECUTION_INFO *e = t->InformationInfo;
int i;
for (i = 0; i < entries; i++) {
#ifdef DEBUG_CONFIG
Print(L"InfoSize = %d Action = %d\n", e->InfoSize, e->Action);
/* print what we have for debugging */
UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
#endif
CHAR16 *name = (CHAR16 *)(e->Data);
int skip = 0;
/* There's a bug in a lot of EFI platforms and they forget to
* put the name here. The only real way of detecting it is to
* look for either a UC16 NULL or ASCII as UC16 */
if (name[0] == '\0' || (e->Data[1] == 0 && e->Data[3] == 0)) {
skip = StrSize(name);
#ifdef DEBUG_CONFIG
Print(L"FOUND NAME %s (%d)\n", name, skip);
#endif
}
EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)(e->Data + skip), *dpn = dp;
if (dp->Type == 0 || dp->Type > 6 || dp->SubType == 0
|| (((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
/* Parse error, table corrupt, bail */
Print(L"Image Execution Information table corrupt\n");
break;
}
UINTN Size;
DevicePathInstance(&dpn, &Size);
#ifdef DEBUG_CONFIG
Print(L"Path: %s\n", DevicePathToStr(dp));
Print(L"Device Path Size %d\n", Size);
#endif
if (Size > e->InfoSize) {
/* parse error; the platform obviously has a
* corrupted image table; bail */
Print(L"Image Execution Information table corrupt\n");
break;
}
if (CompareMem(dp, DevicePath, Size) == 0) {
#ifdef DEBUG_CONFIG
Print(L"***FOUND\n");
console_get_keystroke();
#endif
return e;
}
e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
}
#ifdef DEBUG_CONFIG
Print(L"***NOT FOUND\n");
console_get_keystroke();
#endif
return NULL;
}
int
configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath)
{
EFI_IMAGE_EXECUTION_INFO *e = configtable_find_image(DevicePath);
/* Image may not be in DB if it gets executed successfully If it is,
* and EFI_IMAGE_EXECUTION_INITIALIZED is not set, then the image
* isn't authenticated. If there's no signature, usually
* EFI_IMAGE_EXECUTION_AUTH_UNTESTED is set, if the hash is in dbx,
* EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND is returned, and if the key is
* in dbx, EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED is returned*/
if (e && (e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND
|| e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED)) {
/* this means the images signing key is in dbx */
#ifdef DEBUG_CONFIG
Print(L"SIGNATURE IS IN DBX, FORBIDDING EXECUTION\n");
#endif
return 1;
}
return 0;
}