]> git.proxmox.com Git - efi-boot-shim.git/blob - lib/configtable.c
Import upstream version 0.7
[efi-boot-shim.git] / lib / configtable.c
1 /*
2 * Copyright 2013 <James.Bottomley@HansenPartnership.com>
3 *
4 * see COPYING file
5 *
6 * read some platform configuration tables
7 */
8 #include <efi.h>
9 #include <efilib.h>
10
11 #include <guid.h>
12 #include <configtable.h>
13
14 void *
15 configtable_get_table(EFI_GUID *guid)
16 {
17 int i;
18
19 for (i = 0; i < ST->NumberOfTableEntries; i++) {
20 EFI_CONFIGURATION_TABLE *CT = &ST->ConfigurationTable[i];
21
22 if (CompareGuid(guid, &CT->VendorGuid) == 0) {
23 return CT->VendorTable;
24 }
25 }
26 return NULL;
27 }
28
29 EFI_IMAGE_EXECUTION_INFO_TABLE *
30 configtable_get_image_table(void)
31 {
32 return configtable_get_table(&SIG_DB);
33 }
34
35 EFI_IMAGE_EXECUTION_INFO *
36 configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
37 {
38 EFI_IMAGE_EXECUTION_INFO_TABLE *t = configtable_get_image_table();
39
40 if (!t)
41 return NULL;
42
43 int entries = t->NumberOfImages;
44 EFI_IMAGE_EXECUTION_INFO *e = t->InformationInfo;
45
46 int i;
47 for (i = 0; i < entries; i++) {
48 #ifdef DEBUG_CONFIG
49 Print(L"InfoSize = %d Action = %d\n", e->InfoSize, e->Action);
50
51 /* print what we have for debugging */
52 UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
53 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
54 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]);
55 d += 16;
56 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
57 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]);
58 d += 16;
59 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
60 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]);
61 d += 16;
62 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
63 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]);
64 d += 16;
65 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
66 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]);
67 d += 16;
68 Print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
69 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]);
70 #endif
71 CHAR16 *name = (CHAR16 *)(e->Data);
72 int skip = 0;
73
74 /* There's a bug in a lot of EFI platforms and they forget to
75 * put the name here. The only real way of detecting it is to
76 * look for either a UC16 NULL or ASCII as UC16 */
77 if (name[0] == '\0' || (e->Data[1] == 0 && e->Data[3] == 0)) {
78 skip = StrSize(name);
79 #ifdef DEBUG_CONFIG
80 Print(L"FOUND NAME %s (%d)\n", name, skip);
81 #endif
82 }
83 EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)(e->Data + skip), *dpn = dp;
84 if (dp->Type == 0 || dp->Type > 6 || dp->SubType == 0
85 || (((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
86 /* Parse error, table corrupt, bail */
87 Print(L"Image Execution Information table corrupt\n");
88 break;
89 }
90
91 UINTN Size;
92 DevicePathInstance(&dpn, &Size);
93 #ifdef DEBUG_CONFIG
94 Print(L"Path: %s\n", DevicePathToStr(dp));
95 Print(L"Device Path Size %d\n", Size);
96 #endif
97 if (Size > e->InfoSize) {
98 /* parse error; the platform obviously has a
99 * corrupted image table; bail */
100 Print(L"Image Execution Information table corrupt\n");
101 break;
102 }
103
104 if (CompareMem(dp, (void *)DevicePath, Size) == 0) {
105 #ifdef DEBUG_CONFIG
106 Print(L"***FOUND\n");
107 console_get_keystroke();
108 #endif
109 return e;
110 }
111 e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
112 }
113
114 #ifdef DEBUG_CONFIG
115 Print(L"***NOT FOUND\n");
116 console_get_keystroke();
117 #endif
118
119 return NULL;
120 }
121
122 int
123 configtable_image_is_forbidden(const EFI_DEVICE_PATH *DevicePath)
124 {
125 EFI_IMAGE_EXECUTION_INFO *e = configtable_find_image(DevicePath);
126
127 /* Image may not be in DB if it gets executed successfully If it is,
128 * and EFI_IMAGE_EXECUTION_INITIALIZED is not set, then the image
129 * isn't authenticated. If there's no signature, usually
130 * EFI_IMAGE_EXECUTION_AUTH_UNTESTED is set, if the hash is in dbx,
131 * EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND is returned, and if the key is
132 * in dbx, EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED is returned*/
133
134 if (e && (e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND
135 || e->Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED)) {
136 /* this means the images signing key is in dbx */
137 #ifdef DEBUG_CONFIG
138 Print(L"SIGNATURE IS IN DBX, FORBIDDING EXECUTION\n");
139 #endif
140 return 1;
141 }
142
143 return 0;
144 }