"Minor" bug fixes

Resolves: CVE-2020-10713
Resolves: CVE-2020-14308
Resolves: CVE-2020-14309
Resolves: CVE-2020-14310
Resolves: CVE-2020-14311
Resolves: CVE-2020-15705
Resolves: CVE-2020-15706
Resolves: CVE-2020-15707

Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
Peter Jones 2020-08-10 17:47:38 -04:00
parent dc2f1a03d9
commit 47cf63735c
47 changed files with 6668 additions and 8 deletions

View File

@ -16,14 +16,22 @@ path fails.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
--- ---
grub-core/net/http.c | 9 ++++++++- grub-core/net/http.c | 10 +++++++++-
1 file changed, 8 insertions(+), 1 deletion(-) 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index b52b558d631..7f878b56157 100644 index b52b558d631..598961afbb5 100644
--- a/grub-core/net/http.c --- a/grub-core/net/http.c
+++ b/grub-core/net/http.c +++ b/grub-core/net/http.c
@@ -501,13 +501,20 @@ http_open (struct grub_file *file, const char *filename) @@ -26,6 +26,7 @@
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/i18n.h>
+#include <grub/env.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -501,13 +502,20 @@ http_open (struct grub_file *file, const char *filename)
{ {
grub_err_t err; grub_err_t err;
struct http_data *data; struct http_data *data;

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Tue, 9 Apr 2019 13:12:40 +0200
Subject: [PATCH] Don't assume that boot commands will only return on fail
While it's true that for most loaders the boot command never returns, it
may be the case that it does. For example the GRUB emulator boot command
calls to systemctl kexec which in turn does an asynchonous call to kexec.
So in this case GRUB will wrongly assume that the boot command fails and
print a "Failed to boot both default and fallback entries" even when the
kexec call later succeeds.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
grub-core/normal/menu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 9ea1f411814..14ceb9bb060 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
- return;
+ return grub_errno;
}
errs_before = grub_err_printed_errors;
@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
- return;
+ return grub_errno;
grub_env_set_menu (menu);
if (auto_boot)
grub_env_set ("timeout", "0");

View File

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 16 Jan 2019 13:21:46 -0500
Subject: [PATCH] Fix a missing return in efi-export-env and efi-load-env
commands
Somewhere along the way this got mis-merged to include a return without
a value. Fix it up.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/commands/efi/env.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c
index a69079786aa..4838dac22e7 100644
--- a/grub-core/commands/efi/env.c
+++ b/grub-core/commands/efi/env.c
@@ -149,6 +149,8 @@ grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)),
grub_envblk_iterate (envblk, NULL, set_var);
grub_free (envblk_s.buf);
+
+ return GRUB_ERR_NONE;
}
static grub_command_t export_cmd, loadenv_cmd;

View File

@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 15 Apr 2020 15:45:02 -0400
Subject: [PATCH] yylex: Make lexer fatal errors actually be fatal
When presented with a command that can't be tokenized to anything
smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
expecting that will stop further processing, as such:
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
if ( yyleng >= YYLMAX ) \
YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
yyg->yy_c_buf_p = yy_cp;
The code flex generates expects that YY_FATAL_ERROR() will either return
for it or do some form of longjmp(), or handle the error in some way at
least, and so the strncpy() call isn't in an "else" clause, and thus if
YY_FATAL_ERROR() is *not* actually fatal, it does the call with the
questionable limit, and predictable results ensue.
Unfortunately, our implementation of YY_FATAL_ERROR() is:
#define YY_FATAL_ERROR(msg) \
do { \
grub_printf (_("fatal error: %s\n"), _(msg)); \
} while (0)
The same pattern exists in yyless(), and similar problems exist in users
of YY_INPUT(), several places in the main parsing loop,
yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
yy_scan_buffer(), etc.
All of these callers expect YY_FATAL_ERROR() to actually be fatal, and
the things they do if it returns after calling it are wildly unsafe.
Fixes: CVE-2020-10713
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 926df817dc8
---
grub-core/script/yylex.l | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l
index 7b44c37b76f..b7203c82309 100644
--- a/grub-core/script/yylex.l
+++ b/grub-core/script/yylex.l
@@ -37,11 +37,11 @@
/*
* As we don't have access to yyscanner, we cannot do much except to
- * print the fatal error.
+ * print the fatal error and exit.
*/
#define YY_FATAL_ERROR(msg) \
do { \
- grub_printf (_("fatal error: %s\n"), _(msg)); \
+ grub_fatal (_("fatal error: %s\n"), _(msg));\
} while (0)
#define COPY(str, hint) \

View File

@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 15 Jun 2020 10:58:42 -0400
Subject: [PATCH] safemath: Add some arithmetic primitives that check for
overflow
This adds a new header, include/grub/safemath.h, that includes easy to
use wrappers for __builtin_{add,sub,mul}_overflow() declared like:
bool OP(a, b, res)
where OP is grub_add, grub_sub or grub_mul. OP() returns true in the
case where the operation would overflow and res is not modified.
Otherwise, false is returned and the operation is executed.
These arithmetic primitives require newer compiler versions. So, bump
these requirements in the INSTALL file too.
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: de1c315841a
---
include/grub/compiler.h | 8 ++++++++
include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++
INSTALL | 22 ++--------------------
3 files changed, 47 insertions(+), 20 deletions(-)
create mode 100644 include/grub/safemath.h
diff --git a/include/grub/compiler.h b/include/grub/compiler.h
index 9859ff4cc79..ebafec68957 100644
--- a/include/grub/compiler.h
+++ b/include/grub/compiler.h
@@ -48,6 +48,14 @@
# define WARN_UNUSED_RESULT
#endif
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+# define CLANG_PREREQ(maj,min) \
+ ((__clang_major__ > (maj)) || \
+ (__clang_major__ == (maj) && __clang_minor__ >= (min)))
+#else
+# define CLANG_PREREQ(maj,min) 0
+#endif
+
#define UNUSED __attribute__((__unused__))
#endif /* ! GRUB_COMPILER_HEADER */
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
new file mode 100644
index 00000000000..c17b89bba17
--- /dev/null
+++ b/include/grub/safemath.h
@@ -0,0 +1,37 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Arithmetic operations that protect against overflow.
+ */
+
+#ifndef GRUB_SAFEMATH_H
+#define GRUB_SAFEMATH_H 1
+
+#include <grub/compiler.h>
+
+/* These appear in gcc 5.1 and clang 3.8. */
+#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
+
+#define grub_add(a, b, res) __builtin_add_overflow(a, b, res)
+#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
+#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
+
+#else
+#error gcc 5.1 or newer or clang 3.8 or newer is required
+#endif
+
+#endif /* GRUB_SAFEMATH_H */
diff --git a/INSTALL b/INSTALL
index 8acb4090235..dcb9b7d7b7a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -11,27 +11,9 @@ GRUB depends on some software packages installed into your system. If
you don't have any of them, please obtain and install them before
configuring the GRUB.
-* GCC 4.1.3 or later
- Note: older versions may work but support is limited
-
- Experimental support for clang 3.3 or later (results in much bigger binaries)
+* GCC 5.1.0 or later
+ Experimental support for clang 3.8.0 or later (results in much bigger binaries)
for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
- Note: clang 3.2 or later works for i386 and x86_64 targets but results in
- much bigger binaries.
- earlier versions not tested
- Note: clang 3.2 or later works for arm
- earlier versions not tested
- Note: clang on arm64 is not supported due to
- https://llvm.org/bugs/show_bug.cgi?id=26030
- Note: clang 3.3 or later works for mips(el)
- earlier versions fail to generate .reginfo and hence gprel relocations
- fail.
- Note: clang 3.2 or later works for powerpc
- earlier versions not tested
- Note: clang 3.5 or later works for sparc64
- earlier versions return "error: unable to interface with target machine"
- Note: clang has no support for ia64 and hence you can't compile GRUB
- for ia64 with clang
* GNU Make
* GNU Bison 2.3 or later
* GNU gettext 0.17 or later

View File

@ -0,0 +1,240 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 15 Jun 2020 12:15:29 -0400
Subject: [PATCH] calloc: Make sure we always have an overflow-checking
calloc() available
This tries to make sure that everywhere in this source tree, we always have
an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
available, and that they all safely check for overflow and return NULL when
it would occur.
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 79e51ab7a9a
---
grub-core/kern/emu/misc.c | 12 ++++++++++++
grub-core/kern/emu/mm.c | 10 ++++++++++
grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++++++++++
grub-core/lib/libgcrypt_wrap/mem.c | 11 +++++++++--
grub-core/lib/posix_wrap/stdlib.h | 8 +++++++-
include/grub/emu/misc.h | 1 +
include/grub/mm.h | 6 ++++++
7 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
index 7a8d9e62300..f08a1bb8415 100644
--- a/grub-core/kern/emu/misc.c
+++ b/grub-core/kern/emu/misc.c
@@ -86,6 +86,18 @@ grub_util_error (const char *fmt, ...)
grub_exit (1);
}
+void *
+xcalloc (grub_size_t nmemb, grub_size_t size)
+{
+ void *p;
+
+ p = calloc (nmemb, size);
+ if (!p)
+ grub_util_error ("%s", _("out of memory"));
+
+ return p;
+}
+
void *
xmalloc (grub_size_t size)
{
diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
index f262e95e388..145b01d3719 100644
--- a/grub-core/kern/emu/mm.c
+++ b/grub-core/kern/emu/mm.c
@@ -25,6 +25,16 @@
#include <string.h>
#include <grub/i18n.h>
+void *
+grub_calloc (grub_size_t nmemb, grub_size_t size)
+{
+ void *ret;
+ ret = calloc (nmemb, size);
+ if (!ret)
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ return ret;
+}
+
void *
grub_malloc (grub_size_t size)
{
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
index 002cbfa4f3d..80d0720d005 100644
--- a/grub-core/kern/mm.c
+++ b/grub-core/kern/mm.c
@@ -67,8 +67,10 @@
#include <grub/dl.h>
#include <grub/i18n.h>
#include <grub/mm_private.h>
+#include <grub/safemath.h>
#ifdef MM_DEBUG
+# undef grub_calloc
# undef grub_malloc
# undef grub_zalloc
# undef grub_realloc
@@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size)
return 0;
}
+/*
+ * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
+ * integer overflow.
+ */
+void *
+grub_calloc (grub_size_t nmemb, grub_size_t size)
+{
+ void *ret;
+ grub_size_t sz = 0;
+
+ if (grub_mul (nmemb, size, &sz))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ return NULL;
+ }
+
+ ret = grub_memalign (0, sz);
+ if (!ret)
+ return NULL;
+
+ grub_memset (ret, 0, sz);
+ return ret;
+}
+
/* Allocate SIZE bytes and return the pointer. */
void *
grub_malloc (grub_size_t size)
@@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
grub_printf ("\n");
}
+void *
+grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size)
+{
+ void *ptr;
+
+ if (grub_mm_debug)
+ grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
+ file, line, size);
+ ptr = grub_calloc (nmemb, size);
+ if (grub_mm_debug)
+ grub_printf ("%p\n", ptr);
+ return ptr;
+}
+
void *
grub_debug_malloc (const char *file, int line, grub_size_t size)
{
diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
index beeb661a3c8..74c6eafe525 100644
--- a/grub-core/lib/libgcrypt_wrap/mem.c
+++ b/grub-core/lib/libgcrypt_wrap/mem.c
@@ -4,6 +4,7 @@
#include <grub/crypto.h>
#include <grub/dl.h>
#include <grub/env.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -36,7 +37,10 @@ void *
gcry_xcalloc (size_t n, size_t m)
{
void *ret;
- ret = grub_zalloc (n * m);
+ size_t sz;
+ if (grub_mul (n, m, &sz))
+ grub_fatal ("gcry_xcalloc would overflow");
+ ret = grub_zalloc (sz);
if (!ret)
grub_fatal ("gcry_xcalloc failed");
return ret;
@@ -56,7 +60,10 @@ void *
gcry_xcalloc_secure (size_t n, size_t m)
{
void *ret;
- ret = grub_zalloc (n * m);
+ size_t sz;
+ if (grub_mul (n, m, &sz))
+ grub_fatal ("gcry_xcalloc would overflow");
+ ret = grub_zalloc (sz);
if (!ret)
grub_fatal ("gcry_xcalloc failed");
return ret;
diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
index 3b46f47ff50..7a8d385e973 100644
--- a/grub-core/lib/posix_wrap/stdlib.h
+++ b/grub-core/lib/posix_wrap/stdlib.h
@@ -21,6 +21,7 @@
#include <grub/mm.h>
#include <grub/misc.h>
+#include <grub/safemath.h>
static inline void
free (void *ptr)
@@ -37,7 +38,12 @@ malloc (grub_size_t size)
static inline void *
calloc (grub_size_t size, grub_size_t nelem)
{
- return grub_zalloc (size * nelem);
+ grub_size_t sz;
+
+ if (grub_mul (size, nelem, &sz))
+ return NULL;
+
+ return grub_zalloc (sz);
}
static inline void *
diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
index 5ef4f79e689..01056954b96 100644
--- a/include/grub/emu/misc.h
+++ b/include/grub/emu/misc.h
@@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev);
#define GRUB_HOST_PRIuLONG_LONG "llu"
#define GRUB_HOST_PRIxLONG_LONG "llx"
+void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT;
void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT;
void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT;
char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT;
diff --git a/include/grub/mm.h b/include/grub/mm.h
index 28e2e53eb32..9c38dd3ca5d 100644
--- a/include/grub/mm.h
+++ b/include/grub/mm.h
@@ -29,6 +29,7 @@
#endif
void grub_mm_init_region (void *addr, grub_size_t size);
+void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
void EXPORT_FUNC(grub_free) (void *ptr);
@@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug);
void grub_mm_dump_free (void);
void grub_mm_dump (unsigned lineno);
+#define grub_calloc(nmemb, size) \
+ grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size)
+
#define grub_malloc(size) \
grub_debug_malloc (GRUB_FILE, __LINE__, size)
@@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno);
#define grub_free(ptr) \
grub_debug_free (GRUB_FILE, __LINE__, ptr)
+void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line,
+ grub_size_t nmemb, grub_size_t size);
void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
grub_size_t size);
void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sat, 4 Jul 2020 12:25:09 -0400
Subject: [PATCH] iso9660: Don't leak memory on realloc() failures
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: f2bd30b2fe7
---
grub-core/fs/iso9660.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
index 7ba5b300bc1..5ec4433b8f8 100644
--- a/grub-core/fs/iso9660.c
+++ b/grub-core/fs/iso9660.c
@@ -533,14 +533,20 @@ add_part (struct iterate_dir_ctx *ctx,
{
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
grub_size_t sz;
+ char *new;
if (grub_add (size, len2, &sz) ||
grub_add (sz, 1, &sz))
return;
- ctx->symlink = grub_realloc (ctx->symlink, sz);
- if (! ctx->symlink)
- return;
+ new = grub_realloc (ctx->symlink, sz);
+ if (!new)
+ {
+ grub_free (ctx->symlink);
+ ctx->symlink = NULL;
+ return;
+ }
+ ctx->symlink = new;
grub_memcpy (ctx->symlink + size, part, len2);
ctx->symlink[size + len2] = 0;
@@ -634,7 +640,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
is the length. Both are part of the `Component
Record'. */
if (ctx->symlink && !ctx->was_continue)
- add_part (ctx, "/", 1);
+ {
+ add_part (ctx, "/", 1);
+ if (grub_errno)
+ return grub_errno;
+ }
+
add_part (ctx, (char *) &entry->data[pos + 2],
entry->data[pos + 1]);
ctx->was_continue = (entry->data[pos] & 1);
@@ -653,6 +664,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
add_part (ctx, "/", 1);
break;
}
+
+ /* Check if grub_realloc() failed in add_part(). */
+ if (grub_errno)
+ return grub_errno;
+
/* In pos + 1 the length of the `Component Record' is
stored. */
pos += entry->data[pos + 1] + 2;

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Tue, 7 Jul 2020 15:36:26 +0200
Subject: [PATCH] font: Do not load more than one NAME section
The GRUB font file can have one NAME section only. Though if somebody
crafts a broken font file with many NAME sections and loads it then the
GRUB leaks memory. So, prevent against that by loading first NAME
section and failing in controlled way on following one.
Reported-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Upstream-commit-id: 482814113dc
---
grub-core/font/font.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 5edb477ac2e..d09bb38d896 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -532,6 +532,12 @@ grub_font_load (const char *filename)
if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
{
+ if (font->name != NULL)
+ {
+ grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections");
+ goto fail;
+ }
+
font->name = read_section_as_string (&section);
if (!font->name)
goto fail;

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 8 Jul 2020 20:41:56 +0000
Subject: [PATCH] gfxmenu: Fix double free in load_image()
self->bitmap should be zeroed after free. Otherwise, there is a chance
to double free (USE_AFTER_FREE) it later in rescale_image().
Fixes: CID 292472
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 5d3e84b15a4
---
grub-core/gfxmenu/gui_image.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c
index 29784ed2d9a..6b2e976f16e 100644
--- a/grub-core/gfxmenu/gui_image.c
+++ b/grub-core/gfxmenu/gui_image.c
@@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path)
return grub_errno;
if (self->bitmap && (self->bitmap != self->raw_bitmap))
- grub_video_bitmap_destroy (self->bitmap);
+ {
+ grub_video_bitmap_destroy (self->bitmap);
+ self->bitmap = 0;
+ }
if (self->raw_bitmap)
grub_video_bitmap_destroy (self->raw_bitmap);

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 8 Jul 2020 21:30:43 +0000
Subject: [PATCH] xnu: Fix double free in grub_xnu_devprop_add_property()
grub_xnu_devprop_add_property() should not free utf8 and utf16 as it get
allocated and freed in the caller.
Minor improvement: do prop fields initialization after memory allocations.
Fixes: CID 292442, CID 292457, CID 292460, CID 292466
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 4d5e2d13519
---
grub-core/loader/i386/xnu.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
index b7d176b5d30..e9e11925972 100644
--- a/grub-core/loader/i386/xnu.c
+++ b/grub-core/loader/i386/xnu.c
@@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
if (!prop)
return grub_errno;
+ prop->data = grub_malloc (datalen);
+ if (!prop->data)
+ {
+ grub_free (prop);
+ return grub_errno;
+ }
+ grub_memcpy (prop->data, data, datalen);
+
prop->name = utf8;
prop->name16 = utf16;
prop->name16len = utf16len;
-
prop->length = datalen;
- prop->data = grub_malloc (prop->length);
- if (!prop->data)
- {
- grub_free (prop->name);
- grub_free (prop->name16);
- grub_free (prop);
- return grub_errno;
- }
- grub_memcpy (prop->data, data, prop->length);
+
grub_list_push (GRUB_AS_LIST_P (&dev->properties),
GRUB_AS_LIST (prop));
return GRUB_ERR_NONE;

View File

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Thu, 9 Jul 2020 03:05:23 +0000
Subject: [PATCH] lzma: Make sure we don't dereference past array
The two dimensional array p->posSlotEncoder[4][64] is being dereferenced
using the GetLenToPosState() macro which checks if len is less than 5,
and if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294.
Obviously we don't want to dereference that far out so we check if the
position found is greater or equal kNumLenToPosStates (4) and bail out.
N.B.: Upstream LZMA 18.05 and later has this function completely rewritten
without any history.
Fixes: CID 51526
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: f91e043bda4
---
grub-core/lib/LzmaEnc.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c
index f2ec04a8c28..753e56a95e3 100644
--- a/grub-core/lib/LzmaEnc.c
+++ b/grub-core/lib/LzmaEnc.c
@@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
}
else
{
- UInt32 posSlot;
+ UInt32 posSlot, lenToPosState;
RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
p->state = kMatchNextStates[p->state];
LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
pos -= LZMA_NUM_REPS;
GetPosSlot(pos, posSlot);
- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+ lenToPosState = GetLenToPosState(len);
+ if (lenToPosState >= kNumLenToPosStates)
+ {
+ p->result = SZ_ERROR_DATA;
+ return CheckErrors(p);
+ }
+ RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{

View File

@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 7 Jul 2020 15:12:25 -0400
Subject: [PATCH] term: Fix overflow on user inputs
This requires a very weird input from the serial interface but can cause
an overflow in input_buf (keys) overwriting the next variable (npending)
with the user choice:
(pahole output)
struct grub_terminfo_input_state {
int input_buf[6]; /* 0 24 */
int npending; /* 24 4 */ <- CORRUPT
...snip...
The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
npending with "q" (aka increase npending to 161). The simplest fix is to
just to disallow overwrites input_buf, which exactly what this patch does.
Fixes: CID 292449
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 98dfa546777
---
grub-core/term/terminfo.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
index 537a5c0cb0b..44d0b3b19fb 100644
--- a/grub-core/term/terminfo.c
+++ b/grub-core/term/terminfo.c
@@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term)
}
static void
-grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
+grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len,
int (*readkey) (struct grub_term_input *term))
{
int c;
@@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
if (c == -1) \
return; \
\
+ if (*len >= max_len) \
+ return; \
+ \
keys[*len] = c; \
(*len)++; \
}
@@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi)
return ret;
}
- grub_terminfo_readkey (termi, data->input_buf,
- &data->npending, data->readkey);
+ grub_terminfo_readkey (termi, data->input_buf, &data->npending,
+ GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey);
#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 7 Jul 2020 22:02:31 -0400
Subject: [PATCH] udf: Fix memory leak
Fixes: CID 73796
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Upstream-commit-id: 8da62d8183c
---
grub-core/fs/udf.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
index 21ac7f4460d..2ac5c1d0048 100644
--- a/grub-core/fs/udf.c
+++ b/grub-core/fs/udf.c
@@ -965,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
return 0;
if (grub_udf_read_icb (dir->data, &dirent.icb, child))
- return 0;
-
+ {
+ grub_free (child);
+ return 0;
+ }
if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
{
/* This is the parent directory. */
@@ -988,11 +990,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
dirent.file_ident_length,
(char *) raw))
!= dirent.file_ident_length)
- return 0;
+ {
+ grub_free (child);
+ return 0;
+ }
filename = read_string (raw, dirent.file_ident_length, 0);
if (!filename)
- grub_print_error ();
+ {
+ /* As the hook won't get called. */
+ grub_free (child);
+ grub_print_error ();
+ }
if (filename && hook (filename, type, child, hook_data))
{

View File

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Fri, 26 Jun 2020 10:51:43 -0400
Subject: [PATCH] multiboot2: Fix memory leak if grub_create_loader_cmdline()
fails
Fixes: CID 292468
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: cd6760b6289
---
grub-core/loader/multiboot_mbi2.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 53da7861516..0efc660620e 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -1070,7 +1070,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
if (err)
- return err;
+ {
+ grub_free (newmod->cmdline);
+ grub_free (newmod);
+ return err;
+ }
if (modules_last)
modules_last->next = newmod;

View File

@ -0,0 +1,278 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Thu, 9 Jul 2020 08:10:40 +0000
Subject: [PATCH] tftp: Do not use priority queue
There is not need to reassemble the order of blocks. Per RFC 1350,
server must wait for the ACK, before sending next block. Data packets
can be served immediately without putting them to priority queue.
Logic to handle incoming packet is this:
- if packet block id equal to expected block id, then
process the packet,
- if packet block id is less than expected - this is retransmit
of old packet, then ACK it and drop the packet,
- if packet block id is more than expected - that shouldn't
happen, just drop the packet.
It makes the tftp receive path code simpler, smaller and faster.
As a benefit, this change fixes CID# 73624 and CID# 96690, caused
by following while loop:
while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
where tftph pointer is not moving from one iteration to another, causing
to serve same packet again. Luckily, double serving didn't happen due to
data->block++ during the first iteration.
Fixes: CID 73624, CID 96690
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 8316694c4f7
---
grub-core/net/tftp.c | 162 ++++++++++++++++-----------------------------------
1 file changed, 50 insertions(+), 112 deletions(-)
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
index e267af354f4..c2df3d7f6ab 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -25,7 +25,6 @@
#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/file.h>
-#include <grub/priority_queue.h>
#include <grub/i18n.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -106,31 +105,8 @@ typedef struct tftp_data
int have_oack;
struct grub_error_saved save_err;
grub_net_udp_socket_t sock;
- grub_priority_queue_t pq;
} *tftp_data_t;
-static int
-cmp_block (grub_uint16_t a, grub_uint16_t b)
-{
- grub_int16_t i = (grub_int16_t) (a - b);
- if (i > 0)
- return +1;
- if (i < 0)
- return -1;
- return 0;
-}
-
-static int
-cmp (const void *a__, const void *b__)
-{
- struct grub_net_buff *a_ = *(struct grub_net_buff **) a__;
- struct grub_net_buff *b_ = *(struct grub_net_buff **) b__;
- struct tftphdr *a = (struct tftphdr *) a_->data;
- struct tftphdr *b = (struct tftphdr *) b_->data;
- /* We want the first elements to be on top. */
- return -cmp_block (grub_be_to_cpu16 (a->u.data.block), grub_be_to_cpu16 (b->u.data.block));
-}
-
static grub_err_t
ack (tftp_data_t data, grub_uint64_t block)
{
@@ -207,73 +183,60 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
return GRUB_ERR_NONE;
}
- err = grub_priority_queue_push (data->pq, &nb);
- if (err)
- return err;
+ /* Ack old/retransmitted block. */
+ if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1)
+ ack (data, grub_be_to_cpu16 (tftph->u.data.block));
+ /* Ignore unexpected block. */
+ else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1)
+ grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block);
+ else
+ {
+ unsigned size;
- {
- struct grub_net_buff **nb_top_p, *nb_top;
- while (1)
- {
- nb_top_p = grub_priority_queue_top (data->pq);
- if (!nb_top_p)
- return GRUB_ERR_NONE;
- nb_top = *nb_top_p;
- tftph = (struct tftphdr *) nb_top->data;
- if (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) >= 0)
- break;
- ack (data, grub_be_to_cpu16 (tftph->u.data.block));
- grub_netbuff_free (nb_top);
- grub_priority_queue_pop (data->pq);
- }
- while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
- {
- unsigned size;
-
- grub_priority_queue_pop (data->pq);
-
- if (file->device->net->packs.count < 50)
+ if (file->device->net->packs.count < 50)
+ {
err = ack (data, data->block + 1);
- else
- {
- file->device->net->stall = 1;
- err = 0;
- }
- if (err)
- return err;
+ if (err)
+ return err;
+ }
+ else
+ file->device->net->stall = 1;
- err = grub_netbuff_pull (nb_top, sizeof (tftph->opcode) +
- sizeof (tftph->u.data.block));
- if (err)
- return err;
- size = nb_top->tail - nb_top->data;
+ err = grub_netbuff_pull (nb, sizeof (tftph->opcode) +
+ sizeof (tftph->u.data.block));
+ if (err)
+ return err;
+ size = nb->tail - nb->data;
- data->block++;
- if (size < data->block_size)
- {
- if (data->ack_sent < data->block)
- ack (data, data->block);
- file->device->net->eof = 1;
- file->device->net->stall = 1;
- grub_net_udp_close (data->sock);
- data->sock = NULL;
- }
- /* Prevent garbage in broken cards. Is it still necessary
- given that IP implementation has been fixed?
- */
- if (size > data->block_size)
- {
- err = grub_netbuff_unput (nb_top, size - data->block_size);
- if (err)
- return err;
- }
- /* If there is data, puts packet in socket list. */
- if ((nb_top->tail - nb_top->data) > 0)
- grub_net_put_packet (&file->device->net->packs, nb_top);
- else
- grub_netbuff_free (nb_top);
- }
- }
+ data->block++;
+ if (size < data->block_size)
+ {
+ if (data->ack_sent < data->block)
+ ack (data, data->block);
+ file->device->net->eof = 1;
+ file->device->net->stall = 1;
+ grub_net_udp_close (data->sock);
+ data->sock = NULL;
+ }
+ /*
+ * Prevent garbage in broken cards. Is it still necessary
+ * given that IP implementation has been fixed?
+ */
+ if (size > data->block_size)
+ {
+ err = grub_netbuff_unput (nb, size - data->block_size);
+ if (err)
+ return err;
+ }
+ /* If there is data, puts packet in socket list. */
+ if ((nb->tail - nb->data) > 0)
+ {
+ grub_net_put_packet (&file->device->net->packs, nb);
+ /* Do not free nb. */
+ return GRUB_ERR_NONE;
+ }
+ }
+ grub_netbuff_free (nb);
return GRUB_ERR_NONE;
case TFTP_ERROR:
data->have_oack = 1;
@@ -287,19 +250,6 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
}
}
-static void
-destroy_pq (tftp_data_t data)
-{
- struct grub_net_buff **nb_p;
- while ((nb_p = grub_priority_queue_top (data->pq)))
- {
- grub_netbuff_free (*nb_p);
- grub_priority_queue_pop (data->pq);
- }
-
- grub_priority_queue_destroy (data->pq);
-}
-
/* Create a normalized copy of the filename.
Compress any string of consecutive forward slashes to a single forward
slash. */
@@ -395,13 +345,6 @@ tftp_open (struct grub_file *file, const char *filename)
file->not_easily_seekable = 1;
file->data = data;
- data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp);
- if (!data->pq)
- {
- grub_free (data);
- return grub_errno;
- }
-
grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server);
err = grub_net_resolve_address (file->device->net->server, &addr);
if (err)
@@ -410,7 +353,6 @@ tftp_open (struct grub_file *file, const char *filename)
grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n",
(unsigned long long)data->file_size,
(unsigned long long)data->block_size);
- destroy_pq (data);
grub_free (data);
return err;
}
@@ -422,7 +364,6 @@ tftp_open (struct grub_file *file, const char *filename)
if (!data->sock)
{
grub_dprintf("tftp", "connection failed\n");
- destroy_pq (data);
grub_free (data);
return grub_errno;
}
@@ -436,7 +377,6 @@ tftp_open (struct grub_file *file, const char *filename)
if (err)
{
grub_net_udp_close (data->sock);
- destroy_pq (data);
grub_free (data);
return err;
}
@@ -453,7 +393,6 @@ tftp_open (struct grub_file *file, const char *filename)
if (grub_errno)
{
grub_net_udp_close (data->sock);
- destroy_pq (data);
grub_free (data);
return grub_errno;
}
@@ -496,7 +435,6 @@ tftp_close (struct grub_file *file)
grub_print_error ();
grub_net_udp_close (data->sock);
}
- destroy_pq (data);
grub_free (data);
return GRUB_ERR_NONE;
}

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lukasz Hawrylko <lukasz.hawrylko@linux.intel.com>
Date: Mon, 16 Dec 2019 11:15:55 +0100
Subject: [PATCH] multiboot2: Set min address for mbi allocation to 0x1000
In some cases GRUB2 allocates multiboot2 structure at 0 address, that is
a confusing behavior. Consumers of that structure can have internal NULL-checks
that will throw an error when get a pointer to data allocated at address 0.
To prevent that, define min address for mbi allocation on x86 and x86_64
platforms.
Signed-off-by: Lukasz Hawrylko <lukasz.hawrylko@linux.intel.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 0f3f5b7c13f
---
grub-core/loader/multiboot_mbi2.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 0efc660620e..e88c9f4884f 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -48,6 +48,12 @@
#define HAS_VGA_TEXT 0
#endif
+#if defined (__i386__) || defined (__x86_64__)
+#define MBI_MIN_ADDR 0x1000
+#else
+#define MBI_MIN_ADDR 0
+#endif
+
struct module
{
struct module *next;
@@ -708,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
- 0, 0xffffffff - bufsize,
+ MBI_MIN_ADDR, 0xffffffff - bufsize,
bufsize, MULTIBOOT_TAG_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)

View File

@ -0,0 +1,147 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 15 Jul 2020 06:42:37 +0000
Subject: [PATCH] relocator: Protect grub_relocator_alloc_chunk_addr() input
args against integer underflow/overflow
Use arithmetic macros from safemath.h to accomplish it. In this commit,
I didn't want to be too paranoid to check every possible math equation
for overflow/underflow. Only obvious places (with non zero chance of
overflow/underflow) were refactored.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: ebb15735f10
---
grub-core/loader/i386/linux.c | 9 +++++++--
grub-core/loader/i386/pc/linux.c | 9 +++++++--
grub-core/loader/i386/xen.c | 12 ++++++++++--
grub-core/loader/xnu.c | 11 +++++++----
4 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 201e6597c6d..90f2315f847 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -37,6 +37,7 @@
#include <grub/linux.h>
#include <grub/machine/kernel.h>
#include <grub/efi/sb.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -548,9 +549,13 @@ grub_linux_boot (void)
{
grub_relocator_chunk_t ch;
+ grub_size_t sz;
+
+ if (grub_add (ctx.real_size, efi_mmap_size, &sz))
+ return GRUB_ERR_OUT_OF_RANGE;
+
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
- ctx.real_mode_target,
- (ctx.real_size + efi_mmap_size));
+ ctx.real_mode_target, sz);
if (err)
return err;
real_mode_mem = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 0bf0e13d647..33d1196b1e2 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -36,6 +36,7 @@
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
#include <grub/efi/sb.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -231,8 +232,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
- grub_linux16_prot_size = grub_file_size (file)
- - real_size - GRUB_DISK_SECTOR_SIZE;
+ if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) ||
+ grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ goto fail;
+ }
if (! grub_linux_is_bzimage
&& GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size
diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index 8f662c8ac89..cd24874ca32 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -41,6 +41,7 @@
#include <grub/linux.h>
#include <grub/i386/memory.h>
#include <grub/verify.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -636,6 +637,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
grub_relocator_chunk_t ch;
grub_addr_t kern_start;
grub_addr_t kern_end;
+ grub_size_t sz;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -703,8 +705,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE);
- err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start,
- kern_end - kern_start);
+
+ if (grub_sub (kern_end, kern_start, &sz))
+ {
+ err = GRUB_ERR_OUT_OF_RANGE;
+ goto fail;
+ }
+
+ err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, sz);
if (err)
goto fail;
kern_chunk_src = get_virtual_current_address (ch);
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index 2f0ebd0b8bf..3fd653993f7 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -35,6 +35,7 @@
#include <grub/i18n.h>
#include <grub/verify.h>
#include <grub/efi/sb.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -60,15 +61,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
{
grub_err_t err;
grub_relocator_chunk_t ch;
+ grub_addr_t tgt;
+
+ if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt))
+ return GRUB_ERR_OUT_OF_RANGE;
- err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
- grub_xnu_heap_target_start
- + grub_xnu_heap_size, size);
+ err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size);
if (err)
return err;
*src = get_virtual_current_address (ch);
- *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
+ *target = tgt;
grub_xnu_heap_size += size;
grub_dprintf ("xnu", "val=%p\n", *src);
return GRUB_ERR_NONE;

View File

@ -0,0 +1,335 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 8 Jul 2020 01:44:38 +0000
Subject: [PATCH] relocator: Protect grub_relocator_alloc_chunk_align()
max_addr against integer underflow
This commit introduces integer underflow mitigation in max_addr calculation
in grub_relocator_alloc_chunk_align() invocation.
It consists of 2 fixes:
1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform
sanity check for min/max and size values, and to make safe invocation of
grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all
invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...)
by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...).
2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top
address (0xffffffff - size + 1) or similar.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 10498c8ba17
---
grub-core/lib/i386/relocator.c | 28 +++++++++++-----------------
grub-core/lib/mips/relocator.c | 6 ++----
grub-core/lib/powerpc/relocator.c | 6 ++----
grub-core/lib/x86_64/efi/relocator.c | 7 +++----
grub-core/loader/i386/linux.c | 5 ++---
grub-core/loader/i386/multiboot_mbi.c | 7 +++----
grub-core/loader/i386/pc/linux.c | 6 ++----
grub-core/loader/mips/linux.c | 9 +++------
grub-core/loader/multiboot.c | 2 +-
grub-core/loader/multiboot_elfxx.c | 10 +++++-----
grub-core/loader/multiboot_mbi2.c | 10 +++++-----
grub-core/loader/xnu_resume.c | 2 +-
include/grub/relocator.h | 29 +++++++++++++++++++++++++++++
13 files changed, 69 insertions(+), 58 deletions(-)
diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
index 71dd4f0ab0c..34cbe834fa3 100644
--- a/grub-core/lib/i386/relocator.c
+++ b/grub-core/lib/i386/relocator.c
@@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel,
/* Specific memory range due to Global Descriptor Table for use by payload
that we will store in returned chunk. The address range and preference
are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000,
- 0x9a000 - RELOCATOR_SIZEOF (32),
- RELOCATOR_SIZEOF (32), 16,
- GRUB_RELOCATOR_PREFERENCE_LOW,
- avoid_efi_bootservices);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000,
+ RELOCATOR_SIZEOF (32), 16,
+ GRUB_RELOCATOR_PREFERENCE_LOW,
+ avoid_efi_bootservices);
if (err)
return err;
@@ -125,13 +124,10 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator_chunk_t ch;
/* Put it higher than the byte it checks for A20 check. */
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
- 0xa0000 - RELOCATOR_SIZEOF (16)
- - GRUB_RELOCATOR16_STACK_SIZE,
- RELOCATOR_SIZEOF (16)
- + GRUB_RELOCATOR16_STACK_SIZE, 16,
- GRUB_RELOCATOR_PREFERENCE_NONE,
- 0);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000,
+ RELOCATOR_SIZEOF (16) +
+ GRUB_RELOCATOR16_STACK_SIZE, 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
@@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel,
void *relst;
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
- max_addr - RELOCATOR_SIZEOF (64),
- RELOCATOR_SIZEOF (64), 16,
- GRUB_RELOCATOR_PREFERENCE_NONE,
- 0);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr,
+ RELOCATOR_SIZEOF (64), 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c
index 9d5f49cb93a..743b213e695 100644
--- a/grub-core/lib/mips/relocator.c
+++ b/grub-core/lib/mips/relocator.c
@@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
unsigned i;
grub_addr_t vtarget;
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- (0xffffffff - stateset_size)
- + 1, stateset_size,
- sizeof (grub_uint32_t),
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
+ stateset_size, sizeof (grub_uint32_t),
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c
index bdf2b111be7..8ffb8b68683 100644
--- a/grub-core/lib/powerpc/relocator.c
+++ b/grub-core/lib/powerpc/relocator.c
@@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
unsigned i;
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- (0xffffffff - stateset_size)
- + 1, stateset_size,
- sizeof (grub_uint32_t),
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
+ stateset_size, sizeof (grub_uint32_t),
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c
index 3caef7a4021..7d200a125ee 100644
--- a/grub-core/lib/x86_64/efi/relocator.c
+++ b/grub-core/lib/x86_64/efi/relocator.c
@@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel,
* 64-bit relocator code may live above 4 GiB quite well.
* However, I do not want ask for problems. Just in case.
*/
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- 0x100000000 - RELOCATOR_SIZEOF (64_efi),
- RELOCATOR_SIZEOF (64_efi), 16,
- GRUB_RELOCATOR_PREFERENCE_NONE, 1);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000,
+ RELOCATOR_SIZEOF (64_efi), 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
return err;
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 90f2315f847..7d0c987cd91 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -182,9 +182,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
for (; err && *align + 1 > min_align; (*align)--)
{
grub_errno = GRUB_ERR_NONE;
- err = grub_relocator_alloc_chunk_align (relocator, &ch,
- 0x1000000,
- 0xffffffff & ~prot_size,
+ err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
+ UP_TO_TOP32 (prot_size),
prot_size, 1 << *align,
GRUB_RELOCATOR_PREFERENCE_LOW,
1);
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index ad3cc292fd1..a67d9d0a808 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -466,10 +466,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
bufsize = grub_multiboot_get_mbi_size ();
- err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
- 0x10000, 0xa0000 - bufsize,
- bufsize, 4,
- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
+ err = grub_relocator_alloc_chunk_align_safe (grub_multiboot_relocator, &ch,
+ 0x10000, 0xa0000, bufsize, 4,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
ptrorig = get_virtual_current_address (ch);
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 33d1196b1e2..f1ad185ddc2 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -463,10 +463,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
{
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (relocator, &ch,
- addr_min, addr_max - size,
- size, 0x1000,
- GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
+ err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size,
+ 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
if (err)
return err;
initrd_chunk = get_virtual_current_address (ch);
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
index 7b723bf189d..e4ed95921df 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
{
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (relocator, &ch,
- (target_addr & 0x1fffffff)
- + linux_size + 0x10000,
- (0x10000000 - size),
- size, 0x10000,
- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
+ err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) +
+ linux_size + 0x10000, 0x10000000, size,
+ 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
goto fail;
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index 3e6ad166dc9..3e286908dda 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -404,7 +404,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
- lowest_addr, (0xffffffff - size) + 1,
+ lowest_addr, UP_TO_TOP32 (size),
size, MULTIBOOT_MOD_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
index cc6853692a8..f2318e0d165 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
- err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
- mld->min_addr, mld->max_addr - load_size,
- load_size, mld->align ? mld->align : 1,
- mld->preference, mld->avoid_efi_boot_services);
+ err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch,
+ mld->min_addr, mld->max_addr,
+ load_size, mld->align ? mld->align : 1,
+ mld->preference, mld->avoid_efi_boot_services);
if (err)
{
@@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
continue;
err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0,
- (0xffffffff - sh->sh_size) + 1,
+ UP_TO_TOP32 (sh->sh_size),
sh->sh_size, sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE,
mld->avoid_efi_boot_services);
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index e88c9f4884f..9a943d7bdd7 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -301,10 +301,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename)
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
}
- err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
- mld.min_addr, mld.max_addr - code_size,
- code_size, mld.align ? mld.align : 1,
- mld.preference, keep_bs);
+ err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch,
+ mld.min_addr, mld.max_addr,
+ code_size, mld.align ? mld.align : 1,
+ mld.preference, keep_bs);
}
else
err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator,
@@ -714,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
- MBI_MIN_ADDR, 0xffffffff - bufsize,
+ MBI_MIN_ADDR, UP_TO_TOP32 (bufsize),
bufsize, MULTIBOOT_TAG_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
index 8089804d482..d648ef0cd3a 100644
--- a/grub-core/loader/xnu_resume.c
+++ b/grub-core/loader/xnu_resume.c
@@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename)
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
- (0xffffffff - hibhead.image_size) + 1,
+ UP_TO_TOP32 (hibhead.image_size),
hibhead.image_size,
GRUB_XNU_PAGESIZE,
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
diff --git a/include/grub/relocator.h b/include/grub/relocator.h
index 24d8672d22c..1b3bdd92ac6 100644
--- a/include/grub/relocator.h
+++ b/include/grub/relocator.h
@@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
int preference,
int avoid_efi_boot_services);
+/*
+ * Wrapper for grub_relocator_alloc_chunk_align() with purpose of
+ * protecting against integer underflow.
+ *
+ * Compare to its callee, max_addr has different meaning here.
+ * It covers entire chunk and not just start address of the chunk.
+ */
+static inline grub_err_t
+grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel,
+ grub_relocator_chunk_t *out,
+ grub_phys_addr_t min_addr,
+ grub_phys_addr_t max_addr,
+ grub_size_t size, grub_size_t align,
+ int preference,
+ int avoid_efi_boot_services)
+{
+ /* Sanity check and ensure following equation (max_addr - size) is safe. */
+ if (max_addr < size || (max_addr - size) < min_addr)
+ return GRUB_ERR_OUT_OF_RANGE;
+
+ return grub_relocator_alloc_chunk_align (rel, out, min_addr,
+ max_addr - size,
+ size, align, preference,
+ avoid_efi_boot_services);
+}
+
+/* Top 32-bit address minus s bytes and plus 1 byte. */
+#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1)
+
#define GRUB_RELOCATOR_PREFERENCE_NONE 0
#define GRUB_RELOCATOR_PREFERENCE_LOW 1
#define GRUB_RELOCATOR_PREFERENCE_HIGH 2

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Fri, 10 Jul 2020 11:21:14 +0100
Subject: [PATCH] script: Remove unused fields from grub_script_function struct
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: d04089c8e52
---
include/grub/script_sh.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
index 360c2be1f05..b382bcf09bc 100644
--- a/include/grub/script_sh.h
+++ b/include/grub/script_sh.h
@@ -359,13 +359,8 @@ struct grub_script_function
/* The script function. */
struct grub_script *func;
- /* The flags. */
- unsigned flags;
-
/* The next element. */
struct grub_script_function *next;
-
- int references;
};
typedef struct grub_script_function *grub_script_function_t;

View File

@ -0,0 +1,105 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Fri, 10 Jul 2020 14:41:45 +0100
Subject: [PATCH] script: Avoid a use-after-free when redefining a function
during execution
Defining a new function with the same name as a previously defined
function causes the grub_script and associated resources for the
previous function to be freed. If the previous function is currently
executing when a function with the same name is defined, this results
in use-after-frees when processing subsequent commands in the original
function.
Instead, reject a new function definition if it has the same name as
a previously defined function, and that function is currently being
executed. Although a behavioural change, this should be backwards
compatible with existing configurations because they can't be
dependent on the current behaviour without being broken.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: f6253a1f540
---
grub-core/script/execute.c | 2 ++
grub-core/script/function.c | 16 +++++++++++++---
include/grub/script_sh.h | 2 ++
grub-core/script/parser.y | 3 ++-
4 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index b55e171c931..d2f02cc5b38 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -872,7 +872,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
old_scope = scope;
scope = &new_scope;
+ func->executing++;
ret = grub_script_execute (func->func);
+ func->executing--;
function_return = 0;
active_loops = loops;
diff --git a/grub-core/script/function.c b/grub-core/script/function.c
index d36655e510f..3aad04bf9dd 100644
--- a/grub-core/script/function.c
+++ b/grub-core/script/function.c
@@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
func = (grub_script_function_t) grub_malloc (sizeof (*func));
if (! func)
return 0;
+ func->executing = 0;
func->name = grub_strdup (functionname_arg->str);
if (! func->name)
@@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
grub_script_function_t q;
q = *p;
- grub_script_free (q->func);
- q->func = cmd;
grub_free (func);
- func = q;
+ if (q->executing > 0)
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("attempt to redefine a function being executed"));
+ func = NULL;
+ }
+ else
+ {
+ grub_script_free (q->func);
+ q->func = cmd;
+ func = q;
+ }
}
else
{
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
index b382bcf09bc..6c48e075122 100644
--- a/include/grub/script_sh.h
+++ b/include/grub/script_sh.h
@@ -361,6 +361,8 @@ struct grub_script_function
/* The next element. */
struct grub_script_function *next;
+
+ unsigned executing;
};
typedef struct grub_script_function *grub_script_function_t;
diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y
index 4f0ab8319e3..f80b86b6f15 100644
--- a/grub-core/script/parser.y
+++ b/grub-core/script/parser.y
@@ -289,7 +289,8 @@ function: "function" "name"
grub_script_mem_free (state->func_mem);
else {
script->children = state->scripts;
- grub_script_function_create ($2, script);
+ if (!grub_script_function_create ($2, script))
+ grub_script_free (script);
}
state->scripts = $<scripts>3;

View File

@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 17 Jul 2020 05:17:26 +0000
Subject: [PATCH] relocator: Fix grub_relocator_alloc_chunk_align() top memory
allocation
Current implementation of grub_relocator_alloc_chunk_align()
does not allow allocation of the top byte.
Assuming input args are:
max_addr = 0xfffff000;
size = 0x1000;
And this is valid. But following overflow protection will
unnecessarily move max_addr one byte down (to 0xffffefff):
if (max_addr > ~size)
max_addr = ~size;
~size + 1 will fix the situation. In addition, check size
for non zero to do not zero max_addr.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: ab80a97eb1f
---
grub-core/lib/relocator.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
index 5847aac3643..f2c1944c28d 100644
--- a/grub-core/lib/relocator.c
+++ b/grub-core/lib/relocator.c
@@ -1386,8 +1386,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
};
grub_addr_t min_addr2 = 0, max_addr2;
- if (max_addr > ~size)
- max_addr = ~size;
+ if (size && (max_addr > ~size))
+ max_addr = ~size + 1;
#ifdef GRUB_MACHINE_PCBIOS
if (min_addr < 0x1000)

View File

@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 14:43:31 -0400
Subject: [PATCH] hfsplus: fix two more overflows
Both node->size and node->namelen come from the supplied filesystem,
which may be user-supplied. We can't trust them for the math unless we
know they don't overflow; making sure they go through calloc() first
will give us that.
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Upstream-commit-id: b4915078903
---
grub-core/fs/hfsplus.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index dae43becc97..9c4e4c88c99 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -31,6 +31,7 @@
#include <grub/hfs.h>
#include <grub/charset.h>
#include <grub/hfsplus.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -475,8 +476,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
{
char *symlink;
grub_ssize_t numread;
+ grub_size_t sz = node->size;
- symlink = grub_malloc (node->size + 1);
+ if (grub_add (sz, 1, &sz))
+ return NULL;
+
+ symlink = grub_malloc (sz);
if (!symlink)
return 0;
@@ -715,8 +720,8 @@ list_nodes (void *record, void *hook_arg)
if (type == GRUB_FSHELP_UNKNOWN)
return 0;
- filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
- * GRUB_MAX_UTF8_PER_UTF16 + 1);
+ filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen),
+ GRUB_MAX_UTF8_PER_UTF16 + 1);
if (! filename)
return 0;

View File

@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 15:48:20 -0400
Subject: [PATCH] lvm: fix two more potential data-dependent alloc overflows
It appears to be possible to make a (possibly invalid) lvm PV with a
metadata size field that overflows our type when adding it to the
address we've allocated. Even if it doesn't, it may be possible to do
so with the math using the outcome of that as an operand. Check them
both.
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Upstream-commit-id: 45ec6046ea0
---
grub-core/disk/lvm.c | 47 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 39 insertions(+), 8 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 8e76d1ae121..cca8ec668ba 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -25,6 +25,7 @@
#include <grub/lvm.h>
#include <grub/partition.h>
#include <grub/i18n.h>
+#include <grub/safemath.h>
#ifdef GRUB_UTIL
#include <grub/emu/misc.h>
@@ -102,10 +103,11 @@ grub_lvm_detect (grub_disk_t disk,
{
grub_err_t err;
grub_uint64_t mda_offset, mda_size;
+ grub_size_t ptr;
char buf[GRUB_LVM_LABEL_SIZE];
char vg_id[GRUB_LVM_ID_STRLEN+1];
char pv_id[GRUB_LVM_ID_STRLEN+1];
- char *metadatabuf, *vgname;
+ char *metadatabuf, *mda_end, *vgname;
const char *p, *q;
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
struct grub_lvm_pv_header *pvh;
@@ -206,19 +208,31 @@ grub_lvm_detect (grub_disk_t disk,
grub_le_to_cpu64 (rlocn->size) -
grub_le_to_cpu64 (mdah->size));
}
- p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
- while (*q != ' ' && q < metadatabuf + mda_size)
- q++;
-
- if (q == metadatabuf + mda_size)
+ if (grub_add ((grub_size_t)metadatabuf,
+ (grub_size_t)grub_le_to_cpu64 (rlocn->offset),
+ &ptr))
{
+error_parsing_metadata:
#ifdef GRUB_UTIL
grub_util_info ("error parsing metadata");
#endif
goto fail2;
}
+ p = q = (char *)ptr;
+
+ if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
+ goto error_parsing_metadata;
+
+ mda_end = (char *)ptr;
+
+ while (*q != ' ' && q < mda_end)
+ q++;
+
+ if (q == mda_end)
+ goto error_parsing_metadata;
+
vgname_len = q - p;
vgname = grub_malloc (vgname_len + 1);
if (!vgname)
@@ -368,8 +382,25 @@ grub_lvm_detect (grub_disk_t disk,
{
const char *iptr;
char *optr;
- lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
- + 1 + 2 * s + 1);
+
+ /* this is kind of hard to read with our safe (but rather
+ * baroque) math primatives, but it boils down to:
+ *
+ * sz0 = vgname_len * 2 + 1
+ * + s * 2 + 1
+ * + sizeof ("lvm/") - 1;
+ */
+ grub_size_t sz0 = vgname_len, sz1 = s;
+
+ if (grub_mul (sz0, 2, &sz0) ||
+ grub_add (sz0, 1, &sz0) ||
+ grub_mul (sz1, 2, &sz1) ||
+ grub_add (sz1, 1, &sz1) ||
+ grub_add (sz0, sz1, &sz0) ||
+ grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
+ goto lvs_fail;
+
+ lv->fullname = grub_malloc (sz0);
if (!lv->fullname)
goto lvs_fail;

View File

@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 16:08:08 -0400
Subject: [PATCH] emu: make grub_free(NULL) safe
The grub_free() implementation in kern/mm.c safely handles NULL
pointers, and code at many places depends on this. We don't know that
the same is true on all host OSes, so we need to handle the same
behavior in grub-emu's implementation.
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Upstream-commit-id: 96bb109e658
---
grub-core/kern/emu/mm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
index 145b01d3719..4d1046a219e 100644
--- a/grub-core/kern/emu/mm.c
+++ b/grub-core/kern/emu/mm.c
@@ -60,7 +60,8 @@ grub_zalloc (grub_size_t size)
void
grub_free (void *ptr)
{
- free (ptr);
+ if (ptr)
+ free (ptr);
}
void *

View File

@ -0,0 +1,248 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 16:53:27 -0400
Subject: [PATCH] efi: fix some malformed device path arithmetic errors.
Several places we take the length of a device path and subtract 4 from
it, without ever checking that it's >= 4. There are also cases where
this kind of malformation will result in unpredictable iteration,
including treating the length from one dp node as the type in the next
node. These are all errors, no matter where the data comes from.
This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
the length is too small. Additionally, it makes several places in the
code check for and return errors in these cases.
Signed-off-by: Peter Jones <pjones@redhat.com>
Upstream-commit-id: 23e68a83990
---
grub-core/kern/efi/efi.c | 67 ++++++++++++++++++++++++++++++++------
grub-core/loader/efi/chainloader.c | 19 +++++++++--
grub-core/loader/i386/xnu.c | 9 ++---
include/grub/efi/api.h | 14 +++++---
4 files changed, 88 insertions(+), 21 deletions(-)
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index ab133fecce0..8c09e60987d 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -350,7 +350,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
dp = dp0;
- while (1)
+ while (dp)
{
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
@@ -360,9 +360,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
&& subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
{
- grub_efi_uint16_t len;
- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
- / sizeof (grub_efi_char16_t));
+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+
+ if (len < 4)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "malformed EFI Device Path node has length=%d", len);
+ return NULL;
+ }
+ len = (len - 4) / sizeof (grub_efi_char16_t);
filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
}
@@ -378,7 +384,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
if (!name)
return NULL;
- while (1)
+ while (dp)
{
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
@@ -394,8 +400,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
*p++ = '/';
- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
- / sizeof (grub_efi_char16_t));
+ len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+ if (len < 4)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "malformed EFI Device Path node has length=%d", len);
+ return NULL;
+ }
+
+ len = (len - 4) / sizeof (grub_efi_char16_t);
fp = (grub_efi_file_path_device_path_t *) dp;
/* According to EFI spec Path Name is NULL terminated */
while (len > 0 && fp->path_name[len - 1] == 0)
@@ -470,7 +483,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
;
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
{
- total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+ grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p);
+
+ /*
+ * In the event that we find a node that's completely garbage, for
+ * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size
+ * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and
+ * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue,
+ * and neither should our consumers, but there won't be any error raised
+ * even though the device path is junk.
+ *
+ * This keeps us from passing junk down back to our caller.
+ */
+ if (len < 4)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "malformed EFI Device Path node has length=%d", len);
+ return NULL;
+ }
+
+ total_size += len;
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
break;
}
@@ -515,7 +547,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
void
grub_efi_print_device_path (grub_efi_device_path_t *dp)
{
- while (1)
+ while (GRUB_EFI_DEVICE_PATH_VALID (dp))
{
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
@@ -987,7 +1019,11 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
/* Return non-zero. */
return 1;
- while (1)
+ if (dp1 == dp2)
+ return 0;
+
+ while (GRUB_EFI_DEVICE_PATH_VALID (dp1)
+ && GRUB_EFI_DEVICE_PATH_VALID (dp2))
{
grub_efi_uint8_t type1, type2;
grub_efi_uint8_t subtype1, subtype2;
@@ -1023,5 +1059,16 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
}
+ /*
+ * There's no "right" answer here, but we probably don't want to call a valid
+ * dp and an invalid dp equal, so pick one way or the other.
+ */
+ if (GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
+ !GRUB_EFI_DEVICE_PATH_VALID (dp2))
+ return 1;
+ else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
+ GRUB_EFI_DEVICE_PATH_VALID (dp2))
+ return -1;
+
return 0;
}
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 736505173cb..5f7c6cfe105 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -125,6 +125,12 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
+ if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
+ return;
+ }
+
path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
if (!path_name)
return;
@@ -165,9 +171,18 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
size = 0;
d = dp;
- while (1)
+ while (d)
{
- size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
+ grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (d);
+
+ if (len < 4)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "malformed EFI Device Path node has length=%d", len);
+ return NULL;
+ }
+
+ size += len;
if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
break;
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
index e9e11925972..a7009360732 100644
--- a/grub-core/loader/i386/xnu.c
+++ b/grub-core/loader/i386/xnu.c
@@ -515,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
devhead = buf;
buf = devhead + 1;
- dpstart = buf;
+ dp = dpstart = buf;
- do
+ while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend)
{
- dp = buf;
buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+ break;
+ dp = buf;
}
- while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
- (char *) dpstart);
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index dec7b06083e..fc8a564e94d 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -666,6 +666,7 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
+#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4)
/* The End of Device Path nodes. */
#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
@@ -674,13 +675,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
- (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
- && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
- == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+ (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \
+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)))
#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
- ((grub_efi_device_path_t *) ((char *) (dp) \
- + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+ (GRUB_EFI_DEVICE_PATH_VALID (dp) \
+ ? ((grub_efi_device_path_t *) \
+ ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \
+ : NULL)
/* Hardware Device Path. */
#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1

View File

@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Wed, 22 Jul 2020 17:06:04 +0100
Subject: [PATCH] Fix a regression caused by "efi: fix some malformed device
path arithmetic errors"
This commit introduced a bogus check inside copy_file_path to
determine whether the destination grub_efi_file_path_device_path_t
was valid before anything was copied to it. Depending on the
contents of the heap buffer, this check could fail which would
result in copy_file_path returning early.
Without any error propagated to the caller, make_file_path would
then try to advance the invalid device path node with
GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL
pointer that would subsequently be dereferenced.
Remove the bogus check, and also propagate errors from copy_file_path.
---
grub-core/loader/efi/chainloader.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 5f7c6cfe105..3dfa41bb49d 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -115,7 +115,7 @@ grub_chainloader_boot (void)
return grub_errno;
}
-static void
+static grub_err_t
copy_file_path (grub_efi_file_path_device_path_t *fp,
const char *str, grub_efi_uint16_t len)
{
@@ -125,15 +125,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
- if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
- {
- grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
- return;
- }
-
path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
if (!path_name)
- return;
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
(const grub_uint8_t *) str, len, 0);
@@ -146,6 +140,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->path_name[size++] = '\0';
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
grub_free (path_name);
+ return GRUB_ERR_NONE;
}
static grub_efi_device_path_t *
@@ -203,13 +198,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
/* Fill the file path for the directory. */
d = (grub_efi_device_path_t *) ((char *) file_path
+ ((char *) d - (char *) dp));
- copy_file_path ((grub_efi_file_path_device_path_t *) d,
- dir_start, dir_end - dir_start);
+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
+ dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
+ {
+ fail:
+ grub_free (file_path);
+ return 0;
+ }
/* Fill the file path for the file. */
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
- copy_file_path ((grub_efi_file_path_device_path_t *) d,
- dir_end + 1, grub_strlen (dir_end + 1));
+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
+ dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
+ goto fail;
/* Fill the end of device path nodes. */
d = GRUB_EFI_NEXT_DEVICE_PATH (d);

View File

@ -0,0 +1,162 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Mon, 20 Jul 2020 23:03:05 +0000
Subject: [PATCH] efi: Fix use-after-free in halt/reboot path
commit 92bfc33db984 ("efi: Free malloc regions on exit")
introduced memory freeing in grub_efi_fini(), which is
used not only by exit path but by halt/reboot one as well.
As result of memory freeing, code and data regions used by
modules, such as halt, reboot, acpi (used by halt) also got
freed. After return to module code, CPU executes, filled
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
a code. Which leads to #UD exception later.
grub> halt
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
RSI - 00000000064DB768, RDI - 000000000832C5C3
R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
R14 - 0000000003E10D80, R15 - 00000000061E2F60
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 0000000007F0F4C0
Proposal here is to continue to free allocated memory for
exit boot services path but keep it for halt/reboot path
as it won't be much security concern here.
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
loader flag to be used by efi halt/reboot path.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
---
grub-core/kern/arm/efi/init.c | 3 +++
grub-core/kern/arm64/efi/init.c | 3 +++
grub-core/kern/efi/efi.c | 3 ++-
grub-core/kern/efi/init.c | 1 -
grub-core/kern/i386/efi/init.c | 9 +++++++--
grub-core/kern/ia64/efi/init.c | 9 +++++++--
grub-core/lib/efi/halt.c | 3 ++-
include/grub/loader.h | 1 +
8 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
index 06df60e2f0e..40c3b467fc6 100644
--- a/grub-core/kern/arm/efi/init.c
+++ b/grub-core/kern/arm/efi/init.c
@@ -71,4 +71,7 @@ grub_machine_fini (int flags)
efi_call_1 (b->close_event, tmr_evt);
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c
index 6224999ec9c..5010caefd66 100644
--- a/grub-core/kern/arm64/efi/init.c
+++ b/grub-core/kern/arm64/efi/init.c
@@ -57,4 +57,7 @@ grub_machine_fini (int flags)
return;
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index 8c09e60987d..5ee739d51ae 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
void
grub_reboot (void)
{
- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
for (;;) ;
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index d1afa3af11e..2ffb5205dda 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -131,5 +131,4 @@ grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_console_fini ();
- grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
index da499aba04e..deb2eacd8d8 100644
--- a/grub-core/kern/i386/efi/init.c
+++ b/grub-core/kern/i386/efi/init.c
@@ -39,6 +39,11 @@ grub_machine_init (void)
void
grub_machine_fini (int flags)
{
- if (flags & GRUB_LOADER_FLAG_NORETURN)
- grub_efi_fini ();
+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+ return;
+
+ grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c
index b5ecbd09121..f1965571b1d 100644
--- a/grub-core/kern/ia64/efi/init.c
+++ b/grub-core/kern/ia64/efi/init.c
@@ -70,6 +70,11 @@ grub_machine_init (void)
void
grub_machine_fini (int flags)
{
- if (flags & GRUB_LOADER_FLAG_NORETURN)
- grub_efi_fini ();
+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+ return;
+
+ grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
index 5859f0498a8..29d41364168 100644
--- a/grub-core/lib/efi/halt.c
+++ b/grub-core/lib/efi/halt.c
@@ -28,7 +28,8 @@
void
grub_halt (void)
{
- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \
!defined(__riscv)
grub_acpi_halt ();
diff --git a/include/grub/loader.h b/include/grub/loader.h
index 7f82a499fd9..b208642821b 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -33,6 +33,7 @@ enum
{
GRUB_LOADER_FLAG_NORETURN = 1,
GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2,
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4,
};
void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 17:11:06 -0400
Subject: [PATCH] efi+dhcp: fix some allocation error checking.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/dhcp.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/grub-core/net/efi/dhcp.c b/grub-core/net/efi/dhcp.c
index dbef63d8c08..e5c79b748b0 100644
--- a/grub-core/net/efi/dhcp.c
+++ b/grub-core/net/efi/dhcp.c
@@ -80,7 +80,7 @@ grub_efi_dhcp4_parse_dns (grub_efi_dhcp4_protocol_t *dhcp4, grub_efi_dhcp4_packe
if (status != GRUB_EFI_BUFFER_TOO_SMALL)
return NULL;
- option_list = grub_malloc (option_count * sizeof(*option_list));
+ option_list = grub_calloc (option_count, sizeof(*option_list));
if (!option_list)
return NULL;
@@ -360,8 +360,11 @@ grub_cmd_efi_bootp6 (struct grub_command *cmd __attribute__ ((unused)),
if (status == GRUB_EFI_BUFFER_TOO_SMALL && count)
{
- options = grub_malloc (count * sizeof(*options));
- status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options);
+ options = grub_calloc (count, sizeof(*options));
+ if (options)
+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options);
+ else
+ status = GRUB_EFI_OUT_OF_RESOURCES;
}
if (status != GRUB_EFI_SUCCESS)

View File

@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 17:14:15 -0400
Subject: [PATCH] efi+http: fix some allocation error checking.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/http.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c
index fc8cb25ae0a..26647a50fa4 100644
--- a/grub-core/net/efi/http.c
+++ b/grub-core/net/efi/http.c
@@ -412,8 +412,8 @@ grub_efihttp_open (struct grub_efi_net_device *dev,
int type)
{
grub_err_t err;
- grub_off_t size;
- char *buf;
+ grub_off_t size = 0;
+ char *buf = NULL;
char *file_name = NULL;
const char *http_path;
@@ -441,8 +441,11 @@ grub_efihttp_open (struct grub_efi_net_device *dev,
return err;
}
- buf = grub_malloc (size);
- efihttp_read (dev, buf, size);
+ if (size)
+ {
+ buf = grub_malloc (size);
+ efihttp_read (dev, buf, size);
+ }
file->size = size;
file->data = buf;

View File

@ -0,0 +1,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 17:27:00 -0400
Subject: [PATCH] efi/ip[46]_config.c: fix some potential allocation overflows
In theory all of this data comes from the firmware stack and it should
be safe, but it's better to be paranoid.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/ip4_config.c | 25 ++++++++++++++++++-------
grub-core/net/efi/ip6_config.c | 13 ++++++++++---
2 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c
index 313c818b184..9725e928f7e 100644
--- a/grub-core/net/efi/ip4_config.c
+++ b/grub-core/net/efi/ip4_config.c
@@ -4,15 +4,20 @@
#include <grub/misc.h>
#include <grub/net/efi.h>
#include <grub/charset.h>
+#include <grub/safemath.h>
char *
grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address)
{
char *hw_addr, *p;
- int sz, s;
- int i;
+ grub_size_t sz, s, i;
- sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1;
+ if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) ||
+ grub_add (sz, 1, &sz))
+ {
+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
+ return NULL;
+ }
hw_addr = grub_malloc (sz);
if (!hw_addr)
@@ -20,7 +25,7 @@ grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_a
p = hw_addr;
s = sz;
- for (i = 0; i < (int)hw_address_size; i++)
+ for (i = 0; i < hw_address_size; i++)
{
grub_snprintf (p, sz, "%02x:", hw_address[i]);
p += sizeof ("XX:") - 1;
@@ -238,14 +243,20 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev)
{
grub_efi_ip4_config2_interface_info_t *interface_info;
char **ret;
- int i, id;
+ int id;
+ grub_size_t i, nmemb;
interface_info = efi_ip4_config_interface_info (dev->ip4_config);
if (!interface_info)
return NULL;
- ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1));
+ if (grub_add (interface_info->route_table_size, 1, &nmemb))
+ {
+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
+ return NULL;
+ }
+ ret = grub_calloc (nmemb, sizeof (*ret));
if (!ret)
{
grub_free (interface_info);
@@ -253,7 +264,7 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev)
}
id = 0;
- for (i = 0; i < (int)interface_info->route_table_size; i++)
+ for (i = 0; i < interface_info->route_table_size; i++)
{
char *subnet, *gateway, *mask;
grub_uint32_t u32_subnet, u32_gateway;
diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c
index 017c4d05bc7..a46f6f9b685 100644
--- a/grub-core/net/efi/ip6_config.c
+++ b/grub-core/net/efi/ip6_config.c
@@ -3,6 +3,7 @@
#include <grub/misc.h>
#include <grub/net/efi.h>
#include <grub/charset.h>
+#include <grub/safemath.h>
char *
grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address)
@@ -228,14 +229,20 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev)
{
grub_efi_ip6_config_interface_info_t *interface_info;
char **ret;
- int i, id;
+ int id;
+ grub_size_t i, nmemb;
interface_info = efi_ip6_config_interface_info (dev->ip6_config);
if (!interface_info)
return NULL;
- ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1));
+ if (grub_add (interface_info->route_count, 1, &nmemb))
+ {
+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
+ return NULL;
+ }
+ ret = grub_calloc (nmemb, sizeof (*ret));
if (!ret)
{
grub_free (interface_info);
@@ -243,7 +250,7 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev)
}
id = 0;
- for (i = 0; i < (int)interface_info->route_count ; i++)
+ for (i = 0; i < interface_info->route_count ; i++)
{
char *gateway, *destination;
grub_uint64_t u64_gateway[2];

View File

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@debian.org>
Date: Fri, 24 Jul 2020 17:18:09 +0100
Subject: [PATCH] efilinux: Fix integer overflows in grub_cmd_initrd
These could be triggered by an extremely large number of arguments to
the initrd command on 32-bit architectures, or a crafted filesystem with
very large files on any architecture.
Signed-off-by: Colin Watson <cjwatson@debian.org>
---
grub-core/loader/i386/efi/linux.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index e5b2736b0ce..c0a98d152ff 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -28,6 +28,8 @@
#include <grub/efi/efi.h>
#include <grub/efi/linux.h>
#include <grub/cpu/efi/memory.h>
+#include <grub/tpm.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -206,7 +208,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- files = grub_zalloc (argc * sizeof (files[0]));
+ files = grub_calloc (argc, sizeof (files[0]));
if (!files)
goto fail;
@@ -216,7 +218,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
if (! files[i])
goto fail;
nfiles++;
- size += ALIGN_UP (grub_file_size (files[i]), 4);
+ if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ goto fail;
+ }
}
initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));

View File

@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Mon, 20 Jul 2020 23:03:05 +0000
Subject: [PATCH] efi: Fix use-after-free in halt/reboot path
commit 92bfc33db984 ("efi: Free malloc regions on exit")
introduced memory freeing in grub_efi_fini(), which is
used not only by exit path but by halt/reboot one as well.
As result of memory freeing, code and data regions used by
modules, such as halt, reboot, acpi (used by halt) also got
freed. After return to module code, CPU executes, filled
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
a code. Which leads to #UD exception later.
grub> halt
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
RSI - 00000000064DB768, RDI - 000000000832C5C3
R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
R14 - 0000000003E10D80, R15 - 00000000061E2F60
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 0000000007F0F4C0
Proposal here is to continue to free allocated memory for
exit boot services path but keep it for halt/reboot path
as it won't be much security concern here.
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
loader flag to be used by efi halt/reboot path.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
---
grub-core/kern/riscv/efi/init.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
index 7eb1969d0b0..38795fe6741 100644
--- a/grub-core/kern/riscv/efi/init.c
+++ b/grub-core/kern/riscv/efi/init.c
@@ -73,4 +73,7 @@ grub_machine_fini (int flags)
return;
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}

View File

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Fri, 24 Jul 2020 13:57:27 -0400
Subject: [PATCH] linux loader: avoid overflow on initrd size calculation
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/loader/linux.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
index 471b214d6c3..25624ebc114 100644
--- a/grub-core/loader/linux.c
+++ b/grub-core/loader/linux.c
@@ -151,8 +151,8 @@ grub_initrd_init (int argc, char *argv[],
initrd_ctx->nfiles = 0;
initrd_ctx->components = 0;
- initrd_ctx->components = grub_zalloc (argc
- * sizeof (initrd_ctx->components[0]));
+ initrd_ctx->components = grub_calloc (argc,
+ sizeof (initrd_ctx->components[0]));
if (!initrd_ctx->components)
return grub_errno;

View File

@ -0,0 +1,130 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Wed, 22 Jul 2020 11:31:43 +0100
Subject: [PATCH] linuxefi: fail kernel validation without shim protocol.
If certificates that signed grub are installed into db, grub can be
booted directly. It will then boot any kernel without signature
validation. The booted kernel will think it was booted in secureboot
mode and will implement lockdown, yet it could have been tampered.
This version of the patch skips calling verification, when booted
without secureboot. And is indented with gnu ident.
CVE-2020-15705
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
---
grub-core/loader/arm64/linux.c | 13 +++++++++----
grub-core/loader/efi/chainloader.c | 1 +
grub-core/loader/efi/linux.c | 1 +
grub-core/loader/i386/efi/linux.c | 17 +++++++++++------
4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 8791b35b6fe..720eec075cd 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -34,6 +34,7 @@
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#include <grub/verify.h>
+#include <grub/efi/sb.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -383,11 +384,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
- if (rc < 0)
+ if (grub_efi_secure_boot ())
{
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
- goto fail;
+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
+ if (rc <= 0)
+ {
+ grub_error (GRUB_ERR_INVALID_COMMAND,
+ N_("%s has invalid signature"), argv[0]);
+ goto fail;
+ }
}
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 3dfa41bb49d..26f4fa9dc6a 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -1083,6 +1083,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
return 0;
}
+ // -1 fall-through to fail
fail:
if (dev)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index e09f824862b..927d89a90d7 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
};
typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+// Returns 1 on success, -1 on error, 0 when not available
int
grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
{
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index c0a98d152ff..60ef7d12f07 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -30,6 +30,7 @@
#include <grub/cpu/efi/memory.h>
#include <grub/tpm.h>
#include <grub/safemath.h>
+#include <grub/efi/sb.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -101,7 +102,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
pages = BYTES_TO_PAGES(size);
grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
- pages, (void *)max);
+ (unsigned long)pages, (void *)(unsigned long)max);
prev_max = max;
addr = grub_efi_allocate_pages_real (max, pages,
@@ -307,12 +308,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- rc = grub_linuxefi_secure_validate (kernel, filelen);
- if (rc < 0)
+ if (grub_efi_secure_boot ())
{
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
- argv[0]);
- goto fail;
+ rc = grub_linuxefi_secure_validate (kernel, filelen);
+ if (rc <= 0)
+ {
+ grub_error (GRUB_ERR_INVALID_COMMAND,
+ N_("%s has invalid signature"), argv[0]);
+ goto fail;
+ }
}
lh = (struct linux_i386_kernel_header *)kernel;
@@ -386,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201);
grub_dprintf ("linux", "copying %lu bytes from %p to %p\n",
+ (unsigned long)
MIN((grub_size_t)0x202+setup_header_end_offset,
sizeof (*params)) - 0x1f1,
(grub_uint8_t *)kernel + 0x1f1,

View File

@ -0,0 +1,166 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@debian.org>
Date: Sat, 25 Jul 2020 12:15:37 +0100
Subject: [PATCH] linux: Fix integer overflows in initrd size handling
These could be triggered by a crafted filesystem with very large files.
Fixes: CVE-2020-15707
Signed-off-by: Colin Watson <cjwatson@debian.org>
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
---
grub-core/loader/linux.c | 75 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 55 insertions(+), 20 deletions(-)
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
index 25624ebc114..1af142f5760 100644
--- a/grub-core/loader/linux.c
+++ b/grub-core/loader/linux.c
@@ -4,6 +4,8 @@
#include <grub/misc.h>
#include <grub/file.h>
#include <grub/mm.h>
+#include <grub/tpm.h>
+#include <grub/safemath.h>
struct newc_head
{
@@ -98,13 +100,13 @@ free_dir (struct dir *root)
grub_free (root);
}
-static grub_size_t
+static grub_err_t
insert_dir (const char *name, struct dir **root,
- grub_uint8_t *ptr)
+ grub_uint8_t *ptr, grub_size_t *size)
{
struct dir *cur, **head = root;
const char *cb, *ce = name;
- grub_size_t size = 0;
+ *size = 0;
while (1)
{
for (cb = ce; *cb == '/'; cb++);
@@ -130,14 +132,22 @@ insert_dir (const char *name, struct dir **root,
ptr = make_header (ptr, name, ce - name,
040777, 0);
}
- size += ALIGN_UP ((ce - (char *) name)
- + sizeof (struct newc_head), 4);
+ if (grub_add (*size,
+ ALIGN_UP ((ce - (char *) name)
+ + sizeof (struct newc_head), 4),
+ size))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
+ grub_free (n->name);
+ grub_free (n);
+ return grub_errno;
+ }
*head = n;
cur = n;
}
root = &cur->next;
}
- return size;
+ return GRUB_ERR_NONE;
}
grub_err_t
@@ -173,26 +183,33 @@ grub_initrd_init (int argc, char *argv[],
eptr = grub_strchr (ptr, ':');
if (eptr)
{
+ grub_size_t dir_size, name_len;
+
initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
- if (!initrd_ctx->components[i].newc_name)
+ if (!initrd_ctx->components[i].newc_name ||
+ insert_dir (initrd_ctx->components[i].newc_name, &root, 0,
+ &dir_size))
{
grub_initrd_close (initrd_ctx);
return grub_errno;
}
- initrd_ctx->size
- += ALIGN_UP (sizeof (struct newc_head)
- + grub_strlen (initrd_ctx->components[i].newc_name),
- 4);
- initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
- &root, 0);
+ name_len = grub_strlen (initrd_ctx->components[i].newc_name);
+ if (grub_add (initrd_ctx->size,
+ ALIGN_UP (sizeof (struct newc_head) + name_len, 4),
+ &initrd_ctx->size) ||
+ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size))
+ goto overflow;
newc = 1;
fname = eptr + 1;
}
}
else if (newc)
{
- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
- + sizeof ("TRAILER!!!") - 1, 4);
+ if (grub_add (initrd_ctx->size,
+ ALIGN_UP (sizeof (struct newc_head)
+ + sizeof ("TRAILER!!!") - 1, 4),
+ &initrd_ctx->size))
+ goto overflow;
free_dir (root);
root = 0;
newc = 0;
@@ -208,19 +225,29 @@ grub_initrd_init (int argc, char *argv[],
initrd_ctx->nfiles++;
initrd_ctx->components[i].size
= grub_file_size (initrd_ctx->components[i].file);
- initrd_ctx->size += initrd_ctx->components[i].size;
+ if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size,
+ &initrd_ctx->size))
+ goto overflow;
}
if (newc)
{
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
- + sizeof ("TRAILER!!!") - 1, 4);
+ if (grub_add (initrd_ctx->size,
+ ALIGN_UP (sizeof (struct newc_head)
+ + sizeof ("TRAILER!!!") - 1, 4),
+ &initrd_ctx->size))
+ goto overflow;
free_dir (root);
root = 0;
}
return GRUB_ERR_NONE;
+
+overflow:
+ free_dir (root);
+ grub_initrd_close (initrd_ctx);
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
}
grub_size_t
@@ -261,8 +288,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
if (initrd_ctx->components[i].newc_name)
{
- ptr += insert_dir (initrd_ctx->components[i].newc_name,
- &root, ptr);
+ grub_size_t dir_size;
+
+ if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr,
+ &dir_size))
+ {
+ free_dir (root);
+ grub_initrd_close (initrd_ctx);
+ return grub_errno;
+ }
+ ptr += dir_size;
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
grub_strlen (initrd_ctx->components[i].newc_name),
0100777,

View File

@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/commands/blscfg.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/commands/blscfg.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index 4ec6504d9a4..e907a6a5d28 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -612,7 +612,7 @@ static char **bls_make_list (struct bls_entry *entry, const char *key, int *num)
return list;
}
-static char *field_append(bool is_var, char *buffer, char *start, char *end)
+static char *field_append(bool is_var, char *buffer, const char *start, const char *end)
{
char *tmp = grub_strndup(start, end - start + 1);
const char *field = tmp;
@@ -641,11 +641,11 @@ static char *field_append(bool is_var, char *buffer, char *start, char *end)
return buffer;
}
-static char *expand_val(char *value)
+static char *expand_val(const char *value)
{
char *buffer = NULL;
- char *start = value;
- char *end = value;
+ const char *start = value;
+ const char *end = value;
bool is_var = false;
if (!value)

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/bootp.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/bootp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 5a5ebbfb1aa..2658a0cda4e 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -365,7 +365,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
struct grub_net_network_level_interface *inter;
int mask = -1;
char server_ip[sizeof ("xxx.xxx.xxx.xxx")];
- const grub_uint8_t *opt;
+ const char *opt;
grub_uint8_t opt_len, overload = 0;
const char *boot_file = 0, *server_name = 0;
grub_size_t boot_file_len, server_name_len;
@@ -572,7 +572,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
if (opt && opt_len)
{
grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len);
- if (opt && grub_strcmp (opt, "HTTPClient") == 0)
+ if (opt && grub_strcmp ((char *)opt, "HTTPClient") == 0)
{
char *proto, *ip, *pa;

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip4_config.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/ip4_config.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c
index 9725e928f7e..cb880fc3e8f 100644
--- a/grub-core/net/efi/ip4_config.c
+++ b/grub-core/net/efi/ip4_config.c
@@ -61,7 +61,8 @@ int
grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest)
{
grub_uint32_t newip = 0;
- int i, ncolon = 0;
+ grub_size_t i;
+ int ncolon = 0;
const char *ptr = val;
/* Check that is not an IPv6 address */
@@ -78,7 +79,7 @@ grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *addres
for (i = 0; i < 4; i++)
{
unsigned long t;
- t = grub_strtoul (ptr, (char **) &ptr, 0);
+ t = grub_strtoul (ptr, &ptr, 0);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip6_config.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/ip6_config.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c
index a46f6f9b685..1c5415d7185 100644
--- a/grub-core/net/efi/ip6_config.c
+++ b/grub-core/net/efi/ip6_config.c
@@ -85,7 +85,7 @@ grub_efi_string_to_ip6_address (const char *val, grub_efi_ipv6_address_t *addres
ptr++;
continue;
}
- t = grub_strtoul (ptr, (char **) &ptr, 16);
+ t = grub_strtoul (ptr, &ptr, 16);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/net.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/net.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c
index a3f0535d43c..78e5442fc52 100644
--- a/grub-core/net/efi/net.c
+++ b/grub-core/net/efi/net.c
@@ -729,7 +729,7 @@ grub_efi_net_parse_address (const char *address,
{
grub_uint32_t subnet_mask_size;
- subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0);
+ subnet_mask_size = grub_strtoul (rest + 1, &rest, 0);
if (!grub_errno && subnet_mask_size <= 32 && *rest == 0)
{
@@ -758,7 +758,7 @@ grub_efi_net_parse_address (const char *address,
{
grub_efi_uint8_t prefix_length;
- prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0);
+ prefix_length = grub_strtoul (rest + 1, &rest, 0);
if (!grub_errno && prefix_length <= 128 && *rest == 0)
{
ip6->prefix_length = prefix_length;

View File

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/pxe.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/efi/pxe.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c
index 531949cba5c..73e2bb01c1b 100644
--- a/grub-core/net/efi/pxe.c
+++ b/grub-core/net/efi/pxe.c
@@ -187,7 +187,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
ptr++;
continue;
}
- t = grub_strtoul (ptr, (char **) &ptr, 16);
+ t = grub_strtoul (ptr, &ptr, 16);
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
@@ -225,7 +225,7 @@ pxe_open (struct grub_efi_net_device *dev,
int type __attribute__((unused)))
{
int i;
- char *p;
+ const char *p;
grub_efi_status_t status;
grub_efi_pxe_ip_address_t server_ip;
grub_efi_uint64_t file_size = 0;
@@ -313,7 +313,7 @@ pxe_read (struct grub_efi_net_device *dev,
grub_size_t len)
{
int i;
- char *p;
+ const char *p;
grub_efi_status_t status;
grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe;
grub_efi_uint64_t bufsz = len;

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 20 Jul 2020 12:24:02 -0400
Subject: [PATCH] Fix const char ** pointers in grub-core/net/url.c
This will need to get folded back in the right place on the next rebase,
but it's before "Make grub_strtol() "end" pointers have safer const
qualifiers" currently, so for now I'm leaving it here instead of merging
it back with the original patch.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/net/url.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/net/url.c b/grub-core/net/url.c
index 146858284cd..d9d2fc9a9dc 100644
--- a/grub-core/net/url.c
+++ b/grub-core/net/url.c
@@ -235,7 +235,7 @@ extract_http_url_info (char *url, int ssl,
c = *port_end;
*port_end = '\0';
- portul = grub_strtoul (port_off, &separator, 10);
+ portul = grub_strtoul (port_off, (const char **)&separator, 10);
*port_end = c;
#ifdef URL_TEST
if (portul == ULONG_MAX && errno == ERANGE)

View File

@ -376,8 +376,13 @@ done \
-p /EFI/%{efi_vendor} -d grub-core ${GRUB_MODULES} \ -p /EFI/%{efi_vendor} -d grub-core ${GRUB_MODULES} \
%{4}./grub-mkimage -O %{1} -o %{3}.orig \\\ %{4}./grub-mkimage -O %{1} -o %{3}.orig \\\
-p /EFI/BOOT -d grub-core ${GRUB_MODULES} \ -p /EFI/BOOT -d grub-core ${GRUB_MODULES} \
%{expand:%%{pesign -s -i %%{2}.orig -o %%{2} -a %%{5} -c %%{6} -n %%{7}}} \ %{expand:%%define ___pesign_client_cert %{?___pesign_client_cert}%{!?___pesign_client_cert:%{__pesign_client_cert}}} \
%{expand:%%{pesign -s -i %%{3}.orig -o %%{3} -a %%{5} -c %%{6} -n %%{7}}} \ %{?__pesign_client_cert:%{expand:%%define __pesign_client_cert %{___pesign_client_cert}}} \
%{expand:%%{pesign -s -i %%{2}.orig -o %%{2}.onesig -a %%{5} -c %%{6} -n %%{7}}} \
%{expand:%%{pesign -s -i %%{3}.orig -o %%{3}.onesig -a %%{5} -c %%{6} -n %%{7}}} \
%{expand:%%define __pesign_client_cert grub2-signer} \
%{expand:%%{pesign -s -i %%{2}.onesig -o %%{2} -a %%{5} -c %%{6} -n %%{7}}} \
%{expand:%%{pesign -s -i %%{3}.onesig -o %%{3} -a %%{5} -c %%{6} -n %%{7}}} \
%{nil} %{nil}
%else %else
%define mkimage() \ %define mkimage() \

View File

@ -220,3 +220,46 @@ Patch0219: 0219-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch
Patch0220: 0220-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch Patch0220: 0220-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch
Patch0221: 0221-fix-build-with-rpm-4.16.patch Patch0221: 0221-fix-build-with-rpm-4.16.patch
Patch0222: 0222-Only-mark-GRUB-as-BLS-supported-in-OSTree-systems-wi.patch Patch0222: 0222-Only-mark-GRUB-as-BLS-supported-in-OSTree-systems-wi.patch
Patch0223: 0223-Don-t-assume-that-boot-commands-will-only-return-on-.patch
Patch0224: 0224-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch
Patch0225: 0225-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch
Patch0226: 0226-safemath-Add-some-arithmetic-primitives-that-check-f.patch
Patch0227: 0227-calloc-Make-sure-we-always-have-an-overflow-checking.patch
Patch0228: 0228-calloc-Use-calloc-at-most-places.patch
Patch0229: 0229-malloc-Use-overflow-checking-primitives-where-we-do-.patch
Patch0230: 0230-iso9660-Don-t-leak-memory-on-realloc-failures.patch
Patch0231: 0231-font-Do-not-load-more-than-one-NAME-section.patch
Patch0232: 0232-gfxmenu-Fix-double-free-in-load_image.patch
Patch0233: 0233-xnu-Fix-double-free-in-grub_xnu_devprop_add_property.patch
Patch0234: 0234-lzma-Make-sure-we-don-t-dereference-past-array.patch
Patch0235: 0235-term-Fix-overflow-on-user-inputs.patch
Patch0236: 0236-udf-Fix-memory-leak.patch
Patch0237: 0237-multiboot2-Fix-memory-leak-if-grub_create_loader_cmd.patch
Patch0238: 0238-tftp-Do-not-use-priority-queue.patch
Patch0239: 0239-multiboot2-Set-min-address-for-mbi-allocation-to-0x1.patch
Patch0240: 0240-relocator-Protect-grub_relocator_alloc_chunk_addr-in.patch
Patch0241: 0241-relocator-Protect-grub_relocator_alloc_chunk_align-m.patch
Patch0242: 0242-script-Remove-unused-fields-from-grub_script_functio.patch
Patch0243: 0243-script-Avoid-a-use-after-free-when-redefining-a-func.patch
Patch0244: 0244-relocator-Fix-grub_relocator_alloc_chunk_align-top-m.patch
Patch0245: 0245-hfsplus-fix-two-more-overflows.patch
Patch0246: 0246-lvm-fix-two-more-potential-data-dependent-alloc-over.patch
Patch0247: 0247-emu-make-grub_free-NULL-safe.patch
Patch0248: 0248-efi-fix-some-malformed-device-path-arithmetic-errors.patch
Patch0249: 0249-Fix-a-regression-caused-by-efi-fix-some-malformed-de.patch
Patch0250: 0250-efi-Fix-use-after-free-in-halt-reboot-path.patch
Patch0251: 0251-efi-dhcp-fix-some-allocation-error-checking.patch
Patch0252: 0252-efi-http-fix-some-allocation-error-checking.patch
Patch0253: 0253-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch
Patch0254: 0254-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch
Patch0255: 0255-efi-Fix-use-after-free-in-halt-reboot-path.patch
Patch0256: 0256-linux-loader-avoid-overflow-on-initrd-size-calculati.patch
Patch0257: 0257-linuxefi-fail-kernel-validation-without-shim-protoco.patch
Patch0258: 0258-linux-Fix-integer-overflows-in-initrd-size-handling.patch
Patch0259: 0259-Fix-const-char-pointers-in-grub-core-commands-blscfg.patch
Patch0260: 0260-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch
Patch0261: 0261-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch
Patch0262: 0262-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch
Patch0263: 0263-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch
Patch0264: 0264-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch
Patch0265: 0265-Fix-const-char-pointers-in-grub-core-net-url.c.patch

View File

@ -14,7 +14,7 @@
Name: grub2 Name: grub2
Epoch: 1 Epoch: 1
Version: 2.04 Version: 2.04
Release: 26%{?dist} Release: 27%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+ License: GPLv3+
URL: http://www.gnu.org/software/grub/ URL: http://www.gnu.org/software/grub/
@ -509,8 +509,20 @@ rm -r /boot/grub2.tmp/ || :
%endif %endif
%changelog %changelog
* Mon Aug 10 2020 Peter Jones <pjones@redhat.com> - 2.04-27
- Attempt to enable dual-signing in f33
- "Minor" bug fixes. For f33:
Resolves: CVE-2020-10713
Resolves: CVE-2020-14308
Resolves: CVE-2020-14309
Resolves: CVE-2020-14310
Resolves: CVE-2020-14311
Resolves: CVE-2020-15705
Resolves: CVE-2020-15706
Resolves: CVE-2020-15707
* Tue Jun 30 2020 Jeff Law <law@redhat.com> - 2.04-26 * Tue Jun 30 2020 Jeff Law <law@redhat.com> - 2.04-26
Disable LTO - Disable LTO
* Thu Jun 18 2020 Javier Martinez Canillas <javierm@redhat.com> - 2.04-25 * Thu Jun 18 2020 Javier Martinez Canillas <javierm@redhat.com> - 2.04-25
- Only mark GRUB as BLS supported in OSTree systems with a boot partition - Only mark GRUB as BLS supported in OSTree systems with a boot partition