summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_boottime.c
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2020-12-29 01:24:40 +0300
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2020-12-31 16:33:07 +0300
commitf8212f09702f802ffab42769133e3114bd6e5e77 (patch)
tree2ab92da9a641ed1e80ac524aba083faac7baac82 /lib/efi_loader/efi_boottime.c
parent0ce3fb55e0be286f1f7686aeb452ee77100a2493 (diff)
downloadu-boot-f8212f09702f802ffab42769133e3114bd6e5e77.tar.xz
efi_loader: use after free in efi_exit()
Do not use data from the loaded image object after deleting it. Fixes: 126a43f15b36 ("efi_loader: unload applications upon Exit()") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib/efi_loader/efi_boottime.c')
-rw-r--r--lib/efi_loader/efi_boottime.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index a08630eef9..b799fcf1f2 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2978,6 +2978,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);
@@ -2999,9 +3001,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
@@ -3023,10 +3027,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;
@@ -3209,6 +3213,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);
@@ -3250,6 +3255,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);
@@ -3263,8 +3271,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: