summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub
diff options
context:
space:
mode:
authorXiangyu Chen <xiangyu.chen@windriver.com>2022-12-07 11:42:54 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-08 10:48:36 +0000
commit7967e2aa0c47686f63894f7501e3a36a1757f8bc (patch)
tree6beea3d729b485a9e923007f8f7c59d013ea8b4d /meta/recipes-bsp/grub
parentcc1c4506bade3b028294efe64d5862ba9be1ad4c (diff)
downloadpoky-7967e2aa0c47686f63894f7501e3a36a1757f8bc.tar.gz
grub: backport patches to fix CVE-2022-28736
(From OE-Core rev: 278e1a0f679be813553b014544314041502a586a) Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-bsp/grub')
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch86
-rw-r--r--meta/recipes-bsp/grub/files/commands-boot-Add-API-to-pass-context-to-loader.patch168
-rw-r--r--meta/recipes-bsp/grub/files/loader-efi-chainloader-Simplify-the-loader-state.patch129
-rw-r--r--meta/recipes-bsp/grub/grub2.inc3
4 files changed, 386 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/meta/recipes-bsp/grub/files/CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch
new file mode 100644
index 0000000000..5741e53f42
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch
@@ -0,0 +1,86 @@
1From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001
2From: Chris Coulson <chris.coulson@canonical.com>
3Date: Tue, 5 Apr 2022 11:48:58 +0100
4Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex()
5
6This ports the EFI chainloader to use grub_loader_set_ex() in order to fix
7a use-after-free bug that occurs when grub_cmd_chainloader() is executed
8more than once before a boot attempt is performed.
9
10Fixes: CVE-2022-28736
11
12Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
13Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
14
15Upstream-Status: Backport
16CVE: CVE-2022-28736
17
18Reference to upstream patch:
19https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d
20
21Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
22---
23 grub-core/loader/efi/chainloader.c | 16 +++++++---------
24 1 file changed, 7 insertions(+), 9 deletions(-)
25
26diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
27index d1602c89b..7557eb269 100644
28--- a/grub-core/loader/efi/chainloader.c
29+++ b/grub-core/loader/efi/chainloader.c
30@@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
31
32 static grub_dl_t my_mod;
33
34-static grub_efi_handle_t image_handle;
35-
36 static grub_err_t
37-grub_chainloader_unload (void)
38+grub_chainloader_unload (void *context)
39 {
40+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
41 grub_efi_loaded_image_t *loaded_image;
42 grub_efi_boot_services_t *b;
43
44@@ -64,8 +63,9 @@ grub_chainloader_unload (void)
45 }
46
47 static grub_err_t
48-grub_chainloader_boot (void)
49+grub_chainloader_boot (void *context)
50 {
51+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
52 grub_efi_boot_services_t *b;
53 grub_efi_status_t status;
54 grub_efi_uintn_t exit_data_size;
55@@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
56 grub_efi_physical_address_t address = 0;
57 grub_efi_uintn_t pages = 0;
58 grub_efi_char16_t *cmdline = NULL;
59+ grub_efi_handle_t image_handle = NULL;
60
61 if (argc == 0)
62 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
63@@ -405,7 +406,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
64 efi_call_2 (b->free_pages, address, pages);
65 grub_free (file_path);
66
67- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
68+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
69 return 0;
70
71 fail:
72@@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
73 efi_call_2 (b->free_pages, address, pages);
74
75 if (image_handle != NULL)
76- {
77- efi_call_1 (b->unload_image, image_handle);
78- image_handle = NULL;
79- }
80+ efi_call_1 (b->unload_image, image_handle);
81
82 grub_dl_unref (my_mod);
83
84--
852.34.1
86
diff --git a/meta/recipes-bsp/grub/files/commands-boot-Add-API-to-pass-context-to-loader.patch b/meta/recipes-bsp/grub/files/commands-boot-Add-API-to-pass-context-to-loader.patch
new file mode 100644
index 0000000000..a2c0530f04
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/commands-boot-Add-API-to-pass-context-to-loader.patch
@@ -0,0 +1,168 @@
1From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001
2From: Chris Coulson <chris.coulson@canonical.com>
3Date: Tue, 5 Apr 2022 10:58:28 +0100
4Subject: [PATCH] commands/boot: Add API to pass context to loader
5
6Loaders rely on global variables for saving context which is consumed
7in the boot hook and freed in the unload hook. In the case where a loader
8command is executed twice, calling grub_loader_set() a second time executes
9the unload hook, but in some cases this runs when the loader's global
10context has already been updated, resulting in the updated context being
11freed and potential use-after-free bugs when the boot hook is subsequently
12called.
13
14This adds a new API, grub_loader_set_ex(), which allows a loader to specify
15context that is passed to its boot and unload hooks. This is an alternative
16to requiring that loaders call grub_loader_unset() before mutating their
17global context.
18
19Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
20Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
21
22Upstream-Status: Backport
23
24Reference to upstream patch:
25https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e
26
27Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
28---
29 grub-core/commands/boot.c | 66 ++++++++++++++++++++++++++++++++++-----
30 include/grub/loader.h | 5 +++
31 2 files changed, 63 insertions(+), 8 deletions(-)
32
33diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
34index bbca81e94..61514788e 100644
35--- a/grub-core/commands/boot.c
36+++ b/grub-core/commands/boot.c
37@@ -27,10 +27,20 @@
38
39 GRUB_MOD_LICENSE ("GPLv3+");
40
41-static grub_err_t (*grub_loader_boot_func) (void);
42-static grub_err_t (*grub_loader_unload_func) (void);
43+static grub_err_t (*grub_loader_boot_func) (void *context);
44+static grub_err_t (*grub_loader_unload_func) (void *context);
45+static void *grub_loader_context;
46 static int grub_loader_flags;
47
48+struct grub_simple_loader_hooks
49+{
50+ grub_err_t (*boot) (void);
51+ grub_err_t (*unload) (void);
52+};
53+
54+/* Don't heap allocate this to avoid making grub_loader_set() fallible. */
55+static struct grub_simple_loader_hooks simple_loader_hooks;
56+
57 struct grub_preboot
58 {
59 grub_err_t (*preboot_func) (int);
60@@ -44,6 +54,29 @@ static int grub_loader_loaded;
61 static struct grub_preboot *preboots_head = 0,
62 *preboots_tail = 0;
63
64+static grub_err_t
65+grub_simple_boot_hook (void *context)
66+{
67+ struct grub_simple_loader_hooks *hooks;
68+
69+ hooks = (struct grub_simple_loader_hooks *) context;
70+ return hooks->boot ();
71+}
72+
73+static grub_err_t
74+grub_simple_unload_hook (void *context)
75+{
76+ struct grub_simple_loader_hooks *hooks;
77+ grub_err_t ret;
78+
79+ hooks = (struct grub_simple_loader_hooks *) context;
80+
81+ ret = hooks->unload ();
82+ grub_memset (hooks, 0, sizeof (*hooks));
83+
84+ return ret;
85+}
86+
87 int
88 grub_loader_is_loaded (void)
89 {
90@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
91 }
92
93 void
94-grub_loader_set (grub_err_t (*boot) (void),
95- grub_err_t (*unload) (void),
96- int flags)
97+grub_loader_set_ex (grub_err_t (*boot) (void *context),
98+ grub_err_t (*unload) (void *context),
99+ void *context,
100+ int flags)
101 {
102 if (grub_loader_loaded && grub_loader_unload_func)
103- grub_loader_unload_func ();
104+ grub_loader_unload_func (grub_loader_context);
105
106 grub_loader_boot_func = boot;
107 grub_loader_unload_func = unload;
108+ grub_loader_context = context;
109 grub_loader_flags = flags;
110
111 grub_loader_loaded = 1;
112 }
113
114+void
115+grub_loader_set (grub_err_t (*boot) (void),
116+ grub_err_t (*unload) (void),
117+ int flags)
118+{
119+ grub_loader_set_ex (grub_simple_boot_hook,
120+ grub_simple_unload_hook,
121+ &simple_loader_hooks,
122+ flags);
123+
124+ simple_loader_hooks.boot = boot;
125+ simple_loader_hooks.unload = unload;
126+}
127+
128 void
129 grub_loader_unset(void)
130 {
131 if (grub_loader_loaded && grub_loader_unload_func)
132- grub_loader_unload_func ();
133+ grub_loader_unload_func (grub_loader_context);
134
135 grub_loader_boot_func = 0;
136 grub_loader_unload_func = 0;
137+ grub_loader_context = 0;
138
139 grub_loader_loaded = 0;
140 }
141@@ -158,7 +208,7 @@ grub_loader_boot (void)
142 return err;
143 }
144 }
145- err = (grub_loader_boot_func) ();
146+ err = (grub_loader_boot_func) (grub_loader_context);
147
148 for (cur = preboots_tail; cur; cur = cur->prev)
149 if (! err)
150diff --git a/include/grub/loader.h b/include/grub/loader.h
151index b20864282..97f231054 100644
152--- a/include/grub/loader.h
153+++ b/include/grub/loader.h
154@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
155 grub_err_t (*unload) (void),
156 int flags);
157
158+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *context),
159+ grub_err_t (*unload) (void *context),
160+ void *context,
161+ int flags);
162+
163 /* Unset current loader, if any. */
164 void EXPORT_FUNC (grub_loader_unset) (void);
165
166--
1672.34.1
168
diff --git a/meta/recipes-bsp/grub/files/loader-efi-chainloader-Simplify-the-loader-state.patch b/meta/recipes-bsp/grub/files/loader-efi-chainloader-Simplify-the-loader-state.patch
new file mode 100644
index 0000000000..a43025d425
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/loader-efi-chainloader-Simplify-the-loader-state.patch
@@ -0,0 +1,129 @@
1From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
2From: Chris Coulson <chris.coulson@canonical.com>
3Date: Tue, 5 Apr 2022 10:02:04 +0100
4Subject: [PATCH] loader/efi/chainloader: Simplify the loader state
5
6The chainloader command retains the source buffer and device path passed
7to LoadImage(), requiring the unload hook passed to grub_loader_set() to
8free them. It isn't required to retain this state though - they aren't
9required by StartImage() or anything else in the boot hook, so clean them
10up before grub_cmd_chainloader() finishes.
11
12Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
13Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
14
15Upstream-Status: Backport
16
17Reference to upstream patch:
18https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
19
20Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
21---
22 grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
23 1 file changed, 21 insertions(+), 17 deletions(-)
24
25diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
26index 2bd80f4db..d1602c89b 100644
27--- a/grub-core/loader/efi/chainloader.c
28+++ b/grub-core/loader/efi/chainloader.c
29@@ -44,25 +44,20 @@ GRUB_MOD_LICENSE ("GPLv3+");
30
31 static grub_dl_t my_mod;
32
33-static grub_efi_physical_address_t address;
34-static grub_efi_uintn_t pages;
35-static grub_efi_device_path_t *file_path;
36 static grub_efi_handle_t image_handle;
37-static grub_efi_char16_t *cmdline;
38
39 static grub_err_t
40 grub_chainloader_unload (void)
41 {
42+ grub_efi_loaded_image_t *loaded_image;
43 grub_efi_boot_services_t *b;
44
45+ loaded_image = grub_efi_get_loaded_image (image_handle);
46+ if (loaded_image != NULL)
47+ grub_free (loaded_image->load_options);
48+
49 b = grub_efi_system_table->boot_services;
50 efi_call_1 (b->unload_image, image_handle);
51- efi_call_2 (b->free_pages, address, pages);
52-
53- grub_free (file_path);
54- grub_free (cmdline);
55- cmdline = 0;
56- file_path = 0;
57
58 grub_dl_unref (my_mod);
59 return GRUB_ERR_NONE;
60@@ -140,7 +135,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
61 char *dir_start;
62 char *dir_end;
63 grub_size_t size;
64- grub_efi_device_path_t *d;
65+ grub_efi_device_path_t *d, *file_path;
66
67 dir_start = grub_strchr (filename, ')');
68 if (! dir_start)
69@@ -222,11 +217,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
70 grub_efi_status_t status;
71 grub_efi_boot_services_t *b;
72 grub_device_t dev = 0;
73- grub_efi_device_path_t *dp = 0;
74+ grub_efi_device_path_t *dp = NULL, *file_path = NULL;
75 grub_efi_loaded_image_t *loaded_image;
76 char *filename;
77 void *boot_image = 0;
78 grub_efi_handle_t dev_handle = 0;
79+ grub_efi_physical_address_t address = 0;
80+ grub_efi_uintn_t pages = 0;
81+ grub_efi_char16_t *cmdline = NULL;
82
83 if (argc == 0)
84 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
85@@ -234,11 +232,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
86
87 grub_dl_ref (my_mod);
88
89- /* Initialize some global variables. */
90- address = 0;
91- image_handle = 0;
92- file_path = 0;
93-
94 b = grub_efi_system_table->boot_services;
95
96 file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
97@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
98 grub_file_close (file);
99 grub_device_close (dev);
100
101+ /* We're finished with the source image buffer and file path now. */
102+ efi_call_2 (b->free_pages, address, pages);
103+ grub_free (file_path);
104+
105 grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
106 return 0;
107
108@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
109 if (file)
110 grub_file_close (file);
111
112+ grub_free (cmdline);
113 grub_free (file_path);
114
115 if (address)
116 efi_call_2 (b->free_pages, address, pages);
117
118+ if (image_handle != NULL)
119+ {
120+ efi_call_1 (b->unload_image, image_handle);
121+ image_handle = NULL;
122+ }
123+
124 grub_dl_unref (my_mod);
125
126 return grub_errno;
127--
1282.34.1
129
diff --git a/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc
index 7161c4560b..e819cb9775 100644
--- a/meta/recipes-bsp/grub/grub2.inc
+++ b/meta/recipes-bsp/grub/grub2.inc
@@ -34,6 +34,9 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
34 file://CVE-2022-28735-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch \ 34 file://CVE-2022-28735-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch \
35 file://0001-configure-Remove-obsoleted-malign-jumps-loops-functi.patch \ 35 file://0001-configure-Remove-obsoleted-malign-jumps-loops-functi.patch \
36 file://0002-configure-Check-for-falign-jumps-1-beside-falign-loo.patch \ 36 file://0002-configure-Check-for-falign-jumps-1-beside-falign-loo.patch \
37 file://loader-efi-chainloader-Simplify-the-loader-state.patch \
38 file://commands-boot-Add-API-to-pass-context-to-loader.patch \
39 file://CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch\
37" 40"
38 41
39SRC_URI[sha256sum] = "23b64b4c741569f9426ed2e3d0e6780796fca081bee4c99f62aa3f53ae803f5f" 42SRC_URI[sha256sum] = "23b64b4c741569f9426ed2e3d0e6780796fca081bee4c99f62aa3f53ae803f5f"