summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHitendra Prajapati <hprajapati@mvista.com>2023-07-07 11:40:05 +0530
committerSteve Sakoman <steve@sakoman.com>2023-07-12 05:13:58 -1000
commit70d75e8996442f015bd0585e60399da3b473e057 (patch)
tree3a95fdbb1ae51e825703f93311779f6d38ffa03e
parentb994c2d4f5baed2b4227f14f0d653cdc28d9062b (diff)
downloadpoky-70d75e8996442f015bd0585e60399da3b473e057.tar.gz
grub2: Fix Multiple CVEs
Backport fixes for: * CVE-2020-27749 - Upstream-Status: Backport from https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=c6c426e5ab6ea715153b72584de6bd8c82f698ec && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=b1c9e9e889e4273fb15712051c887e6078511448 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=3d157bbd06506b170fde5ec23980c4bf9f7660e2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=8bc817014ce3d7a498db44eae33c8b90e2430926 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=030fb6c4fa354cdbd6a8d6903dfed5d36eaf3cb2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=4ea7bae51f97e49c84dc67ea30b466ca8633b9f6 * CVE-2021-20225 - Upstream-Status: Backport from https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2a330dba93ff11bc00eda76e9419bc52b0c7ead6 * CVE-2021-20233 - Upstream-Status: Backport from https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2f533a89a8dfcacbf2c9dbc77d910f111f24bf33 (From OE-Core rev: 636aab87bc7e10b4ce0bdaa00dd01416a590a801) Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2020-27749.patch609
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2021-20225.patch58
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2021-20233.patch50
-rw-r--r--meta/recipes-bsp/grub/grub2.inc3
4 files changed, 720 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2020-27749.patch b/meta/recipes-bsp/grub/files/CVE-2020-27749.patch
new file mode 100644
index 0000000000..a2566b2ded
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2020-27749.patch
@@ -0,0 +1,609 @@
1From 4ea7bae51f97e49c84dc67ea30b466ca8633b9f6 Mon Sep 17 00:00:00 2001
2From: Chris Coulson <chris.coulson@canonical.com>
3Date: Thu, 7 Jan 2021 19:21:03 +0000
4Subject: kern/parser: Fix a stack buffer overflow
5
6grub_parser_split_cmdline() expands variable names present in the supplied
7command line in to their corresponding variable contents and uses a 1 kiB
8stack buffer for temporary storage without sufficient bounds checking. If
9the function is called with a command line that references a variable with
10a sufficiently large payload, it is possible to overflow the stack
11buffer via tab completion, corrupt the stack frame and potentially
12control execution.
13
14Fixes: CVE-2020-27749
15
16Reported-by: Chris Coulson <chris.coulson@canonical.com>
17Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
18Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
19Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
20
21Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=c6c426e5ab6ea715153b72584de6bd8c82f698ec && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=b1c9e9e889e4273fb15712051c887e6078511448 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=3d157bbd06506b170fde5ec23980c4bf9f7660e2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=8bc817014ce3d7a498db44eae33c8b90e2430926 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=030fb6c4fa354cdbd6a8d6903dfed5d36eaf3cb2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=4ea7bae51f97e49c84dc67ea30b466ca8633b9f6]
22CVE: CVE-2020-27749
23
24Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
25---
26 grub-core/Makefile.core.def | 1 +
27 grub-core/kern/buffer.c | 117 +++++++++++++++++++++
28 grub-core/kern/parser.c | 204 +++++++++++++++++++++++-------------
29 include/grub/buffer.h | 144 +++++++++++++++++++++++++
30 4 files changed, 395 insertions(+), 71 deletions(-)
31 create mode 100644 grub-core/kern/buffer.c
32 create mode 100644 include/grub/buffer.h
33
34diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
35index 651ea2a..823cd57 100644
36--- a/grub-core/Makefile.core.def
37+++ b/grub-core/Makefile.core.def
38@@ -123,6 +123,7 @@ kernel = {
39 riscv32_efi_startup = kern/riscv/efi/startup.S;
40 riscv64_efi_startup = kern/riscv/efi/startup.S;
41
42+ common = kern/buffer.c;
43 common = kern/command.c;
44 common = kern/corecmd.c;
45 common = kern/device.c;
46diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c
47new file mode 100644
48index 0000000..9f5f8b8
49--- /dev/null
50+++ b/grub-core/kern/buffer.c
51@@ -0,0 +1,117 @@
52+/*
53+ * GRUB -- GRand Unified Bootloader
54+ * Copyright (C) 2021 Free Software Foundation, Inc.
55+ *
56+ * GRUB is free software: you can redistribute it and/or modify
57+ * it under the terms of the GNU General Public License as published by
58+ * the Free Software Foundation, either version 3 of the License, or
59+ * (at your option) any later version.
60+ *
61+ * GRUB is distributed in the hope that it will be useful,
62+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
63+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64+ * GNU General Public License for more details.
65+ *
66+ * You should have received a copy of the GNU General Public License
67+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
68+ */
69+
70+#include <grub/buffer.h>
71+#include <grub/err.h>
72+#include <grub/misc.h>
73+#include <grub/mm.h>
74+#include <grub/safemath.h>
75+#include <grub/types.h>
76+
77+grub_buffer_t
78+grub_buffer_new (grub_size_t sz)
79+{
80+ struct grub_buffer *ret;
81+
82+ ret = (struct grub_buffer *) grub_malloc (sizeof (*ret));
83+ if (ret == NULL)
84+ return NULL;
85+
86+ ret->data = (grub_uint8_t *) grub_malloc (sz);
87+ if (ret->data == NULL)
88+ {
89+ grub_free (ret);
90+ return NULL;
91+ }
92+
93+ ret->sz = sz;
94+ ret->pos = 0;
95+ ret->used = 0;
96+
97+ return ret;
98+}
99+
100+void
101+grub_buffer_free (grub_buffer_t buf)
102+{
103+ grub_free (buf->data);
104+ grub_free (buf);
105+}
106+
107+grub_err_t
108+grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req)
109+{
110+ grub_uint8_t *d;
111+ grub_size_t newsz = 1;
112+
113+ /* Is the current buffer size adequate? */
114+ if (buf->sz >= req)
115+ return GRUB_ERR_NONE;
116+
117+ /* Find the smallest power-of-2 size that satisfies the request. */
118+ while (newsz < req)
119+ {
120+ if (newsz == 0)
121+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
122+ N_("requested buffer size is too large"));
123+ newsz <<= 1;
124+ }
125+
126+ d = (grub_uint8_t *) grub_realloc (buf->data, newsz);
127+ if (d == NULL)
128+ return grub_errno;
129+
130+ buf->data = d;
131+ buf->sz = newsz;
132+
133+ return GRUB_ERR_NONE;
134+}
135+
136+void *
137+grub_buffer_take_data (grub_buffer_t buf)
138+{
139+ void *data = buf->data;
140+
141+ buf->data = NULL;
142+ buf->sz = buf->pos = buf->used = 0;
143+
144+ return data;
145+}
146+
147+void
148+grub_buffer_reset (grub_buffer_t buf)
149+{
150+ buf->pos = buf->used = 0;
151+}
152+
153+grub_err_t
154+grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n)
155+{
156+ grub_size_t newpos;
157+
158+ if (grub_add (buf->pos, n, &newpos))
159+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
160+
161+ if (newpos > buf->used)
162+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
163+ N_("new read is position beyond the end of the written data"));
164+
165+ buf->pos = newpos;
166+
167+ return GRUB_ERR_NONE;
168+}
169diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
170index d1cf061..6ab7aa4 100644
171--- a/grub-core/kern/parser.c
172+++ b/grub-core/kern/parser.c
173@@ -1,7 +1,7 @@
174 /* parser.c - the part of the parser that can return partial tokens */
175 /*
176 * GRUB -- GRand Unified Bootloader
177- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc.
178+ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc.
179 *
180 * GRUB is free software: you can redistribute it and/or modify
181 * it under the terms of the GNU General Public License as published by
182@@ -18,6 +18,7 @@
183 */
184
185 #include <grub/parser.h>
186+#include <grub/buffer.h>
187 #include <grub/env.h>
188 #include <grub/misc.h>
189 #include <grub/mm.h>
190@@ -107,8 +108,8 @@ check_varstate (grub_parser_state_t s)
191 }
192
193
194-static void
195-add_var (char *varname, char **bp, char **vp,
196+static grub_err_t
197+add_var (grub_buffer_t varname, grub_buffer_t buf,
198 grub_parser_state_t state, grub_parser_state_t newstate)
199 {
200 const char *val;
201@@ -116,17 +117,74 @@ add_var (char *varname, char **bp, char **vp,
202 /* Check if a variable was being read in and the end of the name
203 was reached. */
204 if (!(check_varstate (state) && !check_varstate (newstate)))
205- return;
206+ return GRUB_ERR_NONE;
207+
208+ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE)
209+ return grub_errno;
210
211- *((*vp)++) = '\0';
212- val = grub_env_get (varname);
213- *vp = varname;
214+ val = grub_env_get ((const char *) grub_buffer_peek_data (varname));
215+ grub_buffer_reset (varname);
216 if (!val)
217- return;
218+ return GRUB_ERR_NONE;
219
220 /* Insert the contents of the variable in the buffer. */
221- for (; *val; val++)
222- *((*bp)++) = *val;
223+ return grub_buffer_append_data (buf, val, grub_strlen (val));
224+}
225+
226+static grub_err_t
227+terminate_arg (grub_buffer_t buffer, int *argc)
228+{
229+ grub_size_t unread = grub_buffer_get_unread_bytes (buffer);
230+
231+ if (unread == 0)
232+ return GRUB_ERR_NONE;
233+
234+ if (*(const char *) grub_buffer_peek_data_at (buffer, unread - 1) == '\0')
235+ return GRUB_ERR_NONE;
236+
237+ if (grub_buffer_append_char (buffer, '\0') != GRUB_ERR_NONE)
238+ return grub_errno;
239+
240+ (*argc)++;
241+
242+ return GRUB_ERR_NONE;
243+}
244+
245+static grub_err_t
246+process_char (char c, grub_buffer_t buffer, grub_buffer_t varname,
247+ grub_parser_state_t state, int *argc,
248+ grub_parser_state_t *newstate)
249+{
250+ char use;
251+
252+ *newstate = grub_parser_cmdline_state (state, c, &use);
253+
254+ /*
255+ * If a variable was being processed and this character does
256+ * not describe the variable anymore, write the variable to
257+ * the buffer.
258+ */
259+ if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE)
260+ return grub_errno;
261+
262+ if (check_varstate (*newstate))
263+ {
264+ if (use)
265+ return grub_buffer_append_char (varname, use);
266+ }
267+ else if (*newstate == GRUB_PARSER_STATE_TEXT &&
268+ state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
269+ {
270+ /*
271+ * Don't add more than one argument if multiple
272+ * spaces are used.
273+ */
274+ return terminate_arg (buffer, argc);
275+ }
276+ else if (use)
277+ return grub_buffer_append_char (buffer, use);
278+
279+ return GRUB_ERR_NONE;
280 }
281
282 grub_err_t
283@@ -135,24 +193,36 @@ grub_parser_split_cmdline (const char *cmdline,
284 int *argc, char ***argv)
285 {
286 grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
287- /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
288- allocated. */
289- char buffer[1024];
290- char *bp = buffer;
291+ grub_buffer_t buffer, varname;
292 char *rd = (char *) cmdline;
293- char varname[200];
294- char *vp = varname;
295- char *args;
296+ char *rp = rd;
297 int i;
298
299 *argc = 0;
300 *argv = NULL;
301+
302+ buffer = grub_buffer_new (1024);
303+ if (buffer == NULL)
304+ return grub_errno;
305+
306+ varname = grub_buffer_new (200);
307+ if (varname == NULL)
308+ goto fail;
309+
310 do
311 {
312- if (!rd || !*rd)
313+ if (rp == NULL || *rp == '\0')
314 {
315+ if (rd != cmdline)
316+ {
317+ grub_free (rd);
318+ rd = rp = NULL;
319+ }
320 if (getline)
321- getline (&rd, 1, getline_data);
322+ {
323+ getline (&rd, 1, getline_data);
324+ rp = rd;
325+ }
326 else
327 break;
328 }
329@@ -160,39 +230,14 @@ grub_parser_split_cmdline (const char *cmdline,
330 if (!rd)
331 break;
332
333- for (; *rd; rd++)
334+ for (; *rp != '\0'; rp++)
335 {
336 grub_parser_state_t newstate;
337- char use;
338
339- newstate = grub_parser_cmdline_state (state, *rd, &use);
340+ if (process_char (*rp, buffer, varname, state, argc,
341+ &newstate) != GRUB_ERR_NONE)
342+ goto fail;
343
344- /* If a variable was being processed and this character does
345- not describe the variable anymore, write the variable to
346- the buffer. */
347- add_var (varname, &bp, &vp, state, newstate);
348-
349- if (check_varstate (newstate))
350- {
351- if (use)
352- *(vp++) = use;
353- }
354- else
355- {
356- if (newstate == GRUB_PARSER_STATE_TEXT
357- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
358- {
359- /* Don't add more than one argument if multiple
360- spaces are used. */
361- if (bp != buffer && *(bp - 1))
362- {
363- *(bp++) = '\0';
364- (*argc)++;
365- }
366- }
367- else if (use)
368- *(bp++) = use;
369- }
370 state = newstate;
371 }
372 }
373@@ -200,43 +245,60 @@ grub_parser_split_cmdline (const char *cmdline,
374
375 /* A special case for when the last character was part of a
376 variable. */
377- add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
378+ if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE)
379+ goto fail;
380
381- if (bp != buffer && *(bp - 1))
382- {
383- *(bp++) = '\0';
384- (*argc)++;
385- }
386+ /* Ensure that the last argument is terminated. */
387+ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE)
388+ goto fail;
389
390 /* If there are no args, then we're done. */
391 if (!*argc)
392- return 0;
393-
394- /* Reserve memory for the return values. */
395- args = grub_malloc (bp - buffer);
396- if (!args)
397- return grub_errno;
398- grub_memcpy (args, buffer, bp - buffer);
399+ {
400+ grub_errno = GRUB_ERR_NONE;
401+ goto out;
402+ }
403
404 *argv = grub_calloc (*argc + 1, sizeof (char *));
405 if (!*argv)
406- {
407- grub_free (args);
408- return grub_errno;
409- }
410+ goto fail;
411
412 /* The arguments are separated with 0's, setup argv so it points to
413 the right values. */
414- bp = args;
415 for (i = 0; i < *argc; i++)
416 {
417- (*argv)[i] = bp;
418- while (*bp)
419- bp++;
420- bp++;
421+ char *arg;
422+
423+ if (i > 0)
424+ {
425+ if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE)
426+ goto fail;
427+ }
428+
429+ arg = (char *) grub_buffer_peek_data (buffer);
430+ if (arg == NULL ||
431+ grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE)
432+ goto fail;
433+
434+ (*argv)[i] = arg;
435 }
436
437- return 0;
438+ /* Keep memory for the return values. */
439+ grub_buffer_take_data (buffer);
440+
441+ grub_errno = GRUB_ERR_NONE;
442+
443+ out:
444+ if (rd != cmdline)
445+ grub_free (rd);
446+ grub_buffer_free (buffer);
447+ grub_buffer_free (varname);
448+
449+ return grub_errno;
450+
451+ fail:
452+ grub_free (*argv);
453+ goto out;
454 }
455
456 /* Helper for grub_parser_execute. */
457diff --git a/include/grub/buffer.h b/include/grub/buffer.h
458new file mode 100644
459index 0000000..f4b10cf
460--- /dev/null
461+++ b/include/grub/buffer.h
462@@ -0,0 +1,144 @@
463+/*
464+ * GRUB -- GRand Unified Bootloader
465+ * Copyright (C) 2021 Free Software Foundation, Inc.
466+ *
467+ * GRUB is free software: you can redistribute it and/or modify
468+ * it under the terms of the GNU General Public License as published by
469+ * the Free Software Foundation, either version 3 of the License, or
470+ * (at your option) any later version.
471+ *
472+ * GRUB is distributed in the hope that it will be useful,
473+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
474+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
475+ * GNU General Public License for more details.
476+ *
477+ * You should have received a copy of the GNU General Public License
478+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
479+ */
480+
481+#ifndef GRUB_BUFFER_H
482+#define GRUB_BUFFER_H 1
483+
484+#include <grub/err.h>
485+#include <grub/misc.h>
486+#include <grub/mm.h>
487+#include <grub/safemath.h>
488+#include <grub/types.h>
489+
490+struct grub_buffer
491+{
492+ grub_uint8_t *data;
493+ grub_size_t sz;
494+ grub_size_t pos;
495+ grub_size_t used;
496+};
497+
498+/*
499+ * grub_buffer_t represents a simple variable sized byte buffer with
500+ * read and write cursors. It currently only implements
501+ * functionality required by the only user in GRUB (append byte[s],
502+ * peeking data at a specified position and updating the read cursor.
503+ * Some things that this doesn't do yet are:
504+ * - Reading a portion of the buffer by copying data from the current
505+ * read position in to a caller supplied destination buffer and then
506+ * automatically updating the read cursor.
507+ * - Dropping the read part at the start of the buffer when an append
508+ * requires more space.
509+ */
510+typedef struct grub_buffer *grub_buffer_t;
511+
512+/* Allocate a new buffer with the specified initial size. */
513+extern grub_buffer_t grub_buffer_new (grub_size_t sz);
514+
515+/* Free the buffer and its resources. */
516+extern void grub_buffer_free (grub_buffer_t buf);
517+
518+/* Return the number of unread bytes in this buffer. */
519+static inline grub_size_t
520+grub_buffer_get_unread_bytes (grub_buffer_t buf)
521+{
522+ return buf->used - buf->pos;
523+}
524+
525+/*
526+ * Ensure that the buffer size is at least the requested
527+ * number of bytes.
528+ */
529+extern grub_err_t grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req);
530+
531+/*
532+ * Append the specified number of bytes from the supplied
533+ * data to the buffer.
534+ */
535+static inline grub_err_t
536+grub_buffer_append_data (grub_buffer_t buf, const void *data, grub_size_t len)
537+{
538+ grub_size_t req;
539+
540+ if (grub_add (buf->used, len, &req))
541+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
542+
543+ if (grub_buffer_ensure_space (buf, req) != GRUB_ERR_NONE)
544+ return grub_errno;
545+
546+ grub_memcpy (&buf->data[buf->used], data, len);
547+ buf->used = req;
548+
549+ return GRUB_ERR_NONE;
550+}
551+
552+/* Append the supplied character to the buffer. */
553+static inline grub_err_t
554+grub_buffer_append_char (grub_buffer_t buf, char c)
555+{
556+ return grub_buffer_append_data (buf, &c, 1);
557+}
558+
559+/*
560+ * Forget and return the underlying data buffer. The caller
561+ * becomes the owner of this buffer, and must free it when it
562+ * is no longer required.
563+ */
564+extern void *grub_buffer_take_data (grub_buffer_t buf);
565+
566+/* Reset this buffer. Note that this does not deallocate any resources. */
567+void grub_buffer_reset (grub_buffer_t buf);
568+
569+/*
570+ * Return a pointer to the underlying data buffer at the specified
571+ * offset from the current read position. Note that this pointer may
572+ * become invalid if the buffer is mutated further.
573+ */
574+static inline void *
575+grub_buffer_peek_data_at (grub_buffer_t buf, grub_size_t off)
576+{
577+ if (grub_add (buf->pos, off, &off))
578+ {
579+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected."));
580+ return NULL;
581+ }
582+
583+ if (off >= buf->used)
584+ {
585+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("peek out of range"));
586+ return NULL;
587+ }
588+
589+ return &buf->data[off];
590+}
591+
592+/*
593+ * Return a pointer to the underlying data buffer at the current
594+ * read position. Note that this pointer may become invalid if the
595+ * buffer is mutated further.
596+ */
597+static inline void *
598+grub_buffer_peek_data (grub_buffer_t buf)
599+{
600+ return grub_buffer_peek_data_at (buf, 0);
601+}
602+
603+/* Advance the read position by the specified number of bytes. */
604+extern grub_err_t grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n);
605+
606+#endif /* GRUB_BUFFER_H */
607--
6082.25.1
609
diff --git a/meta/recipes-bsp/grub/files/CVE-2021-20225.patch b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch
new file mode 100644
index 0000000000..b864febe62
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2021-20225.patch
@@ -0,0 +1,58 @@
1From 2a330dba93ff11bc00eda76e9419bc52b0c7ead6 Mon Sep 17 00:00:00 2001
2From: Daniel Axtens <dja@axtens.net>
3Date: Fri, 22 Jan 2021 16:07:29 +1100
4Subject: lib/arg: Block repeated short options that require an argument
5
6Fuzzing found the following crash:
7
8 search -hhhhhhhhhhhhhf
9
10We didn't allocate enough option space for 13 hints because the
11allocation code counts the number of discrete arguments (i.e. argc).
12However, the shortopt parsing code will happily keep processing
13a combination of short options without checking if those short
14options require an argument. This means you can easily end writing
15past the allocated option space.
16
17This fixes a OOB write which can cause heap corruption.
18
19Fixes: CVE-2021-20225
20
21Reported-by: Daniel Axtens <dja@axtens.net>
22Signed-off-by: Daniel Axtens <dja@axtens.net>
23Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
24
25Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2a330dba93ff11bc00eda76e9419bc52b0c7ead6]
26CVE: CVE-2021-20225
27Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
28---
29 grub-core/lib/arg.c | 13 +++++++++++++
30 1 file changed, 13 insertions(+)
31
32diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
33index 3288609..537c5e9 100644
34--- a/grub-core/lib/arg.c
35+++ b/grub-core/lib/arg.c
36@@ -299,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
37 it can have an argument value. */
38 if (*curshort)
39 {
40+ /*
41+ * Only permit further short opts if this one doesn't
42+ * require a value.
43+ */
44+ if (opt->type != ARG_TYPE_NONE &&
45+ !(opt->flags & GRUB_ARG_OPTION_OPTIONAL))
46+ {
47+ grub_error (GRUB_ERR_BAD_ARGUMENT,
48+ N_("missing mandatory option for `%s'"),
49+ opt->longarg);
50+ goto fail;
51+ }
52+
53 if (parse_option (cmd, opt, 0, usr) || grub_errno)
54 goto fail;
55 }
56--
572.25.1
58
diff --git a/meta/recipes-bsp/grub/files/CVE-2021-20233.patch b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch
new file mode 100644
index 0000000000..d2069afc18
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2021-20233.patch
@@ -0,0 +1,50 @@
1From 2f533a89a8dfcacbf2c9dbc77d910f111f24bf33 Mon Sep 17 00:00:00 2001
2From: Daniel Axtens <dja@axtens.net>
3Date: Fri, 22 Jan 2021 17:10:48 +1100
4Subject: commands/menuentry: Fix quoting in setparams_prefix()
5
6Commit 9acdcbf32542 (use single quotes in menuentry setparams command)
7says that expressing a quoted single quote will require 3 characters. It
8actually requires (and always did require!) 4 characters:
9
10 str: a'b => a'\''b
11 len: 3 => 6 (2 for the letters + 4 for the quote)
12
13This leads to not allocating enough memory and thus out of bounds writes
14that have been observed to cause heap corruption.
15
16Allocate 4 bytes for each single quote.
17
18Commit 22e7dbb2bb81 (Fix quoting in legacy parser.) does the same
19quoting, but it adds 3 as extra overhead on top of the single byte that
20the quote already needs. So it's correct.
21
22Fixes: 9acdcbf32542 (use single quotes in menuentry setparams command)
23Fixes: CVE-2021-20233
24
25Reported-by: Daniel Axtens <dja@axtens.net>
26Signed-off-by: Daniel Axtens <dja@axtens.net>
27
28Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2f533a89a8dfcacbf2c9dbc77d910f111f24bf33]
29CVE: CVE-2021-20233
30Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
31---
32 grub-core/commands/menuentry.c | 2 +-
33 1 file changed, 1 insertion(+), 1 deletion(-)
34
35diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
36index 9164df7..720e6d8 100644
37--- a/grub-core/commands/menuentry.c
38+++ b/grub-core/commands/menuentry.c
39@@ -230,7 +230,7 @@ setparams_prefix (int argc, char **args)
40 len += 3; /* 3 = 1 space + 2 quotes */
41 p = args[i];
42 while (*p)
43- len += (*p++ == '\'' ? 3 : 1);
44+ len += (*p++ == '\'' ? 4 : 1);
45 }
46
47 result = grub_malloc (len + 2);
48--
492.25.1
50
diff --git a/meta/recipes-bsp/grub/grub2.inc b/meta/recipes-bsp/grub/grub2.inc
index d09eecd8ac..5a6e213936 100644
--- a/meta/recipes-bsp/grub/grub2.inc
+++ b/meta/recipes-bsp/grub/grub2.inc
@@ -106,6 +106,9 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
106 file://font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch \ 106 file://font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch \
107 file://CVE-2022-2601.patch \ 107 file://CVE-2022-2601.patch \
108 file://CVE-2022-3775.patch \ 108 file://CVE-2022-3775.patch \
109 file://CVE-2020-27749.patch \
110 file://CVE-2021-20225.patch \
111 file://CVE-2021-20233.patch \
109 " 112 "
110SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934" 113SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934"
111SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea" 114SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea"