summaryrefslogtreecommitdiff
path: root/shim.c
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2025-07-06 21:59:18 +0200
committerChristian Breunig <christian@breunig.cc>2025-07-06 21:59:18 +0200
commit02acad285c74015e8120ade2b41d51b39ae66b63 (patch)
tree980533ac963ac23bc9e090e3e4212bdb9e225a05 /shim.c
parent1c1d50da810e6c49e804a74719c2675b88b033a6 (diff)
parent18d98bfb34be583a5fe2987542e4b15e0db9cb61 (diff)
downloadefi-boot-shim-02acad285c74015e8120ade2b41d51b39ae66b63.tar.gz
efi-boot-shim-02acad285c74015e8120ade2b41d51b39ae66b63.zip
Merge tag '16.0' into vyos/current
shim-16.0 What's Changed * Validate that a supplied vendor cert is not in PEM format by @steve-mcintyre in https://github.com/rhboot/shim/pull/646 * sbat: Add grub.peimage,2 to latest (CVE-2024-2312) by @julian-klode in https://github.com/rhboot/shim/pull/651 * sbat: Also bump latest for grub,4 (and to todays date) by @julian-klode in https://github.com/rhboot/shim/pull/653 * undo change that limits certificate files to a single file by @jsetje in https://github.com/rhboot/shim/pull/659 * shim: don't set second_stage to the empty string by @jjd27 in https://github.com/rhboot/shim/pull/640 * Fix SBAT.md for today's consensus about numbers by @aronowski in https://github.com/rhboot/shim/pull/672 * Update Code of Conduct contact address by @aronowski in https://github.com/rhboot/shim/pull/683 * make-certs: Handle missing OpenSSL installation by @aronowski in https://github.com/rhboot/shim/pull/595 * Update MokVars.txt by @mikebeaton in https://github.com/rhboot/shim/pull/598 * export DEFINES for sub makefile by @bryteise in https://github.com/rhboot/shim/pull/600 * Drop unused EFI_IMAGE_SECURITY_DATABASE_GUID definition by @vittyvk in https://github.com/rhboot/shim/pull/609 * Null-terminate 'arguments' in fallback by @vittyvk in https://github.com/rhboot/shim/pull/611 * Fix "Verifiying" typo in error message by @chrisbainbridge in https://github.com/rhboot/shim/pull/706 * Update Fedora CI targets by @vathpela in https://github.com/rhboot/shim/pull/708 * Force gcc to produce DWARF4 so that gdb can use it by @mikebeaton in https://github.com/rhboot/shim/pull/607 * Minor housekeeping 2024121700 by @vathpela in https://github.com/rhboot/shim/pull/709 * Discard load-options that start with WINDOWS by @Metabolix in https://github.com/rhboot/shim/pull/621 * Fix the issue that the gBS->LoadImage pointer was empty. by @15058718379 in https://github.com/rhboot/shim/pull/703 * shim: Allow data after the end of device path node in load options by @dbnicholson in https://github.com/rhboot/shim/pull/694 * Handle network file not found like disks by @dbnicholson in https://github.com/rhboot/shim/pull/695 * Update gnu-efi submodule for EFI_HTTP_ERROR by @vathpela in https://github.com/rhboot/shim/pull/674 * Increase EFI file alignment by @lumag in https://github.com/rhboot/shim/pull/673 * avoid EFIv2 runtime services on Apple x86 machines by @eduardacatrinei in https://github.com/rhboot/shim/pull/690 * Improve shortcut performance when comparing two boolean expressions by @dennis-tseng99 in https://github.com/rhboot/shim/pull/667 * Provide better error message when MokManager is not found by @rmetrich in https://github.com/rhboot/shim/pull/663 * tpm: Boot with a warning if the event log is full by @kukrimate in https://github.com/rhboot/shim/pull/657 * MokManager: remove redundant logical constraints by @xypron in https://github.com/rhboot/shim/pull/409 * Test import_mok_state() when MokListRT would be bigger than available size by @vathpela in https://github.com/rhboot/shim/pull/417 * test-mok-mirror: minor bug fix by @vathpela in https://github.com/rhboot/shim/pull/715 * Fix file system browser hang when enrolling MOK from disk by @miczyg1 in https://github.com/rhboot/shim/pull/622 * Ignore a minor clang-tidy nit by @vathpela in https://github.com/rhboot/shim/pull/716 * Allow fallback to default loader when encountering errors on network boot by @nathan-omeara in https://github.com/rhboot/shim/pull/666 * test.mk: don't use a temporary random.bin by @vathpela in https://github.com/rhboot/shim/pull/718 * pe: Enhance debug report for update_mem_attrs by @jongwu in https://github.com/rhboot/shim/pull/594 * Multiple certificate handling improvements by @rosslagerwall in https://github.com/rhboot/shim/pull/644 * Generate SbatLevel Metadata from SbatLevel_Variable.txt by @jsetje in https://github.com/rhboot/shim/pull/711 * Apply EKU check with compile option by @dennis-tseng99 in https://github.com/rhboot/shim/pull/664 * Add configuration option to boot an alternative 2nd stage by @esnowberg in https://github.com/rhboot/shim/pull/608 * Loader protocol (with Device Path resolution support) by @kukrimate in https://github.com/rhboot/shim/pull/656 * netboot cleanup for additional files by @jsetje in https://github.com/rhboot/shim/pull/686 * Document how revocations can be delivered by @jsetje in https://github.com/rhboot/shim/pull/722 * post-process-pe: add tests to validate NX compliance by @vathpela in https://github.com/rhboot/shim/pull/705 * regression: CopyMem() in ad8692e copies out of bounds by @jsetje in https://github.com/rhboot/shim/pull/725 * Save the debug and error logs in mok-variables by @vathpela in https://github.com/rhboot/shim/pull/726 * Add features for the Host Security ID program by @vathpela in https://github.com/rhboot/shim/pull/660 * Mirror some more efi variables to mok-variables by @vathpela in https://github.com/rhboot/shim/pull/723 * This adds DXE Services measurements to HSI and uses them for NX by @vathpela in https://github.com/rhboot/shim/pull/724 * Add shim's current NX_COMPAT status to HSIStatus by @vathpela in https://github.com/rhboot/shim/pull/727 * README.tpm: reflect that vendor_db is in fact logged as "vendor_db" by @jsetje in https://github.com/rhboot/shim/pull/728 * Reject HTTP message with duplicate Content-Length header fields by @dennis-tseng99 in https://github.com/rhboot/shim/pull/637 * Disable log saving by @vathpela in https://github.com/rhboot/shim/pull/729 * fallback: don't add new boot order entries backwards by @vathpela in https://github.com/rhboot/shim/pull/730 * Misc fixes... by @vathpela in https://github.com/rhboot/shim/pull/735 * README.tpm: Update MokList entry to MokListRT by @trungams in https://github.com/rhboot/shim/pull/732 * SBAT Level update for February 2025 GRUB CVEs by @jsetje in https://github.com/rhboot/shim/pull/736 New Contributors * @jjd27 made their first contribution in https://github.com/rhboot/shim/pull/640 * @mikebeaton made their first contribution in https://github.com/rhboot/shim/pull/598 * @bryteise made their first contribution in https://github.com/rhboot/shim/pull/600 * @vittyvk made their first contribution in https://github.com/rhboot/shim/pull/609 * @chrisbainbridge made their first contribution in https://github.com/rhboot/shim/pull/706 * @Metabolix made their first contribution in https://github.com/rhboot/shim/pull/621 * @15058718379 made their first contribution in https://github.com/rhboot/shim/pull/703 * @dbnicholson made their first contribution in https://github.com/rhboot/shim/pull/694 * @lumag made their first contribution in https://github.com/rhboot/shim/pull/673 * @eduardacatrinei made their first contribution in https://github.com/rhboot/shim/pull/690 * @kukrimate made their first contribution in https://github.com/rhboot/shim/pull/657 * @miczyg1 made their first contribution in https://github.com/rhboot/shim/pull/622 * @nathan-omeara made their first contribution in https://github.com/rhboot/shim/pull/666 * @jongwu made their first contribution in https://github.com/rhboot/shim/pull/594 * @rosslagerwall made their first contribution in https://github.com/rhboot/shim/pull/644 * @trungams made their first contribution in https://github.com/rhboot/shim/pull/732 **Full Changelog**: https://github.com/rhboot/shim/compare/15.8...16.0 * tag '16.0': (451 commits) Update version to 16.0 SBAT Level update for February 2025 GRUB CVEs README.tpm: Update MokList entry to MokListRT Make 'make fanalyzer' work again. simple_dir_filter(): test our 'next' pointer shim_load_image(): initialize the buffer fully mirror_mok_db(): Free our mok variable name correctly mirror_one_mok_variable(): fix a memory leak on TPM log error. mirror_mok_db(): get rid of an unused variable+allocation generate_sbat_var_defs: Ensure revlistentry->revocations is initialized. generate_sbat_var_defs: Fix memory leak on realloc failure and fd leak. generate_sbat_var_defs: run clang-format on readfile() SetSecureVariable(): free Cert on failure Update version to 16.0~rc1 make-archive: some minor housekeeping makefiles: Make GITTAG swizzle tildes to dashes fallback: don't add new boot order entries backwards Disable log saving for now. Some save_logs() improvements. reject message with different values in multiple Content-Length header field ...
Diffstat (limited to 'shim.c')
-rw-r--r--shim.c296
1 files changed, 199 insertions, 97 deletions
diff --git a/shim.c b/shim.c
index 633163a0..8b933d7b 100644
--- a/shim.c
+++ b/shim.c
@@ -52,8 +52,6 @@ extern struct {
UINT32 vendor_deauthorized_offset;
} cert_table;
-#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
-
typedef enum {
DATA_FOUND,
DATA_NOT_FOUND,
@@ -781,39 +779,6 @@ verify_buffer (char *data, int datasize,
}
static int
-is_removable_media_path(EFI_LOADED_IMAGE *li)
-{
- unsigned int pathlen = 0;
- CHAR16 *bootpath = NULL;
- int ret = 0;
-
- bootpath = DevicePathToStr(li->FilePath);
-
- /* Check the beginning of the string and the end, to avoid
- * caring about which arch this is. */
- /* I really don't know why, but sometimes bootpath gives us
- * L"\\EFI\\BOOT\\/BOOTX64.EFI". So just handle that here...
- */
- if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) &&
- StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15) &&
- StrnCaseCmp(bootpath, L"EFI\\BOOT\\BOOT", 13) &&
- StrnCaseCmp(bootpath, L"EFI\\BOOT\\/BOOT", 14))
- goto error;
-
- pathlen = StrLen(bootpath);
- if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI"))
- goto error;
-
- ret = 1;
-
-error:
- if (bootpath)
- FreePool(bootpath);
-
- return ret;
-}
-
-static int
should_use_fallback(EFI_HANDLE image_handle)
{
EFI_LOADED_IMAGE *li;
@@ -994,10 +959,9 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size)
if ((INT32)size < 0)
return EFI_INVALID_PARAMETER;
- loader_is_participating = 1;
in_protocol = 1;
- efi_status = read_header(buffer, size, &context);
+ efi_status = read_header(buffer, size, &context, true);
if (EFI_ERROR(efi_status))
goto done;
@@ -1052,7 +1016,7 @@ static EFI_STATUS shim_read_header(void *data, unsigned int datasize,
EFI_STATUS efi_status;
in_protocol = 1;
- efi_status = read_header(data, datasize, context);
+ efi_status = read_header(data, datasize, context, true);
in_protocol = 0;
return efi_status;
@@ -1091,7 +1055,8 @@ str16_to_str8(CHAR16 *str16, CHAR8 **str8)
* Load and run an EFI executable
*/
EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
- CHAR16 **PathName, void **data, int *datasize)
+ CHAR16 **PathName, void **data, int *datasize,
+ int flags)
{
EFI_STATUS efi_status;
void *sourcebuffer = NULL;
@@ -1128,10 +1093,11 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
}
FreePool(netbootname);
efi_status = FetchNetbootimage(image_handle, &sourcebuffer,
- &sourcesize);
+ &sourcesize, flags);
if (EFI_ERROR(efi_status)) {
- perror(L"Unable to fetch TFTP image: %r\n",
- efi_status);
+ if (~flags & SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE)
+ perror(L"Unable to fetch TFTP image: %r\n",
+ efi_status);
return efi_status;
}
*data = sourcebuffer;
@@ -1143,8 +1109,9 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
&sourcesize,
netbootname);
if (EFI_ERROR(efi_status)) {
- perror(L"Unable to fetch HTTP image %a: %r\n",
- netbootname, efi_status);
+ if (~flags & SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE)
+ perror(L"Unable to fetch HTTP image %a: %r\n",
+ netbootname, efi_status);
return efi_status;
}
*data = sourcebuffer;
@@ -1156,7 +1123,7 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath,
efi_status = load_image(shim_li, data, datasize, *PathName);
if (EFI_ERROR(efi_status)) {
perror(L"Failed to load image %s: %r\n",
- PathName, efi_status);
+ *PathName, efi_status);
PrintErrors();
ClearErrors();
return efi_status;
@@ -1183,7 +1150,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
int datasize = 0;
efi_status = read_image(image_handle, ImagePath, &PathName, &data,
- &datasize);
+ &datasize, 0);
if (EFI_ERROR(efi_status))
goto done;
@@ -1215,7 +1182,9 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
goto restore;
}
- loader_is_participating = 0;
+#if 0
+ save_logs();
+#endif
/*
* The binary is trusted and relocated. Run it
@@ -1257,10 +1226,15 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
use_fb ? FALLBACK : second_stage);
}
- // If the filename is invalid, or the file does not exist,
- // just fallback to the default loader.
+ /*
+ * If the filename is invalid, or the file does not exist, just fall
+ * back to the default loader. Also fall back to the default loader
+ * if we get a TFTP error or HTTP error.
+ */
if (!use_fb && (efi_status == EFI_INVALID_PARAMETER ||
- efi_status == EFI_NOT_FOUND)) {
+ efi_status == EFI_NOT_FOUND ||
+ efi_status == EFI_HTTP_ERROR ||
+ efi_status == EFI_TFTP_ERROR)) {
console_print(
L"start_image() returned %r, falling back to default loader\n",
efi_status);
@@ -1286,7 +1260,7 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
EFI_STATUS efi_status;
EFI_LOADED_IMAGE *li = NULL;
- second_stage = DEFAULT_LOADER;
+ second_stage = (optional_second_stage) ? optional_second_stage : DEFAULT_LOADER;
load_options = NULL;
load_options_size = 0;
@@ -1373,13 +1347,17 @@ install_shim_protocols(void)
if (!EFI_ERROR(efi_status))
uninstall_shim_protocols();
+ init_image_loader();
+
/*
* Install the protocol
*/
- efi_status = BS->InstallProtocolInterface(&shim_lock_handle,
- &SHIM_LOCK_GUID,
- EFI_NATIVE_INTERFACE,
- &shim_lock_interface);
+ efi_status = BS->InstallMultipleProtocolInterfaces(&shim_lock_handle,
+ &SHIM_LOCK_GUID,
+ &shim_lock_interface,
+ &SHIM_IMAGE_LOADER_GUID,
+ &shim_image_loader_interface,
+ NULL);
if (EFI_ERROR(efi_status)) {
console_error(L"Could not install security protocol",
efi_status);
@@ -1405,8 +1383,12 @@ uninstall_shim_protocols(void)
/*
* If we're back here then clean everything up before exiting
*/
- BS->UninstallProtocolInterface(shim_lock_handle, &SHIM_LOCK_GUID,
- &shim_lock_interface);
+ BS->UninstallMultipleProtocolInterfaces(shim_lock_handle,
+ &SHIM_LOCK_GUID,
+ &shim_lock_interface,
+ &SHIM_IMAGE_LOADER_GUID,
+ &shim_image_loader_interface,
+ NULL);
if (!secure_mode())
return;
@@ -1444,7 +1426,7 @@ check_section_helper(char *section_name, int len, void **pointer,
section, data, datasize, minsize)
EFI_STATUS
-load_revocations_file(EFI_HANDLE image_handle, CHAR16 *PathName)
+load_revocations_file(EFI_HANDLE image_handle, CHAR16 *FileName, CHAR16 *PathName)
{
EFI_STATUS efi_status = EFI_SUCCESS;
PE_COFF_LOADER_IMAGE_CONTEXT context;
@@ -1459,12 +1441,12 @@ load_revocations_file(EFI_HANDLE image_handle, CHAR16 *PathName)
uint8_t *ssps_latest = NULL;
uint8_t *sspv_latest = NULL;
- efi_status = read_image(image_handle, L"revocations.efi", &PathName,
- &data, &datasize);
- if (EFI_ERROR(efi_status))
- return efi_status;
+ efi_status = read_image(image_handle, FileName, &PathName,
+ &data, &datasize,
+ SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE);
+ if (!EFI_ERROR(efi_status))
+ efi_status = verify_image(data, datasize, shim_li, &context);
- efi_status = verify_image(data, datasize, shim_li, &context);
if (EFI_ERROR(efi_status)) {
dprint(L"revocations failed to verify\n");
return efi_status;
@@ -1510,7 +1492,8 @@ load_revocations_file(EFI_HANDLE image_handle, CHAR16 *PathName)
}
EFI_STATUS
-load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName)
+load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName,
+ int flags)
{
EFI_STATUS efi_status;
PE_COFF_LOADER_IMAGE_CONTEXT context;
@@ -1518,37 +1501,58 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName)
EFI_SIGNATURE_LIST *certlist;
void *pointer;
UINT32 original;
+ UINT32 offset;
int datasize = 0;
void *data = NULL;
int i;
efi_status = read_image(image_handle, filename, &PathName,
- &data, &datasize);
+ &data, &datasize, flags);
if (EFI_ERROR(efi_status))
return efi_status;
efi_status = verify_image(data, datasize, shim_li, &context);
- if (EFI_ERROR(efi_status))
+ if (EFI_ERROR(efi_status)) {
+ FreePool(data);
return efi_status;
+ }
Section = context.FirstSection;
for (i = 0; i < context.NumberOfSections; i++, Section++) {
+ UINT32 sec_size = MIN(Section->Misc.VirtualSize, Section->SizeOfRawData);
+
if (CompareMem(Section->Name, ".db\0\0\0\0\0", 8) == 0) {
- original = user_cert_size;
- if (Section->SizeOfRawData < sizeof(EFI_SIGNATURE_LIST)) {
- continue;
- }
- pointer = ImageAddress(data, datasize,
- Section->PointerToRawData);
- if (!pointer) {
- continue;
+ offset = 0;
+ while ((sec_size - offset) >= sizeof(EFI_SIGNATURE_LIST)) {
+ UINT8 *tmp;
+
+ original = user_cert_size;
+ pointer = ImageAddress(data, datasize,
+ Section->PointerToRawData + offset);
+ if (!pointer) {
+ break;
+ }
+ certlist = pointer;
+
+ if (certlist->SignatureListSize < sizeof(EFI_SIGNATURE_LIST) ||
+ checked_add(offset, certlist->SignatureListSize, &offset) ||
+ offset > sec_size ||
+ checked_add(user_cert_size, certlist->SignatureListSize,
+ &user_cert_size)) {
+ break;
+ }
+
+ tmp = ReallocatePool(user_cert, original,
+ user_cert_size);
+ if (!tmp) {
+ FreePool(data);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ user_cert = tmp;
+
+ CopyMem(user_cert + original, pointer,
+ certlist->SignatureListSize);
}
- certlist = pointer;
- user_cert_size += certlist->SignatureListSize;;
- user_cert = ReallocatePool(user_cert, original,
- user_cert_size);
- CopyMem(user_cert + original, pointer,
- certlist->SignatureListSize);
}
}
FreePool(data);
@@ -1565,6 +1569,7 @@ load_unbundled_trust(EFI_HANDLE image_handle)
EFI_STATUS efi_status;
EFI_LOADED_IMAGE *li = NULL;
CHAR16 *PathName = NULL;
+ static CHAR16 FileName[] = L"shim_certificate_0.efi";
EFI_FILE *root, *dir;
EFI_FILE_INFO *info;
EFI_HANDLE device;
@@ -1572,6 +1577,7 @@ load_unbundled_trust(EFI_HANDLE image_handle)
UINTN buffersize = 0;
void *buffer = NULL;
BOOLEAN search_revocations = TRUE;
+ int i = 0;
efi_status = gBS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
(void **)&li);
@@ -1592,11 +1598,17 @@ load_unbundled_trust(EFI_HANDLE image_handle)
efi_status);
/*
* Network boot cases do not support reading a directory. Try
- * to read revocations.efi to pull in any unbundled SBATLevel
+ * to read revocations to pull in any unbundled SBATLevel
* updates unconditionally in those cases. This may produce
* console noise when the file is not present.
*/
- load_cert_file(image_handle, REVOCATIONFILE, PathName);
+ load_revocations_file(image_handle, SKUSIREVOCATIONFILE, PathName);
+ load_revocations_file(image_handle, SBATREVOCATIONFILE, PathName);
+ while (load_cert_file(image_handle, FileName, PathName,
+ SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE) == EFI_SUCCESS
+ && i++ < 10) {
+ FileName[17]++;
+ }
goto done;
}
@@ -1666,17 +1678,17 @@ load_unbundled_trust(EFI_HANDLE image_handle)
}
/*
- * In the event that there are unprocessed revocation
+ * In the event that there are unprocessed sbat revocation
* additions, they could be intended to ban any *new* trust
* anchors we find here. With that in mind, we always want to
* do a pass of loading revocations before we try to add
* anything new to our allowlist. This is done by making two
* passes over the directory, first to search for the
- * revocations.efi file then to search for shim_certificate.efi
+ * revocations_sbat.efi file then to search for shim_certificate*.efi
*/
if (search_revocations &&
- StrCaseCmp(info->FileName, REVOCATIONFILE) == 0) {
- load_revocations_file(image_handle, PathName);
+ StrCaseCmp(info->FileName, SBATREVOCATIONFILE) == 0) {
+ load_revocations_file(image_handle, SBATREVOCATIONFILE, PathName);
search_revocations = FALSE;
efi_status = root->Open(root, &dir, PathName,
EFI_FILE_MODE_READ, 0);
@@ -1687,9 +1699,14 @@ load_unbundled_trust(EFI_HANDLE image_handle)
}
}
- if (!search_revocations &&
- StrCaseCmp(info->FileName, L"shim_certificate.efi") == 0) {
- load_cert_file(image_handle, info->FileName, PathName);
+ if (!search_revocations) {
+ if (StrnCaseCmp(info->FileName, L"shim_certificate", 16) == 0) {
+ load_cert_file(image_handle, info->FileName, PathName, 0);
+ }
+ if (StrCaseCmp(info->FileName, SKUSIREVOCATIONFILE) == 0) {
+ load_revocations_file(image_handle,
+ SKUSIREVOCATIONFILE, PathName);
+ }
}
}
done:
@@ -1698,6 +1715,86 @@ done:
return efi_status;
}
+/* Read optional options file */
+EFI_STATUS
+load_shim_options(EFI_HANDLE image_handle)
+{
+ EFI_STATUS efi_status;
+ EFI_HANDLE device;
+ EFI_LOADED_IMAGE *li = NULL;
+ EFI_FILE_IO_INTERFACE *drive;
+ EFI_FILE *root;
+ EFI_FILE_HANDLE ofile;
+ CHAR16 *PathName = NULL;
+ CHAR16 *buffer;
+ UINTN comma0;
+ UINT64 bs;
+
+ efi_status = gBS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID,
+ (void **)&li);
+ if (EFI_ERROR(efi_status)) {
+ perror(L"Unable to init protocol\n");
+ return efi_status;
+ }
+
+ efi_status = generate_path_from_image_path(li, L"options.csv", &PathName);
+ if (EFI_ERROR(efi_status))
+ goto done;
+
+ device = li->DeviceHandle;
+
+ efi_status = BS->HandleProtocol(device, &EFI_SIMPLE_FILE_SYSTEM_GUID,
+ (void **) &drive);
+ if (EFI_ERROR(efi_status))
+ goto done;
+
+ efi_status = drive->OpenVolume(drive, &root);
+ if (EFI_ERROR(efi_status)) {
+ perror(L"Failed to open fs: %r\n", efi_status);
+ goto done;
+ }
+
+ efi_status = root->Open(root, &ofile, PathName, EFI_FILE_READ_ONLY, 0);
+ if (EFI_ERROR(efi_status)) {
+ if (efi_status != EFI_NOT_FOUND)
+ perror(L"Failed to open %s - %r\n", PathName, efi_status);
+ goto done;
+ }
+
+ dprint(L"Loading optional second stage info from options.csv\n");
+ efi_status = read_file(ofile, PathName, &buffer, &bs);
+ if (EFI_ERROR(efi_status)) {
+ perror(L"Failed to read file\n");
+ goto done;
+ }
+
+ /*
+ * This file may or may not start with the Unicode byte order marker.
+ * Since UEFI is defined as LE, this file must also be LE.
+ * If we find the LE byte order marker, just skip its.
+ */
+ if (*buffer == 0xfeff)
+ buffer++;
+
+ comma0 = StrCSpn(buffer, L",");
+ if (comma0 == 0) {
+ perror(L"Invalid csv file\n");
+ goto done;
+ }
+
+ /*
+ * Currently the options.csv file allows one entry for the optional
+ * secondary boot stage, anything afterwards is skipped.
+ */
+ buffer[comma0] = L'\0';
+ dprint(L"Optional 2nd stage:\"%s\"\n", buffer);
+ optional_second_stage=buffer;
+
+done:
+ FreePool(PathName);
+ return EFI_SUCCESS;
+}
+
EFI_STATUS
shim_init(void)
{
@@ -1720,7 +1817,6 @@ shim_init(void)
* validation of the next image.
*/
hook_system_services(systab);
- loader_is_participating = 0;
}
}
@@ -1746,11 +1842,12 @@ shim_fini(void)
uninstall_shim_protocols();
if (secure_mode()) {
-
- /*
- * Remove our hooks from system services.
- */
- unhook_system_services();
+ if (vendor_authorized_size || vendor_deauthorized_size) {
+ /*
+ * Remove our hooks from system services.
+ */
+ unhook_system_services();
+ }
}
unhook_exit();
@@ -1860,7 +1957,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
L"shim_init() failed",
L"import of SBAT data failed",
L"SBAT self-check failed",
- SBAT_VAR_NAME L" UEFI variable setting failed",
+ SBAT_VAR_NAME L" UEFI variable setting failed", // NOLINT(bugprone-suspicious-missing-comma)
NULL
};
enum {
@@ -1898,6 +1995,8 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
*/
debug_hook();
+ get_shim_nx_capability(image_handle);
+
efi_status = set_sbat_uefi_variable_internal();
if (EFI_ERROR(efi_status) && secure_mode()) {
perror(L"%s variable initialization failed\n", SBAT_VAR_NAME);
@@ -1929,7 +2028,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
efi_status = verify_sbat_section(sbat_start, sbat_end - sbat_start - 1);
if (EFI_ERROR(efi_status)) {
- perror(L"Verifiying shim SBAT data failed: %r\n",
+ perror(L"Verifying shim SBAT data failed: %r\n",
efi_status);
msg = SBAT_SELF_CHECK;
goto die;
@@ -1938,6 +2037,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
}
init_openssl();
+ get_hsi_mem_info();
efi_status = load_unbundled_trust(global_image_handle);
if (EFI_ERROR(efi_status)) {
@@ -1981,6 +2081,8 @@ die:
*/
(void) del_variable(SHIM_RETAIN_PROTOCOL_VAR_NAME, SHIM_LOCK_GUID);
+ load_shim_options(image_handle);
+
efi_status = shim_init();
if (EFI_ERROR(efi_status)) {
msg = SHIM_INIT;