diff --git a/include/netboot.h b/include/netboot.h index a7bf6cd8f..296f10f00 100644 --- a/include/netboot.h +++ b/include/netboot.h @@ -3,10 +3,13 @@ #ifndef SHIM_NETBOOT_H #define SHIM_NETBOOT_H +#define SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE 1 + extern BOOLEAN findNetboot(EFI_HANDLE image_handle); extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle, CHAR8 *name); -extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz); +extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, + UINT64 *bufsiz, int flags); #endif /* SHIM_NETBOOT_H */ diff --git a/include/sbat.h b/include/sbat.h index bb523e7e0..093bb64a5 100644 --- a/include/sbat.h +++ b/include/sbat.h @@ -38,7 +38,8 @@ #define POLICY_RESET 3 #define POLICY_NOTREAD 255 -#define REVOCATIONFILE L"revocations.efi" +#define SBATREVOCATIONFILE L"revocations_sbat.efi" +#define SKUSIREVOCATIONFILE L"revocations_sku.efi" extern UINTN _sbat, _esbat; diff --git a/netboot.c b/netboot.c index a4cc7acde..467654270 100644 --- a/netboot.c +++ b/netboot.c @@ -368,7 +368,8 @@ status_from_error(UINT8 error_code) } } -EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, UINT64 *bufsiz) +EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, + UINT64 *bufsiz, int flags) { EFI_STATUS efi_status; EFI_PXE_BASE_CODE_TFTP_OPCODE read = EFI_PXE_BASE_CODE_TFTP_READ_FILE; @@ -376,7 +377,8 @@ EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, UINT BOOLEAN nobuffer = FALSE; UINTN blksz = 512; - console_print(L"Fetching Netboot Image %a\n", full_path); + if (~flags & SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE) + console_print(L"Fetching Netboot Image %a\n", full_path); if (*buffer == NULL) { *buffer = AllocatePool(4096 * 1024); if (!*buffer) @@ -399,7 +401,8 @@ EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, UINT if (EFI_ERROR(efi_status)) { if (pxe->Mode->TftpErrorReceived) { - console_print(L"TFTP error %u: %a\n", + if (~flags & SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE) + console_print(L"TFTP error %u: %a\n", pxe->Mode->TftpError.ErrorCode, pxe->Mode->TftpError.ErrorString); @@ -412,7 +415,9 @@ EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle UNUSED, VOID **buffer, UINT * * https://github.com/tianocore/edk2/pull/6287 */ - console_print(L"Unknown TFTP error, treating as file not found\n"); + if (~flags & SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE) + console_print(L"Unknown TFTP error, treating " + "as file not found\n"); efi_status = EFI_NOT_FOUND; } diff --git a/shim.c b/shim.c index bf0c9e6c4..083ea9e87 100644 --- a/shim.c +++ b/shim.c @@ -1055,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; @@ -1092,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; @@ -1107,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; @@ -1147,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; @@ -1419,7 +1422,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; @@ -1434,12 +1437,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; @@ -1485,7 +1488,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; @@ -1499,7 +1503,7 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) int i; efi_status = read_image(image_handle, filename, &PathName, - &data, &datasize); + &data, &datasize, flags); if (EFI_ERROR(efi_status)) return efi_status; @@ -1561,6 +1565,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; @@ -1568,6 +1573,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); @@ -1588,11 +1594,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; } @@ -1662,17 +1674,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); @@ -1683,9 +1695,14 @@ load_unbundled_trust(EFI_HANDLE image_handle) } } - if (!search_revocations && - StrnCaseCmp(info->FileName, L"shim_certificate", 16) == 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: