diff options
author | Tom Rini <trini@konsulko.com> | 2020-06-03 14:10:03 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-06-03 14:10:03 -0400 |
commit | 1b6ae82a5abb4cbedb0d6cb262526173f4efa486 (patch) | |
tree | 916aadd700c3c98d3f6b6929ef1249e38043e319 /lib | |
parent | 0d8f35b58cc8458a5263b424896a386429ee49e5 (diff) | |
parent | a4292eccfdc98b51d0200a6c912af237aeddd5c8 (diff) |
Merge tag 'efi-2020-07-rc4' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
Pull request for UEFI sub-system for efi-2020-07-rc4
This patch series addresses the following issues:
* allow compiling with clang
* add missing function descriptions to the HTML documentation
* simplify the validation of UEFI images
* validate load options in the UEFI boot manager
In a preparatory patch a structure definition is moved.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_bootmgr.c | 48 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 10 | ||||
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 35 | ||||
-rw-r--r-- | lib/efi_loader/efi_signature.c | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_variable.c | 1 |
5 files changed, 62 insertions, 33 deletions
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index b112f5d81e..e144b3e7f4 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -36,24 +36,50 @@ static const struct efi_runtime_services *rs; * * @lo: pointer to target * @data: serialized data + * @size: size of the load option, on return size of the optional data + * Return: status code */ -void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data) +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, + efi_uintn_t *size) { + efi_uintn_t len; + + len = sizeof(u32); + if (*size < len + 2 * sizeof(u16)) + return EFI_INVALID_PARAMETER; lo->attributes = get_unaligned_le32(data); - data += sizeof(u32); + data += len; + *size -= len; + len = sizeof(u16); lo->file_path_length = get_unaligned_le16(data); - data += sizeof(u16); + data += len; + *size -= len; - /* FIXME */ lo->label = (u16 *)data; - data += (u16_strlen(lo->label) + 1) * sizeof(u16); - - /* FIXME */ + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); + if (lo->label[len]) + return EFI_INVALID_PARAMETER; + len = (len + 1) * sizeof(u16); + if (*size < len) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + len = lo->file_path_length; + if (*size < len) + return EFI_INVALID_PARAMETER; lo->file_path = (struct efi_device_path *)data; - data += lo->file_path_length; + /* + * TODO: validate device path. There should be an end node within + * the indicated file_path_length. + */ + data += len; + *size -= len; lo->optional_data = data; + + return EFI_SUCCESS; } /** @@ -168,7 +194,11 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle) if (!load_option) return EFI_LOAD_ERROR; - efi_deserialize_load_option(&lo, load_option); + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + log_warning("Invalid load option for %ls\n", varname); + goto error; + } if (lo.attributes & LOAD_OPTION_ACTIVE) { u32 attributes; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index db34938196..1591ad8300 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -49,7 +49,7 @@ static efi_handle_t current_image; * restriction so we need to manually swap its and our view of that register on * EFI callback entry/exit. */ -static volatile void *efi_gd, *app_gd; +static volatile gd_t *efi_gd, *app_gd; #endif /* 1 if inside U-Boot code, 0 if inside EFI payload code */ @@ -89,7 +89,7 @@ int __efi_entry_check(void) #ifdef CONFIG_ARM assert(efi_gd); app_gd = gd; - gd = efi_gd; + set_gd(efi_gd); #endif return ret; } @@ -99,7 +99,7 @@ int __efi_exit_check(void) { int ret = --entry_count == 0; #ifdef CONFIG_ARM - gd = app_gd; + set_gd(app_gd); #endif return ret; } @@ -123,7 +123,7 @@ void efi_restore_gd(void) /* Only restore if we're already in EFI context */ if (!efi_gd) return; - gd = efi_gd; + set_gd(efi_gd); #endif } @@ -2920,7 +2920,7 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, * otherwise __efi_entry_check() will put the wrong value into * app_gd. */ - gd = app_gd; + set_gd(app_gd); #endif /* * To get ready to call EFI_EXIT below we have to execute the diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 5dd601908d..478aaf50d3 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -212,14 +212,16 @@ static void efi_set_code_and_data_type( #ifdef CONFIG_EFI_SECURE_BOOT /** - * cmp_pe_section - compare two sections - * @arg1: Pointer to pointer to first section - * @arg2: Pointer to pointer to second section + * cmp_pe_section() - compare virtual addresses of two PE image sections + * @arg1: pointer to pointer to first section header + * @arg2: pointer to pointer to second section header * - * Compare two sections in PE image. + * Compare the virtual addresses of two sections of an portable executable. + * The arguments are defined as const void * to allow usage with qsort(). * - * Return: -1, 0, 1 respectively if arg1 < arg2, arg1 == arg2 or - * arg1 > arg2 + * Return: -1 if the virtual address of arg1 is less than that of arg2, + * 0 if the virtual addresses are equal, 1 if the virtual address + * of arg1 is greater than that of arg2. */ static int cmp_pe_section(const void *arg1, const void *arg2) { @@ -237,7 +239,7 @@ static int cmp_pe_section(const void *arg1, const void *arg2) } /** - * efi_image_parse - parse a PE image + * efi_image_parse() - parse a PE image * @efi: Pointer to image * @len: Size of @efi * @regp: Pointer to a list of regions @@ -404,7 +406,7 @@ err: } /** - * efi_image_unsigned_authenticate - authenticate unsigned image with + * efi_image_unsigned_authenticate() - authenticate unsigned image with * SHA256 hash * @regs: List of regions to be verified * @@ -451,7 +453,7 @@ out: } /** - * efi_image_authenticate - verify a signature of signed image + * efi_image_authenticate() - verify a signature of signed image * @efi: Pointer to image * @efi_size: Size of @efi * @@ -635,21 +637,18 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, goto err; } - /* assume sizeof(IMAGE_NT_HEADERS32) <= sizeof(IMAGE_NT_HEADERS64) */ - if (efi_size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS32)) { + /* + * Check if the image section header fits into the file. Knowing that at + * least one section header follows we only need to check for the length + * of the 64bit header which is longer than the 32bit header. + */ + if (efi_size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS64)) { printf("%s: Invalid offset for Extended Header\n", __func__); ret = EFI_LOAD_ERROR; goto err; } nt = (void *) ((char *)efi + dos->e_lfanew); - if ((nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) && - (efi_size < dos->e_lfanew + sizeof(IMAGE_NT_HEADERS64))) { - printf("%s: Invalid offset for Extended Header\n", __func__); - ret = EFI_LOAD_ERROR; - goto err; - } - if (nt->Signature != IMAGE_NT_SIGNATURE) { printf("%s: Invalid NT Signature\n", __func__); ret = EFI_LOAD_ERROR; diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index adcb8c9cca..6685253856 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -22,6 +22,7 @@ const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID; const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID; const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID; const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID; +const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; #ifdef CONFIG_EFI_SECURE_BOOT diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 0a43db5678..e097670e28 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -26,7 +26,6 @@ enum efi_secure_mode { EFI_MODE_DEPLOYED, }; -const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; static bool efi_secure_boot; static int efi_secure_mode; static u8 efi_vendor_keys; |