summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub/files/CVE-2022-28736.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-bsp/grub/files/CVE-2022-28736.patch')
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2022-28736.patch275
1 files changed, 275 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2022-28736.patch b/meta/recipes-bsp/grub/files/CVE-2022-28736.patch
new file mode 100644
index 0000000000..4fc9fdaf05
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2022-28736.patch
@@ -0,0 +1,275 @@
1From 431a111c60095fc973d83fe9209f26f29ce78784 Mon Sep 17 00:00:00 2001
2From: Hitendra Prajapati <hprajapati@mvista.com>
3Date: Mon, 1 Aug 2022 11:17:17 +0530
4Subject: [PATCH] CVE-2022-28736
5
6Upstream-Status: Backport [https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=04c86e0bb7b58fc2f913f798cdb18934933e532d]
7CVE: CVE-2022-28736
8Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
9
10loader/efi/chainloader: Use grub_loader_set_ex()
11
12This ports the EFI chainloader to use grub_loader_set_ex() in order to fix
13a use-after-free bug that occurs when grub_cmd_chainloader() is executed
14more than once before a boot attempt is performed.
15
16Fixes: CVE-2022-28736
17
18Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
19Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
20---
21 grub-core/commands/boot.c | 66 ++++++++++++++++++++++++++----
22 grub-core/loader/efi/chainloader.c | 46 +++++++++++----------
23 include/grub/loader.h | 5 +++
24 3 files changed, 87 insertions(+), 30 deletions(-)
25
26diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
27index bbca81e..6151478 100644
28--- a/grub-core/commands/boot.c
29+++ b/grub-core/commands/boot.c
30@@ -27,10 +27,20 @@
31
32 GRUB_MOD_LICENSE ("GPLv3+");
33
34-static grub_err_t (*grub_loader_boot_func) (void);
35-static grub_err_t (*grub_loader_unload_func) (void);
36+static grub_err_t (*grub_loader_boot_func) (void *context);
37+static grub_err_t (*grub_loader_unload_func) (void *context);
38+static void *grub_loader_context;
39 static int grub_loader_flags;
40
41+struct grub_simple_loader_hooks
42+{
43+ grub_err_t (*boot) (void);
44+ grub_err_t (*unload) (void);
45+};
46+
47+/* Don't heap allocate this to avoid making grub_loader_set() fallible. */
48+static struct grub_simple_loader_hooks simple_loader_hooks;
49+
50 struct grub_preboot
51 {
52 grub_err_t (*preboot_func) (int);
53@@ -44,6 +54,29 @@ static int grub_loader_loaded;
54 static struct grub_preboot *preboots_head = 0,
55 *preboots_tail = 0;
56
57+static grub_err_t
58+grub_simple_boot_hook (void *context)
59+{
60+ struct grub_simple_loader_hooks *hooks;
61+
62+ hooks = (struct grub_simple_loader_hooks *) context;
63+ return hooks->boot ();
64+}
65+
66+static grub_err_t
67+grub_simple_unload_hook (void *context)
68+{
69+ struct grub_simple_loader_hooks *hooks;
70+ grub_err_t ret;
71+
72+ hooks = (struct grub_simple_loader_hooks *) context;
73+
74+ ret = hooks->unload ();
75+ grub_memset (hooks, 0, sizeof (*hooks));
76+
77+ return ret;
78+}
79+
80 int
81 grub_loader_is_loaded (void)
82 {
83@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
84 }
85
86 void
87-grub_loader_set (grub_err_t (*boot) (void),
88- grub_err_t (*unload) (void),
89- int flags)
90+grub_loader_set_ex (grub_err_t (*boot) (void *context),
91+ grub_err_t (*unload) (void *context),
92+ void *context,
93+ int flags)
94 {
95 if (grub_loader_loaded && grub_loader_unload_func)
96- grub_loader_unload_func ();
97+ grub_loader_unload_func (grub_loader_context);
98
99 grub_loader_boot_func = boot;
100 grub_loader_unload_func = unload;
101+ grub_loader_context = context;
102 grub_loader_flags = flags;
103
104 grub_loader_loaded = 1;
105 }
106
107+void
108+grub_loader_set (grub_err_t (*boot) (void),
109+ grub_err_t (*unload) (void),
110+ int flags)
111+{
112+ grub_loader_set_ex (grub_simple_boot_hook,
113+ grub_simple_unload_hook,
114+ &simple_loader_hooks,
115+ flags);
116+
117+ simple_loader_hooks.boot = boot;
118+ simple_loader_hooks.unload = unload;
119+}
120+
121 void
122 grub_loader_unset(void)
123 {
124 if (grub_loader_loaded && grub_loader_unload_func)
125- grub_loader_unload_func ();
126+ grub_loader_unload_func (grub_loader_context);
127
128 grub_loader_boot_func = 0;
129 grub_loader_unload_func = 0;
130+ grub_loader_context = 0;
131
132 grub_loader_loaded = 0;
133 }
134@@ -158,7 +208,7 @@ grub_loader_boot (void)
135 return err;
136 }
137 }
138- err = (grub_loader_boot_func) ();
139+ err = (grub_loader_boot_func) (grub_loader_context);
140
141 for (cur = preboots_tail; cur; cur = cur->prev)
142 if (! err)
143diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
144index a8d7b91..93a028a 100644
145--- a/grub-core/loader/efi/chainloader.c
146+++ b/grub-core/loader/efi/chainloader.c
147@@ -44,33 +44,28 @@ GRUB_MOD_LICENSE ("GPLv3+");
148
149 static grub_dl_t my_mod;
150
151-static grub_efi_physical_address_t address;
152-static grub_efi_uintn_t pages;
153-static grub_efi_device_path_t *file_path;
154-static grub_efi_handle_t image_handle;
155-static grub_efi_char16_t *cmdline;
156-
157 static grub_err_t
158-grub_chainloader_unload (void)
159+grub_chainloader_unload (void *context)
160 {
161+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
162+ grub_efi_loaded_image_t *loaded_image;
163 grub_efi_boot_services_t *b;
164
165+ loaded_image = grub_efi_get_loaded_image (image_handle);
166+ if (loaded_image != NULL)
167+ grub_free (loaded_image->load_options);
168+
169 b = grub_efi_system_table->boot_services;
170 efi_call_1 (b->unload_image, image_handle);
171- efi_call_2 (b->free_pages, address, pages);
172-
173- grub_free (file_path);
174- grub_free (cmdline);
175- cmdline = 0;
176- file_path = 0;
177
178 grub_dl_unref (my_mod);
179 return GRUB_ERR_NONE;
180 }
181
182 static grub_err_t
183-grub_chainloader_boot (void)
184+grub_chainloader_boot (void *context)
185 {
186+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
187 grub_efi_boot_services_t *b;
188 grub_efi_status_t status;
189 grub_efi_uintn_t exit_data_size;
190@@ -139,7 +134,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
191 char *dir_start;
192 char *dir_end;
193 grub_size_t size;
194- grub_efi_device_path_t *d;
195+ grub_efi_device_path_t *d, *file_path;
196
197 dir_start = grub_strchr (filename, ')');
198 if (! dir_start)
199@@ -215,11 +210,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
200 grub_efi_status_t status;
201 grub_efi_boot_services_t *b;
202 grub_device_t dev = 0;
203- grub_efi_device_path_t *dp = 0;
204+ grub_efi_device_path_t *dp = NULL, *file_path = NULL;
205 grub_efi_loaded_image_t *loaded_image;
206 char *filename;
207 void *boot_image = 0;
208 grub_efi_handle_t dev_handle = 0;
209+ grub_efi_physical_address_t address = 0;
210+ grub_efi_uintn_t pages = 0;
211+ grub_efi_char16_t *cmdline = NULL;
212+ grub_efi_handle_t image_handle = NULL;
213
214 if (argc == 0)
215 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
216@@ -227,11 +226,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
217
218 grub_dl_ref (my_mod);
219
220- /* Initialize some global variables. */
221- address = 0;
222- image_handle = 0;
223- file_path = 0;
224-
225 b = grub_efi_system_table->boot_services;
226
227 file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
228@@ -401,7 +395,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
229 grub_file_close (file);
230 grub_device_close (dev);
231
232- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
233+ /* We're finished with the source image buffer and file path now. */
234+ efi_call_2 (b->free_pages, address, pages);
235+ grub_free (file_path);
236+
237+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
238 return 0;
239
240 fail:
241@@ -412,11 +410,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
242 if (file)
243 grub_file_close (file);
244
245+ grub_free (cmdline);
246 grub_free (file_path);
247
248 if (address)
249 efi_call_2 (b->free_pages, address, pages);
250
251+ if (image_handle != NULL)
252+ efi_call_1 (b->unload_image, image_handle);
253+
254 grub_dl_unref (my_mod);
255
256 return grub_errno;
257diff --git a/include/grub/loader.h b/include/grub/loader.h
258index 7f82a49..3071a50 100644
259--- a/include/grub/loader.h
260+++ b/include/grub/loader.h
261@@ -39,6 +39,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
262 grub_err_t (*unload) (void),
263 int flags);
264
265+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *context),
266+ grub_err_t (*unload) (void *context),
267+ void *context,
268+ int flags);
269+
270 /* Unset current loader, if any. */
271 void EXPORT_FUNC (grub_loader_unset) (void);
272
273--
2742.25.1
275