1*4882a593SmuzhiyunFrom 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Chris Coulson <chris.coulson@canonical.com>
3*4882a593SmuzhiyunDate: Tue, 5 Apr 2022 10:02:04 +0100
4*4882a593SmuzhiyunSubject: [PATCH] loader/efi/chainloader: Simplify the loader state
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunThe chainloader command retains the source buffer and device path passed
7*4882a593Smuzhiyunto LoadImage(), requiring the unload hook passed to grub_loader_set() to
8*4882a593Smuzhiyunfree them. It isn't required to retain this state though - they aren't
9*4882a593Smuzhiyunrequired by StartImage() or anything else in the boot hook, so clean them
10*4882a593Smuzhiyunup before grub_cmd_chainloader() finishes.
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunSigned-off-by: Chris Coulson <chris.coulson@canonical.com>
13*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunUpstream-Status: Backport
16*4882a593Smuzhiyun
17*4882a593SmuzhiyunReference to upstream patch:
18*4882a593Smuzhiyunhttps://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
19*4882a593Smuzhiyun
20*4882a593SmuzhiyunSigned-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
21*4882a593Smuzhiyun---
22*4882a593Smuzhiyun grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
23*4882a593Smuzhiyun 1 file changed, 21 insertions(+), 17 deletions(-)
24*4882a593Smuzhiyun
25*4882a593Smuzhiyundiff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
26*4882a593Smuzhiyunindex 2bd80f4db..d1602c89b 100644
27*4882a593Smuzhiyun--- a/grub-core/loader/efi/chainloader.c
28*4882a593Smuzhiyun+++ b/grub-core/loader/efi/chainloader.c
29*4882a593Smuzhiyun@@ -44,25 +44,20 @@ GRUB_MOD_LICENSE ("GPLv3+");
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun static grub_dl_t my_mod;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun-static grub_efi_physical_address_t address;
34*4882a593Smuzhiyun-static grub_efi_uintn_t pages;
35*4882a593Smuzhiyun-static grub_efi_device_path_t *file_path;
36*4882a593Smuzhiyun static grub_efi_handle_t image_handle;
37*4882a593Smuzhiyun-static grub_efi_char16_t *cmdline;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun static grub_err_t
40*4882a593Smuzhiyun grub_chainloader_unload (void)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun+  grub_efi_loaded_image_t *loaded_image;
43*4882a593Smuzhiyun   grub_efi_boot_services_t *b;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun+  loaded_image = grub_efi_get_loaded_image (image_handle);
46*4882a593Smuzhiyun+  if (loaded_image != NULL)
47*4882a593Smuzhiyun+    grub_free (loaded_image->load_options);
48*4882a593Smuzhiyun+
49*4882a593Smuzhiyun   b = grub_efi_system_table->boot_services;
50*4882a593Smuzhiyun   efi_call_1 (b->unload_image, image_handle);
51*4882a593Smuzhiyun-  efi_call_2 (b->free_pages, address, pages);
52*4882a593Smuzhiyun-
53*4882a593Smuzhiyun-  grub_free (file_path);
54*4882a593Smuzhiyun-  grub_free (cmdline);
55*4882a593Smuzhiyun-  cmdline = 0;
56*4882a593Smuzhiyun-  file_path = 0;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun   grub_dl_unref (my_mod);
59*4882a593Smuzhiyun   return GRUB_ERR_NONE;
60*4882a593Smuzhiyun@@ -140,7 +135,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
61*4882a593Smuzhiyun   char *dir_start;
62*4882a593Smuzhiyun   char *dir_end;
63*4882a593Smuzhiyun   grub_size_t size;
64*4882a593Smuzhiyun-  grub_efi_device_path_t *d;
65*4882a593Smuzhiyun+  grub_efi_device_path_t *d, *file_path;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun   dir_start = grub_strchr (filename, ')');
68*4882a593Smuzhiyun   if (! dir_start)
69*4882a593Smuzhiyun@@ -222,11 +217,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
70*4882a593Smuzhiyun   grub_efi_status_t status;
71*4882a593Smuzhiyun   grub_efi_boot_services_t *b;
72*4882a593Smuzhiyun   grub_device_t dev = 0;
73*4882a593Smuzhiyun-  grub_efi_device_path_t *dp = 0;
74*4882a593Smuzhiyun+  grub_efi_device_path_t *dp = NULL, *file_path = NULL;
75*4882a593Smuzhiyun   grub_efi_loaded_image_t *loaded_image;
76*4882a593Smuzhiyun   char *filename;
77*4882a593Smuzhiyun   void *boot_image = 0;
78*4882a593Smuzhiyun   grub_efi_handle_t dev_handle = 0;
79*4882a593Smuzhiyun+  grub_efi_physical_address_t address = 0;
80*4882a593Smuzhiyun+  grub_efi_uintn_t pages = 0;
81*4882a593Smuzhiyun+  grub_efi_char16_t *cmdline = NULL;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun   if (argc == 0)
84*4882a593Smuzhiyun     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
85*4882a593Smuzhiyun@@ -234,11 +232,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun   grub_dl_ref (my_mod);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun-  /* Initialize some global variables.  */
90*4882a593Smuzhiyun-  address = 0;
91*4882a593Smuzhiyun-  image_handle = 0;
92*4882a593Smuzhiyun-  file_path = 0;
93*4882a593Smuzhiyun-
94*4882a593Smuzhiyun   b = grub_efi_system_table->boot_services;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun   file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
97*4882a593Smuzhiyun@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
98*4882a593Smuzhiyun   grub_file_close (file);
99*4882a593Smuzhiyun   grub_device_close (dev);
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun+  /* We're finished with the source image buffer and file path now. */
102*4882a593Smuzhiyun+  efi_call_2 (b->free_pages, address, pages);
103*4882a593Smuzhiyun+  grub_free (file_path);
104*4882a593Smuzhiyun+
105*4882a593Smuzhiyun   grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
106*4882a593Smuzhiyun   return 0;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
109*4882a593Smuzhiyun   if (file)
110*4882a593Smuzhiyun     grub_file_close (file);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun+  grub_free (cmdline);
113*4882a593Smuzhiyun   grub_free (file_path);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun   if (address)
116*4882a593Smuzhiyun     efi_call_2 (b->free_pages, address, pages);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun+  if (image_handle != NULL)
119*4882a593Smuzhiyun+    {
120*4882a593Smuzhiyun+      efi_call_1 (b->unload_image, image_handle);
121*4882a593Smuzhiyun+      image_handle = NULL;
122*4882a593Smuzhiyun+    }
123*4882a593Smuzhiyun+
124*4882a593Smuzhiyun   grub_dl_unref (my_mod);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun   return grub_errno;
127*4882a593Smuzhiyun--
128*4882a593Smuzhiyun2.34.1
129*4882a593Smuzhiyun
130