diff options
author | Tom Rini <trini@konsulko.com> | 2019-05-03 07:10:17 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2019-05-03 07:10:17 -0400 |
commit | 6e25cfe9a475e8177bad7d9f97cffead6aab6b0d (patch) | |
tree | 2a74f7339892266a8d1d9afd812e9dad38ba0593 /lib | |
parent | 3570ea1f98229dc8c166dfc2693510db9167f7f8 (diff) | |
parent | 4ccf678f37731d8ec09eae8dca5f4cbe84132a52 (diff) |
Merge tag 'efi-2019-07-rc2' of git://git.denx.de/u-boot-efi
Pull request for UEFI sub-system for v2019.07-rc2
This pull request provides error fixes for the handling of GPT partitions
and for the UEFI subsystem.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_bootmgr.c | 15 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 57 | ||||
-rw-r--r-- | lib/efi_loader/efi_memory.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_setup.c | 11 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_miniapp_exit.c | 17 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_startimage_exit.c | 15 | ||||
-rw-r--r-- | lib/uuid.c | 2 |
7 files changed, 101 insertions, 18 deletions
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 4ccba22875..7bf51874c1 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -53,19 +53,20 @@ void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data) */ unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) { - unsigned long label_len, option_len; + unsigned long label_len; unsigned long size; u8 *p; label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); - option_len = strlen((char *)lo->optional_data); /* total size */ size = sizeof(lo->attributes); size += sizeof(lo->file_path_length); size += label_len; size += lo->file_path_length; - size += option_len + 1; + if (lo->optional_data) + size += (utf8_utf16_strlen((const char *)lo->optional_data) + + 1) * sizeof(u16); p = malloc(size); if (!p) return 0; @@ -84,10 +85,10 @@ unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) memcpy(p, lo->file_path, lo->file_path_length); p += lo->file_path_length; - memcpy(p, lo->optional_data, option_len); - p += option_len; - *(char *)p = '\0'; - + if (lo->optional_data) { + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); + p += sizeof(u16); /* size of trailing \0 */ + } return size; } diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 601b0a2cb8..e5c46e9f08 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -423,10 +423,12 @@ static efi_status_t EFIAPI efi_free_pool_ext(void *buffer) } /** - * efi_add_handle() - add a new object to the object list - * @obj: object to be added + * efi_add_handle() - add a new handle to the object list * - * The protocols list is initialized. The object handle is set. + * @handle: handle to be added + * + * The protocols list is initialized. The handle is added to the list of known + * UEFI objects. */ void efi_add_handle(efi_handle_t handle) { @@ -618,7 +620,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl, } if ((type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) && - (is_valid_tpl(notify_tpl) != EFI_SUCCESS)) + (!notify_function || is_valid_tpl(notify_tpl) != EFI_SUCCESS)) return EFI_INVALID_PARAMETER; evt = calloc(1, sizeof(struct efi_event)); @@ -2626,6 +2628,9 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, efi_is_direct_boot = false; + image_obj->exit_data_size = exit_data_size; + image_obj->exit_data = exit_data; + /* call the image! */ if (setjmp(&image_obj->exit_jmp)) { /* @@ -2670,6 +2675,41 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, } /** + * efi_update_exit_data() - fill exit data parameters of StartImage() + * + * @image_obj image handle + * @exit_data_size size of the exit data buffer + * @exit_data buffer with data returned by UEFI payload + * Return: status code + */ +static efi_status_t efi_update_exit_data(struct efi_loaded_image_obj *image_obj, + efi_uintn_t exit_data_size, + u16 *exit_data) +{ + efi_status_t ret; + + /* + * If exit_data is not provided to StartImage(), exit_data_size must be + * ignored. + */ + if (!image_obj->exit_data) + return EFI_SUCCESS; + if (image_obj->exit_data_size) + *image_obj->exit_data_size = exit_data_size; + if (exit_data_size && exit_data) { + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, + exit_data_size, + (void **)image_obj->exit_data); + if (ret != EFI_SUCCESS) + return ret; + memcpy(*image_obj->exit_data, exit_data, exit_data_size); + } else { + image_obj->exit_data = NULL; + } + return EFI_SUCCESS; +} + +/** * efi_exit() - leave an EFI application or driver * @image_handle: handle of the application or driver that is exiting * @exit_status: status code @@ -2709,6 +2749,15 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, if (ret != EFI_SUCCESS) goto out; + /* Exit data is only foreseen in case of failure. */ + if (exit_status != EFI_SUCCESS) { + ret = efi_update_exit_data(image_obj, exit_data_size, + exit_data); + /* Exiting has priority. Don't return error to caller. */ + if (ret != EFI_SUCCESS) + EFI_PRINT("%s: out of memory\n", __func__); + } + /* Make sure entry/exit counts for EFI world cross-overs match */ EFI_EXIT(exit_status); diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 987cc6dc5f..776077cc35 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -452,7 +452,7 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) uint64_t r = 0; /* Sanity check */ - if (!memory || (memory & EFI_PAGE_MASK)) { + if (!memory || (memory & EFI_PAGE_MASK) || !pages) { printf("%s: illegal free 0x%llx, 0x%zx\n", __func__, memory, pages); return EFI_INVALID_PARAMETER; diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index b32a7b3f93..87db51cbb7 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -79,6 +79,7 @@ out: */ efi_status_t efi_init_obj_list(void) { + u64 os_indications_supported = 0; /* None */ efi_status_t ret = EFI_SUCCESS; /* Initialize once only */ @@ -90,6 +91,16 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + /* Indicate supported features */ + ret = EFI_CALL(efi_set_variable(L"OsIndicationsSupported", + &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(os_indications_supported), + &os_indications_supported)); + if (ret != EFI_SUCCESS) + goto out; + /* Initialize system table */ ret = efi_initialize_system_table(); if (ret != EFI_SUCCESS) diff --git a/lib/efi_selftest/efi_selftest_miniapp_exit.c b/lib/efi_selftest/efi_selftest_miniapp_exit.c index b3ca109d81..6b5cfb01cf 100644 --- a/lib/efi_selftest/efi_selftest_miniapp_exit.c +++ b/lib/efi_selftest/efi_selftest_miniapp_exit.c @@ -9,7 +9,7 @@ */ #include <common.h> -#include <efi_api.h> +#include <efi_selftest.h> static efi_guid_t loaded_image_protocol_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; @@ -66,15 +66,22 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, struct efi_system_table *systable) { struct efi_simple_text_output_protocol *con_out = systable->con_out; - efi_status_t ret = EFI_UNSUPPORTED; + efi_status_t ret; + u16 text[] = EFI_ST_SUCCESS_STR; con_out->output_string(con_out, L"EFI application calling Exit\n"); - if (check_loaded_image_protocol(handle, systable) != EFI_SUCCESS) + if (check_loaded_image_protocol(handle, systable) != EFI_SUCCESS) { + con_out->output_string(con_out, + L"Loaded image protocol missing\n"); ret = EFI_NOT_FOUND; + goto out; + } - /* The return value is checked by the calling test */ - systable->boottime->exit(handle, ret, 0, NULL); + /* This return value is expected by the calling test */ + ret = EFI_UNSUPPORTED; +out: + systable->boottime->exit(handle, ret, sizeof(text), text); /* * This statement should not be reached. diff --git a/lib/efi_selftest/efi_selftest_startimage_exit.c b/lib/efi_selftest/efi_selftest_startimage_exit.c index fa4b7d4a9b..96049dea86 100644 --- a/lib/efi_selftest/efi_selftest_startimage_exit.c +++ b/lib/efi_selftest/efi_selftest_startimage_exit.c @@ -123,6 +123,9 @@ static int execute(void) { efi_status_t ret; efi_handle_t handle; + efi_uintn_t exit_data_size = 0; + u16 *exit_data = NULL; + u16 expected_text[] = EFI_ST_SUCCESS_STR; ret = boottime->load_image(false, image_handle, NULL, image, img.length, &handle); @@ -130,11 +133,21 @@ static int execute(void) efi_st_error("Failed to load image\n"); return EFI_ST_FAILURE; } - ret = boottime->start_image(handle, NULL, NULL); + ret = boottime->start_image(handle, &exit_data_size, &exit_data); if (ret != EFI_UNSUPPORTED) { efi_st_error("Wrong return value from application\n"); return EFI_ST_FAILURE; } + if (!exit_data || exit_data_size != sizeof(expected_text) || + efi_st_memcmp(exit_data, expected_text, sizeof(expected_text))) { + efi_st_error("Incorrect exit data\n"); + return EFI_ST_FAILURE; + } + ret = boottime->free_pool(exit_data); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to free exit data\n"); + return EFI_ST_FAILURE; + } return EFI_ST_SUCCESS; } diff --git a/lib/uuid.c b/lib/uuid.c index fa20ee39fc..2d4d6ef7e4 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -238,6 +238,8 @@ void gen_rand_uuid(unsigned char *uuid_bin) unsigned int *ptr = (unsigned int *)&uuid; int i; + srand(get_ticks() + rand()); + /* Set all fields randomly */ for (i = 0; i < sizeof(struct uuid) / sizeof(*ptr); i++) *(ptr + i) = cpu_to_be32(rand()); |