diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-bsp/grub/files/CVE-2022-28733.patch | 60 | ||||
-rw-r--r-- | meta/recipes-bsp/grub/files/CVE-2022-28734.patch | 67 | ||||
-rw-r--r-- | meta/recipes-bsp/grub/files/CVE-2022-28736.patch | 275 | ||||
-rw-r--r-- | meta/recipes-bsp/grub/grub2.inc | 3 |
4 files changed, 405 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2022-28733.patch b/meta/recipes-bsp/grub/files/CVE-2022-28733.patch new file mode 100644 index 0000000000..6cfdf20e2d --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2022-28733.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From 415fb5eb83cbd3b5cfc25ac1290f2de4fe3d231c Mon Sep 17 00:00:00 2001 | ||
2 | From: Hitendra Prajapati <hprajapati@mvista.com> | ||
3 | Date: Mon, 1 Aug 2022 10:48:34 +0530 | ||
4 | Subject: [PATCH] CVE-2022-28733 | ||
5 | |||
6 | Upstream-Status: Backport [https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=3e4817538de828319ba6d59ced2fbb9b5ca13287] | ||
7 | CVE: CVE-2022-28733 | ||
8 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
9 | |||
10 | net/ip: Do IP fragment maths safely | ||
11 | |||
12 | We can receive packets with invalid IP fragmentation information. This | ||
13 | can lead to rsm->total_len underflowing and becoming very large. | ||
14 | |||
15 | Then, in grub_netbuff_alloc(), we add to this very large number, which can | ||
16 | cause it to overflow and wrap back around to a small positive number. | ||
17 | The allocation then succeeds, but the resulting buffer is too small and | ||
18 | subsequent operations can write past the end of the buffer. | ||
19 | |||
20 | Catch the underflow here. | ||
21 | |||
22 | Fixes: CVE-2022-28733 | ||
23 | |||
24 | Signed-off-by: Daniel Axtens <dja@axtens.net> | ||
25 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | ||
26 | --- | ||
27 | grub-core/net/ip.c | 10 +++++++++- | ||
28 | 1 file changed, 9 insertions(+), 1 deletion(-) | ||
29 | |||
30 | diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c | ||
31 | index ea5edf8..74e4e8b 100644 | ||
32 | --- a/grub-core/net/ip.c | ||
33 | +++ b/grub-core/net/ip.c | ||
34 | @@ -25,6 +25,7 @@ | ||
35 | #include <grub/net/netbuff.h> | ||
36 | #include <grub/mm.h> | ||
37 | #include <grub/priority_queue.h> | ||
38 | +#include <grub/safemath.h> | ||
39 | #include <grub/time.h> | ||
40 | |||
41 | struct iphdr { | ||
42 | @@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, | ||
43 | { | ||
44 | rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) | ||
45 | + (nb->tail - nb->data)); | ||
46 | - rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t)); | ||
47 | + | ||
48 | + if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t), | ||
49 | + &rsm->total_len)) | ||
50 | + { | ||
51 | + grub_dprintf ("net", "IP reassembly size underflow\n"); | ||
52 | + return GRUB_ERR_NONE; | ||
53 | + } | ||
54 | + | ||
55 | rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len); | ||
56 | if (!rsm->asm_netbuff) | ||
57 | { | ||
58 | -- | ||
59 | 2.25.1 | ||
60 | |||
diff --git a/meta/recipes-bsp/grub/files/CVE-2022-28734.patch b/meta/recipes-bsp/grub/files/CVE-2022-28734.patch new file mode 100644 index 0000000000..577ec10bea --- /dev/null +++ b/meta/recipes-bsp/grub/files/CVE-2022-28734.patch | |||
@@ -0,0 +1,67 @@ | |||
1 | From f03f09c2a07eae7f3a4646e33a406ae2689afb9e Mon Sep 17 00:00:00 2001 | ||
2 | From: Hitendra Prajapati <hprajapati@mvista.com> | ||
3 | Date: Mon, 1 Aug 2022 10:59:41 +0530 | ||
4 | Subject: [PATCH] CVE-2022-28734 | ||
5 | |||
6 | Upstream-Status: Backport [https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=b26b4c08e7119281ff30d0fb4a6169bd2afa8fe4] | ||
7 | CVE: CVE-2022-28734 | ||
8 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
9 | |||
10 | net/http: Fix OOB write for split http headers | ||
11 | |||
12 | GRUB has special code for handling an http header that is split | ||
13 | across two packets. | ||
14 | |||
15 | The code tracks the end of line by looking for a "\n" byte. The | ||
16 | code for split headers has always advanced the pointer just past the | ||
17 | end of the line, whereas the code that handles unsplit headers does | ||
18 | not advance the pointer. This extra advance causes the length to be | ||
19 | one greater, which breaks an assumption in parse_line(), leading to | ||
20 | it writing a NUL byte one byte past the end of the buffer where we | ||
21 | reconstruct the line from the two packets. | ||
22 | |||
23 | It's conceivable that an attacker controlled set of packets could | ||
24 | cause this to zero out the first byte of the "next" pointer of the | ||
25 | grub_mm_region structure following the current_line buffer. | ||
26 | |||
27 | Do not advance the pointer in the split header case. | ||
28 | |||
29 | Fixes: CVE-2022-28734 | ||
30 | --- | ||
31 | grub-core/net/http.c | 12 +++++++++--- | ||
32 | 1 file changed, 9 insertions(+), 3 deletions(-) | ||
33 | |||
34 | diff --git a/grub-core/net/http.c b/grub-core/net/http.c | ||
35 | index 5aa4ad3..a220d21 100644 | ||
36 | --- a/grub-core/net/http.c | ||
37 | +++ b/grub-core/net/http.c | ||
38 | @@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) | ||
39 | char *end = ptr + len; | ||
40 | while (end > ptr && *(end - 1) == '\r') | ||
41 | end--; | ||
42 | + | ||
43 | + /* LF without CR. */ | ||
44 | + if (end == ptr + len) | ||
45 | + { | ||
46 | + data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR")); | ||
47 | + return GRUB_ERR_NONE; | ||
48 | + } | ||
49 | *end = 0; | ||
50 | + | ||
51 | /* Trailing CRLF. */ | ||
52 | if (data->in_chunk_len == 1) | ||
53 | { | ||
54 | @@ -190,9 +198,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), | ||
55 | int have_line = 1; | ||
56 | char *t; | ||
57 | ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data); | ||
58 | - if (ptr) | ||
59 | - ptr++; | ||
60 | - else | ||
61 | + if (ptr == NULL) | ||
62 | { | ||
63 | have_line = 0; | ||
64 | ptr = (char *) nb->tail; | ||
65 | -- | ||
66 | 2.25.1 | ||
67 | |||
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 @@ | |||
1 | From 431a111c60095fc973d83fe9209f26f29ce78784 Mon Sep 17 00:00:00 2001 | ||
2 | From: Hitendra Prajapati <hprajapati@mvista.com> | ||
3 | Date: Mon, 1 Aug 2022 11:17:17 +0530 | ||
4 | Subject: [PATCH] CVE-2022-28736 | ||
5 | |||
6 | Upstream-Status: Backport [https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=04c86e0bb7b58fc2f913f798cdb18934933e532d] | ||
7 | CVE: CVE-2022-28736 | ||
8 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
9 | |||
10 | loader/efi/chainloader: Use grub_loader_set_ex() | ||
11 | |||
12 | This ports the EFI chainloader to use grub_loader_set_ex() in order to fix | ||
13 | a use-after-free bug that occurs when grub_cmd_chainloader() is executed | ||
14 | more than once before a boot attempt is performed. | ||
15 | |||
16 | Fixes: CVE-2022-28736 | ||
17 | |||
18 | Signed-off-by: Chris Coulson <chris.coulson@canonical.com> | ||
19 | Reviewed-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 | |||
26 | diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c | ||
27 | index 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) | ||
143 | diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c | ||
144 | index 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; | ||
257 | diff --git a/include/grub/loader.h b/include/grub/loader.h | ||
258 | index 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 | -- | ||
274 | 2.25.1 | ||
275 | |||
diff --git a/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc index 0b7ca6d3d6..a248af0073 100644 --- a/meta/recipes-bsp/grub/grub2.inc +++ b/meta/recipes-bsp/grub/grub2.inc | |||
@@ -99,6 +99,9 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \ | |||
99 | file://CVE-2021-3695.patch \ | 99 | file://CVE-2021-3695.patch \ |
100 | file://CVE-2021-3696.patch \ | 100 | file://CVE-2021-3696.patch \ |
101 | file://CVE-2021-3697.patch \ | 101 | file://CVE-2021-3697.patch \ |
102 | file://CVE-2022-28733.patch \ | ||
103 | file://CVE-2022-28734.patch \ | ||
104 | file://CVE-2022-28736.patch \ | ||
102 | " | 105 | " |
103 | SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" | 106 | SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" |
104 | SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" | 107 | SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" |