1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2013 <James.Bottomley@HansenPartnership.com>
*
* read some platform configuration tables
*/
#include "shim.h"
void *
configtable_get_table(EFI_GUID *guid)
{
unsigned 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
console_print(L"InfoSize = %d Action = %d\n", e->InfoSize, e->Action);
/* print what we have for debugging */
UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
console_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;
console_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;
console_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;
console_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;
console_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;
console_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
console_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
|| ((unsigned)((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
/* Parse error, table corrupt, bail */
console_print(L"Image Execution Information table corrupt\n");
break;
}
UINTN Size;
DevicePathInstance(&dpn, &Size);
#ifdef DEBUG_CONFIG
console_print(L"Path: %s\n", DevicePathToStr(dp));
console_print(L"Device Path Size %d\n", Size);
#endif
if (Size > e->InfoSize) {
/* parse error; the platform obviously has a
* corrupted image table; bail */
console_print(L"Image Execution Information table corrupt\n");
break;
}
if (CompareMem(dp, (void *)DevicePath, Size) == 0) {
#ifdef DEBUG_CONFIG
console_print(L"***FOUND\n");
console_get_keystroke();
#endif
return e;
}
e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
}
#ifdef DEBUG_CONFIG
console_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
console_print(L"SIGNATURE IS IN DBX, FORBIDDING EXECUTION\n");
#endif
return 1;
}
return 0;
}
|