diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2020-12-28 23:24:40 +0100 |
---|---|---|
committer | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2020-12-31 14:33:07 +0100 |
commit | f8212f09702f802ffab42769133e3114bd6e5e77 (patch) | |
tree | 2ab92da9a641ed1e80ac524aba083faac7baac82 /lib | |
parent | 0ce3fb55e0be286f1f7686aeb452ee77100a2493 (diff) | |
download | u-boot-f8212f09702f802ffab42769133e3114bd6e5e77.zip u-boot-f8212f09702f802ffab42769133e3114bd6e5e77.tar.gz u-boot-f8212f09702f802ffab42769133e3114bd6e5e77.tar.bz2 |
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')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index a08630e..b799fcf 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: |