If an application or driver started via StartImage returns without
calling Exit, StartImage has to call Exit. This is mandated by the
UEFI spec and we do the same in efi_do_enter().

The patch looks bigger than it is. To avoid a forward declaration function
efi_exit() was moved up. Only one (void*) was replaced by (void *).
The only real change is in efi_start_image().

Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de>
---
Without this patch on Ubuntu 16.04 a crash could be observed in
efi_selftest_startimage_return.c. With the patch it is gone.
But this could be coincidence.
---
 lib/efi_loader/efi_boottime.c | 99 ++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 48 deletions(-)

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 0ac5b44..62a24bf 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1519,6 +1519,54 @@ failure:
 }
 
 /*
+ * Leave an EFI application or driver.
+ *
+ * This function implements the Exit service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @image_handle       handle of the application or driver that is exiting
+ * @exit_status                status code
+ * @exit_data_size     size of the buffer in bytes
+ * @exit_data          buffer with data describing an error
+ * @return             status code
+ */
+static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
+                       efi_status_t exit_status, unsigned long exit_data_size,
+                       int16_t *exit_data)
+{
+       /*
+        * We require that the handle points to the original loaded
+        * image protocol interface.
+        *
+        * For getting the longjmp address this is safer than locating
+        * the protocol because the protocol may have been reinstalled
+        * pointing to another memory location.
+        *
+        * TODO: We should call the unload procedure of the loaded
+        *       image protocol.
+        */
+       struct efi_loaded_image *loaded_image_info = (void *)image_handle;
+
+       EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
+                 exit_data_size, exit_data);
+
+       /* Make sure entry/exit counts for EFI world cross-overs match */
+       EFI_EXIT(exit_status);
+
+       /*
+        * But longjmp out with the U-Boot gd, not the application's, as
+        * the other end is a setjmp call inside EFI context.
+        */
+       efi_restore_gd();
+
+       loaded_image_info->exit_status = exit_status;
+       longjmp(&loaded_image_info->exit_jmp, 1);
+
+       panic("EFI application exited");
+}
+
+/*
  * Call the entry point of an image.
  *
  * This function implements the StartImage service.
@@ -1575,59 +1623,14 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t 
image_handle,
 
        ret = EFI_CALL(entry(image_handle, &systab));
 
+       /* Clean up the image */
+       ret = EFI_CALL(efi_exit(image_handle, ret, 0, NULL));
+
        /* Should usually never get here */
        return EFI_EXIT(ret);
 }
 
 /*
- * Leave an EFI application or driver.
- *
- * This function implements the Exit service.
- * See the Unified Extensible Firmware Interface (UEFI) specification
- * for details.
- *
- * @image_handle       handle of the application or driver that is exiting
- * @exit_status                status code
- * @exit_data_size     size of the buffer in bytes
- * @exit_data          buffer with data describing an error
- * @return             status code
- */
-static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
-                       efi_status_t exit_status, unsigned long exit_data_size,
-                       int16_t *exit_data)
-{
-       /*
-        * We require that the handle points to the original loaded
-        * image protocol interface.
-        *
-        * For getting the longjmp address this is safer than locating
-        * the protocol because the protocol may have been reinstalled
-        * pointing to another memory location.
-        *
-        * TODO: We should call the unload procedure of the loaded
-        *       image protocol.
-        */
-       struct efi_loaded_image *loaded_image_info = (void*)image_handle;
-
-       EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
-                 exit_data_size, exit_data);
-
-       /* Make sure entry/exit counts for EFI world cross-overs match */
-       EFI_EXIT(exit_status);
-
-       /*
-        * But longjmp out with the U-Boot gd, not the application's, as
-        * the other end is a setjmp call inside EFI context.
-        */
-       efi_restore_gd();
-
-       loaded_image_info->exit_status = exit_status;
-       longjmp(&loaded_image_info->exit_jmp, 1);
-
-       panic("EFI application exited");
-}
-
-/*
  * Unload an EFI image.
  *
  * This function implements the UnloadImage service.
-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to