aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-12-29 10:23:58 -0500
committerTom Rini <trini@konsulko.com>2020-12-29 10:23:58 -0500
commit21e1cae7902e6a9b1d7cf47cf4764e6fe7d3452a (patch)
treeda2c201eb28835141b1652216e57cb36811bd24d
parentab865a8ee5c1a069f72a171270c02c99ccda7bfa (diff)
parentbe48b0f453a3903e924a4f1790f134b9b36e5fa8 (diff)
downloadu-boot-WIP/29Dec2020.zip
u-boot-WIP/29Dec2020.tar.gz
u-boot-WIP/29Dec2020.tar.bz2
Merge tag 'efi-2021-01-rc5-2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efiWIP/29Dec2020
Pull request for UEFI sub-system for efi-2021-01-rc5 (2) The following errors in the UEFI sub-system are fixed: * use after free in efi_exit() * invalid free when using the boot manager * pressing escape key once not recognized
-rw-r--r--include/efi_loader.h8
-rw-r--r--lib/efi_loader/efi_bootmgr.c2
-rw-r--r--lib/efi_loader/efi_boottime.c23
-rw-r--r--lib/efi_loader/efi_console.c12
4 files changed, 33 insertions, 12 deletions
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 3c68b85..0fc2255 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -297,15 +297,17 @@ enum efi_image_auth_status {
* @exit_status: exit status passed to Exit()
* @exit_data_size: exit data size passed to Exit()
* @exit_data: exit data passed to Exit()
- * @exit_jmp: long jump buffer for returning form started image
+ * @exit_jmp: long jump buffer for returning from started image
* @entry: entry address of the relocated image
+ * @image_type: indicates if the image is an applicition or a driver
+ * @auth_status: indicates if the image is authenticated
*/
struct efi_loaded_image_obj {
struct efi_object header;
- efi_status_t exit_status;
+ efi_status_t *exit_status;
efi_uintn_t *exit_data_size;
u16 **exit_data;
- struct jmp_buf_data exit_jmp;
+ struct jmp_buf_data *exit_jmp;
EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
struct efi_system_table *st);
u16 image_type;
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index 61dc72a..d3be2f9 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -275,7 +275,7 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
memcpy(*load_options, lo.optional_data, size);
ret = efi_set_load_options(*handle, size, *load_options);
} else {
- load_options = NULL;
+ *load_options = NULL;
}
error:
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 246b59d..a89bdb3 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -271,8 +271,8 @@ efi_status_t is_valid_tpl(efi_uintn_t tpl)
* efi_signal_event() - signal an EFI event
* @event: event to signal
*
- * This function signals an event. If the event belongs to an event group all
- * events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL
+ * This function signals an event. If the event belongs to an event group, all
+ * events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL,
* their notification function is queued.
*
* For the SignalEvent service see efi_signal_event_ext.
@@ -2000,7 +2000,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
}
if (!efi_st_keep_devices) {
- if IS_ENABLED(CONFIG_USB_DEVICE)
+ if (IS_ENABLED(CONFIG_USB_DEVICE))
udc_disconnect();
board_quiesce_devices();
dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
@@ -2899,6 +2899,8 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
efi_status_t ret;
void *info;
efi_handle_t parent_image = current_image;
+ efi_status_t exit_status;
+ struct jmp_buf_data exit_jmp;
EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
@@ -2920,9 +2922,11 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
image_obj->exit_data_size = exit_data_size;
image_obj->exit_data = exit_data;
+ image_obj->exit_status = &exit_status;
+ image_obj->exit_jmp = &exit_jmp;
/* call the image! */
- if (setjmp(&image_obj->exit_jmp)) {
+ if (setjmp(&exit_jmp)) {
/*
* We called the entry point of the child image with EFI_CALL
* in the lines below. The child image called the Exit() boot
@@ -2944,10 +2948,10 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
*/
assert(__efi_entry_check());
EFI_PRINT("%lu returned by started image\n",
- (unsigned long)((uintptr_t)image_obj->exit_status &
+ (unsigned long)((uintptr_t)exit_status &
~EFI_ERROR_MASK));
current_image = parent_image;
- return EFI_EXIT(image_obj->exit_status);
+ return EFI_EXIT(exit_status);
}
current_image = image_handle;
@@ -3130,6 +3134,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
struct efi_loaded_image *loaded_image_protocol;
struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle;
+ struct jmp_buf_data *exit_jmp;
EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
exit_data_size, exit_data);
@@ -3171,6 +3176,9 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
if (ret != EFI_SUCCESS)
EFI_PRINT("%s: out of memory\n", __func__);
}
+ /* efi_delete_image() frees image_obj. Copy before the call. */
+ exit_jmp = image_obj->exit_jmp;
+ *image_obj->exit_status = exit_status;
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION ||
exit_status != EFI_SUCCESS)
efi_delete_image(image_obj, loaded_image_protocol);
@@ -3184,8 +3192,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
*/
efi_restore_gd();
- image_obj->exit_status = exit_status;
- longjmp(&image_obj->exit_jmp, 1);
+ longjmp(exit_jmp, 1);
panic("EFI application exited");
out:
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 011acca..7051095 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -14,6 +14,7 @@
#include <env.h>
#include <stdio_dev.h>
#include <video_console.h>
+#include <linux/delay.h>
#define EFI_COUT_MODE_2 2
#define EFI_MAX_COUT_MODE 3
@@ -689,6 +690,17 @@ static efi_status_t efi_cin_read_key(struct efi_key_data *key)
switch (ch) {
case 0x1b:
/*
+ * If a second key is received within 10 ms, assume that we are
+ * dealing with an escape sequence. Otherwise consider this the
+ * escape key being hit. 10 ms is long enough to work fine at
+ * 1200 baud and above.
+ */
+ udelay(10000);
+ if (!tstc()) {
+ pressed_key.scan_code = 23;
+ break;
+ }
+ /*
* Xterm Control Sequences
* https://www.xfree86.org/4.8.0/ctlseqs.html
*/