Update buildroot to 2020.02.7 (#923)
Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch>
This commit is contained in:
committed by
Stefan Agner
parent
f9c29ef209
commit
e43d4cd632
@@ -1,6 +1,6 @@
|
||||
config BR2_TARGET_AT91BOOTSTRAP3
|
||||
bool "AT91 Bootstrap 3"
|
||||
depends on BR2_arm926t || BR2_cortex_a5
|
||||
depends on BR2_arm926t || BR2_cortex_a5 || BR2_cortex_a7
|
||||
help
|
||||
AT91Bootstrap is a first level bootloader for the Atmel AT91
|
||||
devices. It integrates algorithms for:
|
||||
|
||||
@@ -88,13 +88,6 @@ $(1)_KCONFIG_DEPENDENCIES = \
|
||||
$(BR2_BISON_HOST_DEPENDENCY) \
|
||||
$(BR2_FLEX_HOST_DEPENDENCY)
|
||||
|
||||
ifeq ($$(BR2_TARGET_$(1)_BAREBOXENV),y)
|
||||
define $(1)_BUILD_BAREBOXENV_CMDS
|
||||
$$(TARGET_CC) $$(TARGET_CFLAGS) $$(TARGET_LDFLAGS) -o $$(@D)/bareboxenv \
|
||||
$$(@D)/scripts/bareboxenv.c
|
||||
endef
|
||||
endif
|
||||
|
||||
ifeq ($$(BR2_TARGET_$(1)_CUSTOM_ENV),y)
|
||||
$(1)_ENV_NAME = $$(notdir $$(call qstrip,\
|
||||
$$(BR2_TARGET_$(1)_CUSTOM_ENV_PATH)))
|
||||
@@ -109,12 +102,23 @@ endef
|
||||
endif
|
||||
|
||||
ifneq ($$($(1)_CUSTOM_EMBEDDED_ENV_PATH),)
|
||||
define $(1)_KCONFIG_FIXUP_CMDS
|
||||
$$(call KCONFIG_ENABLE_OPT,CONFIG_DEFAULT_ENVIRONMENT,$$(@D)/.config)
|
||||
$$(call KCONFIG_SET_OPT,CONFIG_DEFAULT_ENVIRONMENT_PATH,"$$($(1)_CUSTOM_EMBEDDED_ENV_PATH)",$$(@D)/.config)
|
||||
define $(1)_KCONFIG_FIXUP_CUSTOM_EMBEDDED_ENV_PATH
|
||||
$$(call KCONFIG_ENABLE_OPT,CONFIG_DEFAULT_ENVIRONMENT)
|
||||
$$(call KCONFIG_SET_OPT,CONFIG_DEFAULT_ENVIRONMENT_PATH,"$$($(1)_CUSTOM_EMBEDDED_ENV_PATH)")
|
||||
endef
|
||||
endif
|
||||
|
||||
define $(1)_KCONFIG_FIXUP_BAREBOXENV
|
||||
$$(if $$(BR2_TARGET_$(1)_BAREBOXENV),\
|
||||
$$(call KCONFIG_ENABLE_OPT,CONFIG_BAREBOXENV_TARGET),\
|
||||
$$(call KCONFIG_DISABLE_OPT,CONFIG_BAREBOXENV_TARGET))
|
||||
endef
|
||||
|
||||
define $(1)_KCONFIG_FIXUP_CMDS
|
||||
$$($(1)_KCONFIG_FIXUP_CUSTOM_EMBEDDED_ENV_PATH)
|
||||
$$($(1)_KCONFIG_FIXUP_BAREBOXENV)
|
||||
endef
|
||||
|
||||
define $(1)_BUILD_CMDS
|
||||
$$($(1)_BUILD_BAREBOXENV_CMDS)
|
||||
$$(TARGET_MAKE_ENV) $$(MAKE) $$($(1)_MAKE_FLAGS) -C $$(@D)
|
||||
@@ -136,7 +140,7 @@ endef
|
||||
|
||||
ifeq ($$(BR2_TARGET_$(1)_BAREBOXENV),y)
|
||||
define $(1)_INSTALL_TARGET_CMDS
|
||||
cp $$(@D)/bareboxenv $$(TARGET_DIR)/usr/bin
|
||||
cp $$(@D)/scripts/bareboxenv-target $$(TARGET_DIR)/usr/bin/bareboxenv
|
||||
endef
|
||||
endif
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From a7ab0cc98fa89a3d5098c29cbe44bcd24b0a6454 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 7b44c37b7..b7203c823 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) \
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
From 782a4580a5e347793443aa8e9152db1bf4a0fff8 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
INSTALL | 22 ++--------------------
|
||||
include/grub/compiler.h | 8 ++++++++
|
||||
include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 47 insertions(+), 20 deletions(-)
|
||||
create mode 100644 include/grub/safemath.h
|
||||
|
||||
diff --git a/INSTALL b/INSTALL
|
||||
index 8acb40902..dcb9b7d7b 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
|
||||
diff --git a/include/grub/compiler.h b/include/grub/compiler.h
|
||||
index c9e1d7a73..8f3be3ae7 100644
|
||||
--- a/include/grub/compiler.h
|
||||
+++ b/include/grub/compiler.h
|
||||
@@ -48,4 +48,12 @@
|
||||
# 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
|
||||
+
|
||||
#endif /* ! GRUB_COMPILER_HEADER */
|
||||
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
|
||||
new file mode 100644
|
||||
index 000000000..c17b89bba
|
||||
--- /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 */
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
From 5775eb40862b67468ced816e6d7560dbe22a3670 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 65db79baa..dfd8a8ec4 100644
|
||||
--- a/grub-core/kern/emu/misc.c
|
||||
+++ b/grub-core/kern/emu/misc.c
|
||||
@@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
|
||||
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 f262e95e3..145b01d37 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 ee88ff611..f2822a836 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 beeb661a3..74c6eafe5 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 3b46f47ff..7a8d385e9 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 ce464cfd0..ff9c48a64 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 28e2e53eb..9c38dd3ca 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,
|
||||
--
|
||||
2.26.2
|
||||
|
||||
1840
buildroot/boot/grub2/0005-calloc-Use-calloc-at-most-places.patch
Normal file
1840
buildroot/boot/grub2/0005-calloc-Use-calloc-at-most-places.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
From e0dd17a3ce79c6622dc78c96e1f2ef1b20e2bf7b 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 7ba5b300b..5ec4433b8 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;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From 73bc7a964c9496d5b0f00dbd69959dacf5adcebe 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 5edb477ac..d09bb38d8 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 (§ion);
|
||||
if (!font->name)
|
||||
goto fail;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 9ff609f0e7798bc5fb04f791131c98e7693bdd9b 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()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 29784ed2d..6b2e976f1 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);
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From dc9777dc17697b196c415c53187a55861d41fd2a 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()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/loader/i386/xnu.c | 17 ++++++++---------
|
||||
1 file changed, 8 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
|
||||
index b7d176b5d..e9e119259 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->name = utf8;
|
||||
- prop->name16 = utf16;
|
||||
- prop->name16len = utf16len;
|
||||
-
|
||||
- prop->length = datalen;
|
||||
- prop->data = grub_malloc (prop->length);
|
||||
+ prop->data = grub_malloc (datalen);
|
||||
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_memcpy (prop->data, data, datalen);
|
||||
+
|
||||
+ prop->name = utf8;
|
||||
+ prop->name16 = utf16;
|
||||
+ prop->name16len = utf16len;
|
||||
+ prop->length = datalen;
|
||||
+
|
||||
grub_list_push (GRUB_AS_LIST_P (&dev->properties),
|
||||
GRUB_AS_LIST (prop));
|
||||
return GRUB_ERR_NONE;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 78829f0c230680e386fff9f420bb1631bc20f761 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 f2ec04a8c..753e56a95 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)
|
||||
{
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From 8d3b6f9da468f666e3a7976657f2ab5c52762a21 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 d317efa36..5fa94c0c3 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
|
||||
--
|
||||
2.26.2
|
||||
|
||||
59
buildroot/boot/grub2/0013-udf-Fix-memory-leak.patch
Normal file
59
buildroot/boot/grub2/0013-udf-Fix-memory-leak.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From 748b691761d31bfff7e9d0d210caa606294c2b52 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 21ac7f446..2ac5c1d00 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))
|
||||
{
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 49bf3faa106498e151306fc780c63194a14751e3 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fixes: CID 292468
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 53da78615..0efc66062 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;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
283
buildroot/boot/grub2/0015-tftp-Do-not-use-priority-queue.patch
Normal file
283
buildroot/boot/grub2/0015-tftp-Do-not-use-priority-queue.patch
Normal file
@@ -0,0 +1,283 @@
|
||||
From b6c4a1b204740fe52b32e7f530831a59f4038e20 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/net/tftp.c | 168 ++++++++++++++-----------------------------
|
||||
1 file changed, 53 insertions(+), 115 deletions(-)
|
||||
|
||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
|
||||
index 7d90bf66e..b4297bc8d 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;
|
||||
-
|
||||
- {
|
||||
- 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)
|
||||
+ /* 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;
|
||||
+
|
||||
+ 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;
|
||||
-
|
||||
- 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;
|
||||
-
|
||||
- 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);
|
||||
- }
|
||||
- }
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+ else
|
||||
+ file->device->net->stall = 1;
|
||||
+
|
||||
+ 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, 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);
|
||||
-}
|
||||
-
|
||||
static grub_err_t
|
||||
tftp_open (struct grub_file *file, const char *filename)
|
||||
{
|
||||
@@ -372,17 +322,9 @@ 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;
|
||||
- }
|
||||
-
|
||||
err = grub_net_resolve_address (file->device->net->server, &addr);
|
||||
if (err)
|
||||
{
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return err;
|
||||
}
|
||||
@@ -392,7 +334,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
file);
|
||||
if (!data->sock)
|
||||
{
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return grub_errno;
|
||||
}
|
||||
@@ -406,7 +347,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;
|
||||
}
|
||||
@@ -423,7 +363,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;
|
||||
}
|
||||
@@ -466,7 +405,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;
|
||||
}
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
From 1c7b619c84f229c1602c1958bcd054b6d9937562 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 d0501e229..02a73463a 100644
|
||||
--- a/grub-core/loader/i386/linux.c
|
||||
+++ b/grub-core/loader/i386/linux.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -547,9 +548,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 47ea2945e..31f09922b 100644
|
||||
--- a/grub-core/loader/i386/pc/linux.c
|
||||
+++ b/grub-core/loader/i386/pc/linux.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <grub/i386/floppy.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -218,8 +219,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 8f662c8ac..cd24874ca 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 77d7060e1..9ae4ceb35 100644
|
||||
--- a/grub-core/loader/xnu.c
|
||||
+++ b/grub-core/loader/xnu.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <grub/env.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -59,15 +60,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;
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
From 0cfbbca3ccd84d36ffb1bcd6644ada7c73b19fc0 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 71dd4f0ab..34cbe834f 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 9d5f49cb9..743b213e6 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 bdf2b111b..8ffb8b686 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 3caef7a40..7d200a125 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 02a73463a..efbb99307 100644
|
||||
--- a/grub-core/loader/i386/linux.c
|
||||
+++ b/grub-core/loader/i386/linux.c
|
||||
@@ -181,9 +181,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 ad3cc292f..a67d9d0a8 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 31f09922b..5fed5ffdf 100644
|
||||
--- a/grub-core/loader/i386/pc/linux.c
|
||||
+++ b/grub-core/loader/i386/pc/linux.c
|
||||
@@ -453,10 +453,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 7b723bf18..e4ed95921 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 4a98d7082..facb13f3d 100644
|
||||
--- a/grub-core/loader/multiboot.c
|
||||
+++ b/grub-core/loader/multiboot.c
|
||||
@@ -403,7 +403,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 cc6853692..f2318e0d1 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 0efc66062..03967839c 100644
|
||||
--- a/grub-core/loader/multiboot_mbi2.c
|
||||
+++ b/grub-core/loader/multiboot_mbi2.c
|
||||
@@ -295,10 +295,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,
|
||||
@@ -708,7 +708,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,
|
||||
+ 0, 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 8089804d4..d648ef0cd 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 24d8672d2..1b3bdd92a 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
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 73aa0776457066ee6ebc93486c3cf0e6b755d1b8 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 360c2be1f..b382bcf09 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;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
From 26349fcf80982b4d0120b73b2836e88bcf16853c 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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.
|
||||
|
||||
Fixes: CVE-2020-15706
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/script/execute.c | 2 ++
|
||||
grub-core/script/function.c | 16 +++++++++++++---
|
||||
grub-core/script/parser.y | 3 ++-
|
||||
include/grub/script_sh.h | 2 ++
|
||||
4 files changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
||||
index c8d6806fe..7e028e135 100644
|
||||
--- a/grub-core/script/execute.c
|
||||
+++ b/grub-core/script/execute.c
|
||||
@@ -838,7 +838,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 d36655e51..3aad04bf9 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/grub-core/script/parser.y b/grub-core/script/parser.y
|
||||
index 4f0ab8319..f80b86b6f 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;
|
||||
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
|
||||
index b382bcf09..6c48e0751 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;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 06aa91f79f902752cb7e5d22ac0ea8e13bffd056 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 5847aac36..f2c1944c2 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)
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From feec993673d8e13fcf22fe2389ac29222b6daebd 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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 grub_add() or
|
||||
grub_calloc() first will give us that.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 dae43becc..9c4e4c88c 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;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
From a1845e90fc19fb5e904091bad8a378f458798e4a 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/disk/lvm.c | 48 ++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 40 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
|
||||
index d1df640b3..139fafd47 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, *p, *q, *vgname;
|
||||
+ char *metadatabuf, *p, *q, *mda_end, *vgname;
|
||||
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
|
||||
struct grub_lvm_pv_header *pvh;
|
||||
struct grub_lvm_disk_locn *dlocn;
|
||||
@@ -205,19 +207,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)
|
||||
@@ -367,8 +381,26 @@ 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;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
38
buildroot/boot/grub2/0023-emu-Make-grub_free-NULL-safe.patch
Normal file
38
buildroot/boot/grub2/0023-emu-Make-grub_free-NULL-safe.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 320e86747a32e4d46d24ee4b64493741c161da50 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The grub_free() implementation in grub-core/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>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
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 145b01d37..4d1046a21 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 *
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
From c330aa099a38bc5c4d3066954fe35767cc06adb1 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/kern/efi/efi.c | 64 +++++++++++++++++++++++++-----
|
||||
grub-core/loader/efi/chainloader.c | 13 +++++-
|
||||
grub-core/loader/i386/xnu.c | 9 +++--
|
||||
include/grub/efi/api.h | 14 ++++---
|
||||
4 files changed, 79 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index dc31caa21..c97969a65 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -332,7 +332,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);
|
||||
@@ -342,9 +342,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;
|
||||
}
|
||||
|
||||
@@ -360,7 +366,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);
|
||||
@@ -376,8 +382,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)
|
||||
@@ -452,7 +465,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;
|
||||
}
|
||||
@@ -497,7 +529,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);
|
||||
@@ -909,7 +941,10 @@ 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;
|
||||
@@ -945,5 +980,14 @@ 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 daf8c6b54..a8d7b9155 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -156,9 +156,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 e9e119259..a70093607 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 addcbfa8f..cf1355a8c 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -625,6 +625,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)
|
||||
@@ -633,13 +634,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
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
From fb55bc37dd510911df4eaf649da939f5fafdc7ce Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Wed, 29 Jul 2020 13:38:31 +0200
|
||||
Subject: [PATCH] efi/chainloader: Propagate errors from copy_file_path()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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 fail, returning a NULL
|
||||
pointer that would subsequently be dereferenced. Hence, propagate
|
||||
errors from copy_file_path().
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index a8d7b9155..7b31c3fb9 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -106,7 +106,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)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
|
||||
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);
|
||||
@@ -131,6 +131,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 *
|
||||
@@ -189,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
d = (grub_efi_device_path_t *) ((char *) file_path
|
||||
+ ((char *) d - (char *) dp));
|
||||
grub_efi_print_device_path (d);
|
||||
- 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);
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
From 8a6d6299efcffd14c1130942195e6c0d9b50cacd 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.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/kern/riscv/efi/init.c | 3 +++
|
||||
grub-core/lib/efi/halt.c | 3 ++-
|
||||
include/grub/loader.h | 1 +
|
||||
9 files changed, 28 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
|
||||
index 06df60e2f..40c3b467f 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 6224999ec..5010caefd 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 c97969a65..9cfd88d77 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 3dfdf2d22..2c31847bf 100644
|
||||
--- a/grub-core/kern/efi/init.c
|
||||
+++ b/grub-core/kern/efi/init.c
|
||||
@@ -80,5 +80,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 da499aba0..deb2eacd8 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 b5ecbd091..f1965571b 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/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
|
||||
index 7eb1969d0..38795fe67 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 ();
|
||||
}
|
||||
diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
|
||||
index 5859f0498..29d413641 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 7f82a499f..b20864282 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),
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From a2a7464e9f10a677d6f91e1c4fa527d084c22e7c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 24 Jul 2020 13:57:27 -0400
|
||||
Subject: [PATCH] loader/linux: Avoid overflow on initrd size calculation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/loader/linux.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 471b214d6..4cd8c20c7 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -151,8 +151,7 @@ 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;
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
From 0367e7d1b9bac3a78608a672bf6e4ace6a28b964 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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
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>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
|
||||
---
|
||||
grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 54 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 4cd8c20c7..3fe390f17 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <grub/misc.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
struct newc_head
|
||||
{
|
||||
@@ -98,13 +99,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 +131,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
|
||||
@@ -172,26 +181,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;
|
||||
@@ -207,19 +223,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
|
||||
@@ -260,8 +286,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,
|
||||
--
|
||||
2.26.2
|
||||
|
||||
@@ -21,6 +21,17 @@ endef
|
||||
GRUB2_POST_PATCH_HOOKS += GRUB2_AVOID_AUTORECONF
|
||||
HOST_GRUB2_POST_PATCH_HOOKS += GRUB2_AVOID_AUTORECONF
|
||||
|
||||
# 0002-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch
|
||||
GRUB2_IGNORE_CVES += CVE-2020-10713
|
||||
# 0005-calloc-Use-calloc-at-most-places.patch
|
||||
GRUB2_IGNORE_CVES += CVE-2020-14308
|
||||
# 0006-malloc-Use-overflow-checking-primitives-where-we-do-.patch
|
||||
GRUB2_IGNORE_CVES += CVE-2020-14309 CVE-2020-14310 CVE-2020-14311
|
||||
# 0019-script-Avoid-a-use-after-free-when-redefining-a-func.patch
|
||||
GRUB2_IGNORE_CVES += CVE-2020-15706
|
||||
# 0028-linux-Fix-integer-overflows-in-initrd-size-handling.patch
|
||||
GRUB2_IGNORE_CVES += CVE-2020-15707
|
||||
|
||||
ifeq ($(BR2_TARGET_GRUB2_INSTALL_TOOLS),y)
|
||||
GRUB2_INSTALL_TARGET = YES
|
||||
else
|
||||
|
||||
@@ -16,6 +16,7 @@ UBOOT_INSTALL_IMAGES = YES
|
||||
|
||||
# u-boot 2020.01+ needs make 4.0+
|
||||
UBOOT_DEPENDENCIES = $(BR2_MAKE_HOST_DEPENDENCY)
|
||||
UBOOT_MAKE = $(BR2_MAKE)
|
||||
|
||||
ifeq ($(UBOOT_VERSION),custom)
|
||||
# Handle custom U-Boot tarballs as specified by the configuration
|
||||
@@ -247,7 +248,7 @@ UBOOT_POST_PATCH_HOOKS += UBOOT_FIXUP_LIBFDT_INCLUDE
|
||||
ifeq ($(BR2_TARGET_UBOOT_BUILD_SYSTEM_LEGACY),y)
|
||||
define UBOOT_CONFIGURE_CMDS
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
$(BR2_MAKE) -C $(@D) $(UBOOT_MAKE_OPTS) \
|
||||
$(UBOOT_MAKE) -C $(@D) $(UBOOT_MAKE_OPTS) \
|
||||
$(UBOOT_BOARD_NAME)_config
|
||||
endef
|
||||
else ifeq ($(BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG),y)
|
||||
@@ -284,7 +285,7 @@ define UBOOT_BUILD_CMDS
|
||||
cp -f $(UBOOT_CUSTOM_DTS_PATH) $(@D)/arch/$(UBOOT_ARCH)/dts/
|
||||
)
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
$(BR2_MAKE) -C $(@D) $(UBOOT_MAKE_OPTS) \
|
||||
$(UBOOT_MAKE) -C $(@D) $(UBOOT_MAKE_OPTS) \
|
||||
$(UBOOT_MAKE_TARGET)
|
||||
$(if $(BR2_TARGET_UBOOT_FORMAT_SD),
|
||||
$(@D)/tools/mxsboot sd $(@D)/u-boot.sb $(@D)/u-boot.sd)
|
||||
|
||||
Reference in New Issue
Block a user