mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
efi_loader: use after free in efi_exit()
Do not use data from the loaded image object after deleting it.
Fixes: 126a43f15b
("efi_loader: unload applications upon Exit()")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
0ce3fb55e0
commit
f8212f0970
2 changed files with 14 additions and 7 deletions
|
@ -311,10 +311,10 @@ enum efi_image_auth_status {
|
|||
*/
|
||||
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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue