diff --git a/shim.c b/shim.c index 87202f7ff..031e1f412 100644 --- a/shim.c +++ b/shim.c @@ -32,6 +32,7 @@ #include #include +#include #define OID_EKU_MODSIGN "1.3.6.1.4.1.2312.16.1.2" @@ -54,6 +55,8 @@ extern struct { #define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }} +#define SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE 1 + typedef enum { DATA_FOUND, DATA_NOT_FOUND, @@ -1091,7 +1094,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; @@ -1130,8 +1134,9 @@ EFI_STATUS read_image(EFI_HANDLE image_handle, CHAR16 *ImagePath, efi_status = FetchNetbootimage(image_handle, &sourcebuffer, &sourcesize); 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 +1148,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; @@ -1183,7 +1189,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; @@ -1459,8 +1465,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); + efi_status = read_image(image_handle, L"revocations_sbat.efi", &PathName, + &data, &datasize, + SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE); + efi_status = read_image(image_handle, L"revocations_skusi.efi", &PathName, + &data, &datasize, + SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE); if (EFI_ERROR(efi_status)) return efi_status; @@ -1510,7 +1520,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; @@ -1523,7 +1534,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; @@ -1565,6 +1576,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 +1584,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 +1605,11 @@ 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, PathName); goto done; } @@ -1683,13 +1696,18 @@ load_unbundled_trust(EFI_HANDLE image_handle) if (EFI_ERROR(efi_status)) { perror(L"Failed to open %s - %r\n", PathName, efi_status); + while (load_cert_file(image_handle, FileName, PathName, + SUPPRESS_NETBOOT_OPEN_FAILURE_NOISE) + == EFI_SUCCESS && i++ < 10) { + FileName[17]++; + } goto done; } } if (!search_revocations && StrnCaseCmp(info->FileName, L"shim_certificate", 16) == 0) { - load_cert_file(image_handle, info->FileName, PathName); + load_cert_file(image_handle, info->FileName, PathName, 0); } } done: