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. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAl7X4dIACgkQxIHbvCwF GsTMfxAAjYeEoHNhdxr6ZAytC653O0iIb6BQQmrkSakcAtU82PgkiUCJ+oSF09th nBpSHZ8QW92avfnmrY3FjXj8fPU01LV4gytZwnEtgi6OaWtenOc/t3pElVVk7adW 17VbRTHY3Urb4+oM9hGI5KEmDOgRCe2LUOlOKA6b6tGiG+1mchE4gIgNGh3LDbbM bAojulCliDoKyIUHMSwrpqX7U5OQF89qhd4AhkmlnYe0OqZueEMS3pDwsHICuP2i j5SPqHF5r8Nm8Mf+bDLcRDK7xKQAkqGzqP8KwqVN1o7++4MbnlI/zL94vBrbbye9 av7OucMyKL44+BnOpB1dm/Zp8rJpJhOdbr0MHzZCk9foPQrWoLXRGx0dJLWNJvGd Sb67YXBl8DP//uZCq4zdj/j9wuWE31ZbSRA7SM4ioODQYpRu3RdrQJltQcwIbcwK M0L0JDXDNdnNPBA3Fwe3QxpskKOaXm1C8yTgDxEnjd9qoZCbohTl/nRjntXQUZWN Xq3rmgxilYXSyYZ+hqtp6zT0KEZAMSHi/OibYSRQRva491hZS9qhcI3nPPpR30/s xBd1ee6WW2sZVHVrEfqkWb4w7379I9Cp08lfmk6Mk+pne4Cbn8qc/lH+fxAaKkO5 eUTxWcWWuXJmgPtdZQux7bqDWr9WC6gUQ8W2PLLv4t8l7gqk1lE= =rbBa -----END PGP SIGNATURE----- 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.
This commit is contained in:
		
						commit
						1b6ae82a5a
					
				|  | @ -117,4 +117,13 @@ static inline gd_t *get_gd(void) | |||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| static inline void set_gd(volatile gd_t *gd_ptr) | ||||
| { | ||||
| #ifdef CONFIG_ARM64 | ||||
| 	__asm__ volatile("ldr x18, %0\n" : : "m"(gd_ptr)); | ||||
| #else | ||||
| 	__asm__ volatile("ldr r9, %0\n" : : "m"(gd_ptr)); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #endif /* __ASM_GBL_DATA_H */ | ||||
|  |  | |||
|  | @ -694,14 +694,19 @@ static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag, | |||
|  * | ||||
|  * Decode the value of UEFI load option variable and print information. | ||||
|  */ | ||||
| static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t size) | ||||
| static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size) | ||||
| { | ||||
| 	struct efi_load_option lo; | ||||
| 	char *label, *p; | ||||
| 	size_t label_len16, label_len; | ||||
| 	u16 *dp_str; | ||||
| 	efi_status_t ret; | ||||
| 
 | ||||
| 	efi_deserialize_load_option(&lo, data); | ||||
| 	ret = efi_deserialize_load_option(&lo, data, size); | ||||
| 	if (ret != EFI_SUCCESS) { | ||||
| 		printf("%ls: invalid load option\n", varname16); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	label_len16 = u16_strlen(lo.label); | ||||
| 	label_len = utf16_utf8_strnlen(lo.label, label_len16); | ||||
|  | @ -728,8 +733,7 @@ static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t size) | |||
| 
 | ||||
| 	printf("  data:\n"); | ||||
| 	print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1, | ||||
| 		       lo.optional_data, size + (u8 *)data - | ||||
| 		       (u8 *)lo.optional_data, true); | ||||
| 		       lo.optional_data, *size, true); | ||||
| 	free(label); | ||||
| } | ||||
| 
 | ||||
|  | @ -759,7 +763,7 @@ static void show_efi_boot_opt(u16 *varname16) | |||
| 						&efi_global_variable_guid, | ||||
| 						NULL, &size, data)); | ||||
| 		if (ret == EFI_SUCCESS) | ||||
| 			show_efi_boot_opt_data(varname16, data, size); | ||||
| 			show_efi_boot_opt_data(varname16, data, &size); | ||||
| 		free(data); | ||||
| 	} | ||||
| } | ||||
|  | @ -920,7 +924,12 @@ static int show_efi_boot_order(void) | |||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		efi_deserialize_load_option(&lo, data); | ||||
| 		ret = efi_deserialize_load_option(&lo, data, &size); | ||||
| 		if (ret != EFI_SUCCESS) { | ||||
| 			printf("%ls: invalid load option\n", var_name16); | ||||
| 			ret = CMD_RET_FAILURE; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		label_len16 = u16_strlen(lo.label); | ||||
| 		label_len = utf16_utf8_strnlen(lo.label, label_len16); | ||||
|  |  | |||
|  | @ -708,7 +708,8 @@ struct efi_load_option { | |||
| 	const u8 *optional_data; | ||||
| }; | ||||
| 
 | ||||
| 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); | ||||
| unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data); | ||||
| efi_status_t efi_bootmgr_load(efi_handle_t *handle); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 	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; | ||||
| 
 | ||||
| 	/* FIXME */ | ||||
| 	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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue