fix CVE-2020-10713 CVE-2020-14308 CVE-2020-14309 CVE-2020-14310 CVE-2020-14311 CVE-2020-15705 CVE-2020-15706 CVE-2020-15707
This commit is contained in:
parent
c40de1165e
commit
a6d732703b
69
0221-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch
Normal file
69
0221-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From a4d3fbdff1e3ca8f87642af2ac8752c30c617a3e Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 15 Apr 2020 15:45:02 -0400
|
||||
Subject: [PATCH 01/27] yylex: Make lexer fatal errors actually be fatal
|
||||
|
||||
When presented with a command that can't be tokenized to anything
|
||||
smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
|
||||
expecting that will stop further processing, as such:
|
||||
|
||||
#define YY_DO_BEFORE_ACTION \
|
||||
yyg->yytext_ptr = yy_bp; \
|
||||
yyleng = (int) (yy_cp - yy_bp); \
|
||||
yyg->yy_hold_char = *yy_cp; \
|
||||
*yy_cp = '\0'; \
|
||||
if ( yyleng >= YYLMAX ) \
|
||||
YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
|
||||
yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
|
||||
yyg->yy_c_buf_p = yy_cp;
|
||||
|
||||
The code flex generates expects that YY_FATAL_ERROR() will either return
|
||||
for it or do some form of longjmp(), or handle the error in some way at
|
||||
least, and so the strncpy() call isn't in an "else" clause, and thus if
|
||||
YY_FATAL_ERROR() is *not* actually fatal, it does the call with the
|
||||
questionable limit, and predictable results ensue.
|
||||
|
||||
Unfortunately, our implementation of YY_FATAL_ERROR() is:
|
||||
|
||||
#define YY_FATAL_ERROR(msg) \
|
||||
do { \
|
||||
grub_printf (_("fatal error: %s\n"), _(msg)); \
|
||||
} while (0)
|
||||
|
||||
The same pattern exists in yyless(), and similar problems exist in users
|
||||
of YY_INPUT(), several places in the main parsing loop,
|
||||
yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
|
||||
yy_scan_buffer(), etc.
|
||||
|
||||
All of these callers expect YY_FATAL_ERROR() to actually be fatal, and
|
||||
the things they do if it returns after calling it are wildly unsafe.
|
||||
|
||||
Fixes: CVE-2020-10713
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 7b44c37..b7203c8 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.23.0
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
From 68708c4503018d61dbcce7ac11cbb511d6425f4d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Jun 2020 10:58:42 -0400
|
||||
Subject: [PATCH 02/27] safemath: Add some arithmetic primitives that check for
|
||||
overflow
|
||||
|
||||
This adds a new header, include/grub/safemath.h, that includes easy to
|
||||
use wrappers for __builtin_{add,sub,mul}_overflow() declared like:
|
||||
|
||||
bool OP(a, b, res)
|
||||
|
||||
where OP is grub_add, grub_sub or grub_mul. OP() returns true in the
|
||||
case where the operation would overflow and res is not modified.
|
||||
Otherwise, false is returned and the operation is executed.
|
||||
|
||||
These arithmetic primitives require newer compiler versions. So, bump
|
||||
these requirements in the INSTALL file too.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
include/grub/compiler.h | 8 ++++++++
|
||||
include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 45 insertions(+)
|
||||
create mode 100644 include/grub/safemath.h
|
||||
|
||||
diff --git a/include/grub/compiler.h b/include/grub/compiler.h
|
||||
index 9859ff4..61c0cb3 100644
|
||||
--- a/include/grub/compiler.h
|
||||
+++ b/include/grub/compiler.h
|
||||
@@ -50,4 +50,12 @@
|
||||
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
|
||||
+#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 0000000..c17b89b
|
||||
--- /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.23.0
|
||||
|
||||
242
0223-calloc-Make-sure-we-always-have-an-overflow-checking.patch
Normal file
242
0223-calloc-Make-sure-we-always-have-an-overflow-checking.patch
Normal file
@ -0,0 +1,242 @@
|
||||
From 64e26162ebfe68317c143ca5ec996c892019f8f8 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 15 Jun 2020 12:15:29 -0400
|
||||
Subject: [PATCH 03/27] calloc: Make sure we always have an overflow-checking
|
||||
calloc() available
|
||||
|
||||
This tries to make sure that everywhere in this source tree, we always have
|
||||
an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
|
||||
available, and that they all safely check for overflow and return NULL when
|
||||
it would occur.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 7a8d9e6..f08a1bb 100644
|
||||
--- a/grub-core/kern/emu/misc.c
|
||||
+++ b/grub-core/kern/emu/misc.c
|
||||
@@ -86,6 +86,18 @@ grub_util_error (const char *fmt, ...)
|
||||
grub_exit (1);
|
||||
}
|
||||
|
||||
+void *
|
||||
+xcalloc (grub_size_t nmemb, grub_size_t size)
|
||||
+{
|
||||
+ void *p;
|
||||
+
|
||||
+ p = calloc (nmemb, size);
|
||||
+ if (!p)
|
||||
+ grub_util_error ("%s", _("out of memory"));
|
||||
+
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
void *
|
||||
xmalloc (grub_size_t size)
|
||||
{
|
||||
diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
|
||||
index 43b31fa..4d1046a 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 002cbfa..80d0720 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 beeb661..74c6eaf 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 3b46f47..7a8d385 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 5ef4f79..0105695 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 28e2e53..9c38dd3 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.23.0
|
||||
|
||||
1836
0224-calloc-Use-calloc-at-most-places.patch
Normal file
1836
0224-calloc-Use-calloc-at-most-places.patch
Normal file
File diff suppressed because it is too large
Load Diff
1322
0225-malloc-Use-overflow-checking-primitives-where-we-do-.patch
Normal file
1322
0225-malloc-Use-overflow-checking-primitives-where-we-do-.patch
Normal file
File diff suppressed because it is too large
Load Diff
68
0226-iso9660-Don-t-leak-memory-on-realloc-failures.patch
Normal file
68
0226-iso9660-Don-t-leak-memory-on-realloc-failures.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From f14380cfa955a2fb502ba148d045f68ac1250f2d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Sat, 4 Jul 2020 12:25:09 -0400
|
||||
Subject: [PATCH 06/27] iso9660: Don't leak memory on realloc() failures
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 7ba5b30..5ec4433 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.23.0
|
||||
|
||||
37
0227-font-Do-not-load-more-than-one-NAME-section.patch
Normal file
37
0227-font-Do-not-load-more-than-one-NAME-section.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 7c1e10c986d1c4b50146f03f58c1aece2aa0bdbe 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 07/27] font: Do not load more than one NAME section
|
||||
|
||||
The GRUB font file can have one NAME section only. Though if somebody
|
||||
crafts a broken font file with many NAME sections and loads it then the
|
||||
GRUB leaks memory. So, prevent against that by loading first NAME
|
||||
section and failing in controlled way on following one.
|
||||
|
||||
Reported-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
---
|
||||
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 5edb477..d09bb38 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.23.0
|
||||
|
||||
35
0228-gfxmenu-Fix-double-free-in-load_image.patch
Normal file
35
0228-gfxmenu-Fix-double-free-in-load_image.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From a2e9386cbca0aeb951badd992a1fc3634c348877 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Wed, 8 Jul 2020 20:41:56 +0000
|
||||
Subject: [PATCH 08/27] gfxmenu: Fix double free in load_image()
|
||||
|
||||
self->bitmap should be zeroed after free. Otherwise, there is a chance
|
||||
to double free (USE_AFTER_FREE) it later in rescale_image().
|
||||
|
||||
Fixes: CID 292472
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 29784ed..6b2e976 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.23.0
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From d7bdee0e38c93b4c49281f5ca79d416bab6eb3ce Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Wed, 8 Jul 2020 21:30:43 +0000
|
||||
Subject: [PATCH 09/27] xnu: Fix double free in grub_xnu_devprop_add_property()
|
||||
|
||||
grub_xnu_devprop_add_property() should not free utf8 and utf16 as it get
|
||||
allocated and freed in the caller.
|
||||
|
||||
Minor improvement: do prop fields initialization after memory allocations.
|
||||
|
||||
Fixes: CID 292442, CID 292457, CID 292460, CID 292466
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 b7d176b..e9e1192 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.23.0
|
||||
|
||||
51
0230-lzma-Make-sure-we-don-t-dereference-past-array.patch
Normal file
51
0230-lzma-Make-sure-we-don-t-dereference-past-array.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From a2fd8fe73250d5a6ebe7e1b9dc31df6ecbcdfc8f 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 10/27] lzma: Make sure we don't dereference past array
|
||||
|
||||
The two dimensional array p->posSlotEncoder[4][64] is being dereferenced
|
||||
using the GetLenToPosState() macro which checks if len is less than 5,
|
||||
and if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294.
|
||||
Obviously we don't want to dereference that far out so we check if the
|
||||
position found is greater or equal kNumLenToPosStates (4) and bail out.
|
||||
|
||||
N.B.: Upstream LZMA 18.05 and later has this function completely rewritten
|
||||
without any history.
|
||||
|
||||
Fixes: CID 51526
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 f2ec04a..753e56a 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.23.0
|
||||
|
||||
65
0231-term-Fix-overflow-on-user-inputs.patch
Normal file
65
0231-term-Fix-overflow-on-user-inputs.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 8054c31c62c4caf5a8767c0e4c8ce09219b8ec6e 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 11/27] term: Fix overflow on user inputs
|
||||
|
||||
This requires a very weird input from the serial interface but can cause
|
||||
an overflow in input_buf (keys) overwriting the next variable (npending)
|
||||
with the user choice:
|
||||
|
||||
(pahole output)
|
||||
|
||||
struct grub_terminfo_input_state {
|
||||
int input_buf[6]; /* 0 24 */
|
||||
int npending; /* 24 4 */ <- CORRUPT
|
||||
...snip...
|
||||
|
||||
The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
|
||||
npending with "q" (aka increase npending to 161). The simplest fix is to
|
||||
just to disallow overwrites input_buf, which exactly what this patch does.
|
||||
|
||||
Fixes: CID 292449
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 537a5c0..44d0b3b 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.23.0
|
||||
|
||||
55
0232-udf-Fix-memory-leak.patch
Normal file
55
0232-udf-Fix-memory-leak.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From ba6a43c85d73196ed00ba662a4d310c310540864 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 12/27] udf: Fix memory leak
|
||||
|
||||
Fixes: CID 73796
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
---
|
||||
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 21ac7f4..2ac5c1d 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.23.0
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From 1eebc205991aeb48f5d88acaac3833ad527b1fb1 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 13/27] multiboot2: Fix memory leak if
|
||||
grub_create_loader_cmdline() fails
|
||||
|
||||
Fixes: CID 292468
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 53da786..0efc660 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.23.0
|
||||
|
||||
284
0234-tftp-Do-not-use-priority-queue.patch
Normal file
284
0234-tftp-Do-not-use-priority-queue.patch
Normal file
@ -0,0 +1,284 @@
|
||||
From 781b3e5efc35c17cbce95393aafd63a5b429f9e6 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Thu, 9 Jul 2020 08:10:40 +0000
|
||||
Subject: [PATCH 14/27] tftp: Do not use priority queue
|
||||
|
||||
There is not need to reassemble the order of blocks. Per RFC 1350,
|
||||
server must wait for the ACK, before sending next block. Data packets
|
||||
can be served immediately without putting them to priority queue.
|
||||
|
||||
Logic to handle incoming packet is this:
|
||||
- if packet block id equal to expected block id, then
|
||||
process the packet,
|
||||
- if packet block id is less than expected - this is retransmit
|
||||
of old packet, then ACK it and drop the packet,
|
||||
- if packet block id is more than expected - that shouldn't
|
||||
happen, just drop the packet.
|
||||
|
||||
It makes the tftp receive path code simpler, smaller and faster.
|
||||
As a benefit, this change fixes CID# 73624 and CID# 96690, caused
|
||||
by following while loop:
|
||||
|
||||
while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
|
||||
|
||||
where tftph pointer is not moving from one iteration to another, causing
|
||||
to serve same packet again. Luckily, double serving didn't happen due to
|
||||
data->block++ during the first iteration.
|
||||
|
||||
Fixes: CID 73624, CID 96690
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
---
|
||||
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 e267af3..c2df3d7 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);
|
||||
-}
|
||||
-
|
||||
/* Create a normalized copy of the filename.
|
||||
Compress any string of consecutive forward slashes to a single forward
|
||||
slash. */
|
||||
@@ -395,13 +345,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
file->not_easily_seekable = 1;
|
||||
file->data = data;
|
||||
|
||||
- data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp);
|
||||
- if (!data->pq)
|
||||
- {
|
||||
- grub_free (data);
|
||||
- return grub_errno;
|
||||
- }
|
||||
-
|
||||
grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server);
|
||||
err = grub_net_resolve_address (file->device->net->server, &addr);
|
||||
if (err)
|
||||
@@ -410,7 +353,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n",
|
||||
(unsigned long long)data->file_size,
|
||||
(unsigned long long)data->block_size);
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return err;
|
||||
}
|
||||
@@ -422,7 +364,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
if (!data->sock)
|
||||
{
|
||||
grub_dprintf("tftp", "connection failed\n");
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return grub_errno;
|
||||
}
|
||||
@@ -436,7 +377,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
if (err)
|
||||
{
|
||||
grub_net_udp_close (data->sock);
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return err;
|
||||
}
|
||||
@@ -453,7 +393,6 @@ tftp_open (struct grub_file *file, const char *filename)
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_net_udp_close (data->sock);
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return grub_errno;
|
||||
}
|
||||
@@ -496,7 +435,6 @@ tftp_close (struct grub_file *file)
|
||||
grub_print_error ();
|
||||
grub_net_udp_close (data->sock);
|
||||
}
|
||||
- destroy_pq (data);
|
||||
grub_free (data);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
149
0235-relocator-Protect-grub_relocator_alloc_chunk_addr-in.patch
Normal file
149
0235-relocator-Protect-grub_relocator_alloc_chunk_addr-in.patch
Normal file
@ -0,0 +1,149 @@
|
||||
From caea56d1f8fa1ae298936f8d75b220e7f12b73d3 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Wed, 15 Jul 2020 06:42:37 +0000
|
||||
Subject: [PATCH 15/27] relocator: Protect grub_relocator_alloc_chunk_addr()
|
||||
input args against integer underflow/overflow
|
||||
|
||||
Use arithmetic macros from safemath.h to accomplish it. In this commit,
|
||||
I didn't want to be too paranoid to check every possible math equation
|
||||
for overflow/underflow. Only obvious places (with non zero chance of
|
||||
overflow/underflow) were refactored.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 201e659..90f2315 100644
|
||||
--- a/grub-core/loader/i386/linux.c
|
||||
+++ b/grub-core/loader/i386/linux.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <grub/linux.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <grub/efi/sb.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -548,9 +549,13 @@ grub_linux_boot (void)
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
+ grub_size_t sz;
|
||||
+
|
||||
+ if (grub_add (ctx.real_size, efi_mmap_size, &sz))
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+
|
||||
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
|
||||
- ctx.real_mode_target,
|
||||
- (ctx.real_size + efi_mmap_size));
|
||||
+ ctx.real_mode_target, sz);
|
||||
if (err)
|
||||
return err;
|
||||
real_mode_mem = get_virtual_current_address (ch);
|
||||
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
|
||||
index 0bf0e13..33d1196 100644
|
||||
--- a/grub-core/loader/i386/pc/linux.c
|
||||
+++ b/grub-core/loader/i386/pc/linux.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/linux.h>
|
||||
#include <grub/efi/sb.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -231,8 +232,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
|
||||
|
||||
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
|
||||
- grub_linux16_prot_size = grub_file_size (file)
|
||||
- - real_size - GRUB_DISK_SECTOR_SIZE;
|
||||
+ if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) ||
|
||||
+ grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
if (! grub_linux_is_bzimage
|
||||
&& GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size
|
||||
diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
|
||||
index 8f662c8..cd24874 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 2f0ebd0..3fd6539 100644
|
||||
--- a/grub-core/loader/xnu.c
|
||||
+++ b/grub-core/loader/xnu.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/verify.h>
|
||||
#include <grub/efi/sb.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -60,15 +61,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_relocator_chunk_t ch;
|
||||
+ grub_addr_t tgt;
|
||||
+
|
||||
+ if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt))
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
|
||||
- err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
|
||||
- grub_xnu_heap_target_start
|
||||
- + grub_xnu_heap_size, size);
|
||||
+ err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*src = get_virtual_current_address (ch);
|
||||
- *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
|
||||
+ *target = tgt;
|
||||
grub_xnu_heap_size += size;
|
||||
grub_dprintf ("xnu", "val=%p\n", *src);
|
||||
return GRUB_ERR_NONE;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From 0f3f5b7c13fa9b677a64cf11f20eca0f850a2b20 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Hawrylko <lukasz.hawrylko@linux.intel.com>
|
||||
Date: Mon, 16 Dec 2019 11:15:55 +0100
|
||||
Subject: [PATCH] multiboot2: Set min address for mbi allocation to 0x1000
|
||||
|
||||
Subject: [PATCH 16/27] multiboot2: Set min address for mbi allocation to
|
||||
0x1000
|
||||
|
||||
In some cases GRUB2 allocates multiboot2 structure at 0 address, that is
|
||||
a confusing behavior. Consumers of that structure can have internal NULL-checks
|
||||
that will throw an error when get a pointer to data allocated at address 0.
|
||||
To prevent that, define min address for mbi allocation on x86 and x86_64
|
||||
platforms.
|
||||
|
||||
Signed-off-by: Lukasz Hawrylko <lukasz.hawrylko@linux.intel.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/loader/multiboot_mbi2.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
|
||||
index 0efc660..e88c9f4 100644
|
||||
--- a/grub-core/loader/multiboot_mbi2.c
|
||||
+++ b/grub-core/loader/multiboot_mbi2.c
|
||||
@@ -48,6 +48,12 @@
|
||||
#define HAS_VGA_TEXT 0
|
||||
#endif
|
||||
|
||||
+#if defined (__i386__) || defined (__x86_64__)
|
||||
+#define MBI_MIN_ADDR 0x1000
|
||||
+#else
|
||||
+#define MBI_MIN_ADDR 0
|
||||
+#endif
|
||||
+
|
||||
struct module
|
||||
{
|
||||
struct module *next;
|
||||
@@ -708,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
|
||||
COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
|
||||
- 0, 0xffffffff - bufsize,
|
||||
+ MBI_MIN_ADDR, 0xffffffff - bufsize,
|
||||
bufsize, MULTIBOOT_TAG_ALIGN,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
|
||||
if (err)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
334
0237-relocator-Protect-grub_relocator_alloc_chunk_align-m.patch
Normal file
334
0237-relocator-Protect-grub_relocator_alloc_chunk_align-m.patch
Normal file
@ -0,0 +1,334 @@
|
||||
From 61ff5602fe8f2a3446346795daebe4ec3b82c20f Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Wed, 8 Jul 2020 01:44:38 +0000
|
||||
Subject: [PATCH 17/27] relocator: Protect grub_relocator_alloc_chunk_align()
|
||||
max_addr against integer underflow
|
||||
|
||||
This commit introduces integer underflow mitigation in max_addr calculation
|
||||
in grub_relocator_alloc_chunk_align() invocation.
|
||||
|
||||
It consists of 2 fixes:
|
||||
1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform
|
||||
sanity check for min/max and size values, and to make safe invocation of
|
||||
grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all
|
||||
invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...)
|
||||
by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...).
|
||||
2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top
|
||||
address (0xffffffff - size + 1) or similar.
|
||||
---
|
||||
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 71dd4f0..34cbe83 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 9d5f49c..743b213 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 bdf2b11..8ffb8b6 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 3caef7a..7d200a1 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 90f2315..7d0c987 100644
|
||||
--- a/grub-core/loader/i386/linux.c
|
||||
+++ b/grub-core/loader/i386/linux.c
|
||||
@@ -182,9 +182,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
|
||||
for (; err && *align + 1 > min_align; (*align)--)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
- err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||
- 0x1000000,
|
||||
- 0xffffffff & ~prot_size,
|
||||
+ err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
|
||||
+ UP_TO_TOP32 (prot_size),
|
||||
prot_size, 1 << *align,
|
||||
GRUB_RELOCATOR_PREFERENCE_LOW,
|
||||
1);
|
||||
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
|
||||
index ad3cc29..a67d9d0 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 33d1196..f1ad185 100644
|
||||
--- a/grub-core/loader/i386/pc/linux.c
|
||||
+++ b/grub-core/loader/i386/pc/linux.c
|
||||
@@ -463,10 +463,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
- err = grub_relocator_alloc_chunk_align (relocator, &ch,
|
||||
- addr_min, addr_max - size,
|
||||
- size, 0x1000,
|
||||
- GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
|
||||
+ err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size,
|
||||
+ 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
|
||||
if (err)
|
||||
return err;
|
||||
initrd_chunk = get_virtual_current_address (ch);
|
||||
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
|
||||
index 7b723bf..e4ed959 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 3e6ad16..3e28690 100644
|
||||
--- a/grub-core/loader/multiboot.c
|
||||
+++ b/grub-core/loader/multiboot.c
|
||||
@@ -404,7 +404,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
|
||||
- lowest_addr, (0xffffffff - size) + 1,
|
||||
+ lowest_addr, UP_TO_TOP32 (size),
|
||||
size, MULTIBOOT_MOD_ALIGN,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
|
||||
if (err)
|
||||
diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
|
||||
index cc68536..f2318e0 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 e88c9f4..9a943d7 100644
|
||||
--- a/grub-core/loader/multiboot_mbi2.c
|
||||
+++ b/grub-core/loader/multiboot_mbi2.c
|
||||
@@ -301,10 +301,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
}
|
||||
|
||||
- err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
|
||||
- mld.min_addr, mld.max_addr - code_size,
|
||||
- code_size, mld.align ? mld.align : 1,
|
||||
- mld.preference, keep_bs);
|
||||
+ err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch,
|
||||
+ mld.min_addr, mld.max_addr,
|
||||
+ code_size, mld.align ? mld.align : 1,
|
||||
+ mld.preference, keep_bs);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator,
|
||||
@@ -714,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
|
||||
COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
|
||||
- MBI_MIN_ADDR, 0xffffffff - bufsize,
|
||||
+ MBI_MIN_ADDR, UP_TO_TOP32 (bufsize),
|
||||
bufsize, MULTIBOOT_TAG_ALIGN,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
|
||||
if (err)
|
||||
diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
|
||||
index 8089804..d648ef0 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 24d8672..1b3bdd9 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.23.0
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 78dc80eec01a56866a0732bf2f808ec26ae45a59 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 18/27] script: Remove unused fields from grub_script_function
|
||||
struct
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 360c2be..b382bcf 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.23.0
|
||||
|
||||
109
0239-script-Avoid-a-use-after-free-when-redefining-a-func.patch
Normal file
109
0239-script-Avoid-a-use-after-free-when-redefining-a-func.patch
Normal file
@ -0,0 +1,109 @@
|
||||
From 0b86881d32d66a0d21b71fdb148ec2accba1be6e 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 19/27] script: Avoid a use-after-free when redefining a
|
||||
function during execution
|
||||
|
||||
Defining a new function with the same name as a previously defined
|
||||
function causes the grub_script and associated resources for the
|
||||
previous function to be freed. If the previous function is currently
|
||||
executing when a function with the same name is defined, this results
|
||||
in use-after-frees when processing subsequent commands in the original
|
||||
function.
|
||||
|
||||
Instead, reject a new function definition if it has the same name as
|
||||
a previously defined function, and that function is currently being
|
||||
executed. Although a behavioural change, this should be backwards
|
||||
compatible with existing configurations because they can't be
|
||||
dependent on the current behaviour without being broken.
|
||||
|
||||
Fixes: CVE-2020-15706
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 b55e171..d2f02cc 100644
|
||||
--- a/grub-core/script/execute.c
|
||||
+++ b/grub-core/script/execute.c
|
||||
@@ -872,7 +872,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
|
||||
old_scope = scope;
|
||||
scope = &new_scope;
|
||||
|
||||
+ func->executing++;
|
||||
ret = grub_script_execute (func->func);
|
||||
+ func->executing--;
|
||||
|
||||
function_return = 0;
|
||||
active_loops = loops;
|
||||
diff --git a/grub-core/script/function.c b/grub-core/script/function.c
|
||||
index d36655e..3aad04b 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 4f0ab83..f80b86b 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 b382bcf..6c48e07 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.23.0
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From 93ec7ea234ae82499034313df0f63c01cb382520 Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Fri, 17 Jul 2020 05:17:26 +0000
|
||||
Subject: [PATCH 20/27] relocator: Fix grub_relocator_alloc_chunk_align() top
|
||||
memory allocation
|
||||
|
||||
Current implementation of grub_relocator_alloc_chunk_align()
|
||||
does not allow allocation of the top byte.
|
||||
|
||||
Assuming input args are:
|
||||
max_addr = 0xfffff000;
|
||||
size = 0x1000;
|
||||
|
||||
And this is valid. But following overflow protection will
|
||||
unnecessarily move max_addr one byte down (to 0xffffefff):
|
||||
if (max_addr > ~size)
|
||||
max_addr = ~size;
|
||||
|
||||
~size + 1 will fix the situation. In addition, check size
|
||||
for non zero to do not zero max_addr.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
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 5847aac..f2c1944 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.23.0
|
||||
|
||||
57
0241-hfsplus-Fix-two-more-overflows.patch
Normal file
57
0241-hfsplus-Fix-two-more-overflows.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 0c0c7f7de657dde6994c58e29133a7356f6f672f Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Sun, 19 Jul 2020 14:43:31 -0400
|
||||
Subject: [PATCH 21/27] hfsplus: Fix two more overflows
|
||||
|
||||
Both node->size and node->namelen come from the supplied filesystem,
|
||||
which may be user-supplied. We can't trust them for the math unless we
|
||||
know they don't overflow. Making sure they go through 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>
|
||||
---
|
||||
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 dae43be..9c4e4c8 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.23.0
|
||||
|
||||
112
0242-lvm-Fix-two-more-potential-data-dependent-alloc-over.patch
Normal file
112
0242-lvm-Fix-two-more-potential-data-dependent-alloc-over.patch
Normal file
@ -0,0 +1,112 @@
|
||||
From 4a56a951ae3cc8ff25f94a291051b5246f1b828a Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Sun, 19 Jul 2020 15:48:20 -0400
|
||||
Subject: [PATCH 22/27] lvm: Fix two more potential data-dependent alloc
|
||||
overflows
|
||||
|
||||
It appears to be possible to make a (possibly invalid) lvm PV with
|
||||
a metadata size field that overflows our type when adding it to the
|
||||
address we've allocated. Even if it doesn't, it may be possible to do so
|
||||
with the math using the outcome of that as an operand. Check them both.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 8e76d1a..9f5630c 100644
|
||||
--- a/grub-core/disk/lvm.c
|
||||
+++ b/grub-core/disk/lvm.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/lvm.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/misc.h>
|
||||
@@ -102,10 +103,11 @@ grub_lvm_detect (grub_disk_t disk,
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_uint64_t mda_offset, mda_size;
|
||||
+ grub_size_t ptr;
|
||||
char buf[GRUB_LVM_LABEL_SIZE];
|
||||
char vg_id[GRUB_LVM_ID_STRLEN+1];
|
||||
char pv_id[GRUB_LVM_ID_STRLEN+1];
|
||||
- char *metadatabuf, *vgname;
|
||||
+ char *metadatabuf, *mda_end, *vgname;
|
||||
const char *p, *q;
|
||||
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
|
||||
struct grub_lvm_pv_header *pvh;
|
||||
@@ -206,19 +208,31 @@ grub_lvm_detect (grub_disk_t disk,
|
||||
grub_le_to_cpu64 (rlocn->size) -
|
||||
grub_le_to_cpu64 (mdah->size));
|
||||
}
|
||||
- p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
|
||||
|
||||
- while (*q != ' ' && q < metadatabuf + mda_size)
|
||||
- q++;
|
||||
-
|
||||
- if (q == metadatabuf + mda_size)
|
||||
+ if (grub_add ((grub_size_t)metadatabuf,
|
||||
+ (grub_size_t)grub_le_to_cpu64 (rlocn->offset),
|
||||
+ &ptr))
|
||||
{
|
||||
+ error_parsing_metadata:
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("error parsing metadata");
|
||||
#endif
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
+ p = q = (char *)ptr;
|
||||
+
|
||||
+ if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
|
||||
+ goto error_parsing_metadata;
|
||||
+
|
||||
+ mda_end = (char *)ptr;
|
||||
+
|
||||
+ while (*q != ' ' && q < mda_end)
|
||||
+ q++;
|
||||
+
|
||||
+ if (q == mda_end)
|
||||
+ goto error_parsing_metadata;
|
||||
+
|
||||
vgname_len = q - p;
|
||||
vgname = grub_malloc (vgname_len + 1);
|
||||
if (!vgname)
|
||||
@@ -368,8 +382,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.23.0
|
||||
|
||||
235
0243-efi-Fix-some-malformed-device-path-arithmetic-errors.patch
Normal file
235
0243-efi-Fix-some-malformed-device-path-arithmetic-errors.patch
Normal file
@ -0,0 +1,235 @@
|
||||
From 8088b8c61e7b45dd8d6115eac72bc718e261e6fe Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Sun, 19 Jul 2020 16:53:27 -0400
|
||||
Subject: [PATCH 23/27] efi: Fix some malformed device path arithmetic errors
|
||||
|
||||
Several places we take the length of a device path and subtract 4 from
|
||||
it, without ever checking that it's >= 4. There are also cases where
|
||||
this kind of malformation will result in unpredictable iteration,
|
||||
including treating the length from one dp node as the type in the next
|
||||
node. These are all errors, no matter where the data comes from.
|
||||
|
||||
This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
|
||||
can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
|
||||
return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
|
||||
the length is too small. Additionally, it makes several places in the
|
||||
code check for and return errors in these cases.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 ab133fe..d6f7bf0 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -350,7 +350,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||
|
||||
dp = dp0;
|
||||
|
||||
- while (1)
|
||||
+ while (dp)
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
@@ -360,9 +360,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||
if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
||||
&& subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
{
|
||||
- grub_efi_uint16_t len;
|
||||
- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
- / sizeof (grub_efi_char16_t));
|
||||
+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||
+
|
||||
+ if (len < 4)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ "malformed EFI Device Path node has length=%d", len);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ len = (len - 4) / sizeof (grub_efi_char16_t);
|
||||
filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
|
||||
}
|
||||
|
||||
@@ -378,7 +384,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
- while (1)
|
||||
+ while (dp)
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
@@ -394,8 +400,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||
|
||||
*p++ = '/';
|
||||
|
||||
- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
- / sizeof (grub_efi_char16_t));
|
||||
+ len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||
+ if (len < 4)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ "malformed EFI Device Path node has length=%d", len);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ len = (len - 4) / sizeof (grub_efi_char16_t);
|
||||
fp = (grub_efi_file_path_device_path_t *) dp;
|
||||
/* According to EFI spec Path Name is NULL terminated */
|
||||
while (len > 0 && fp->path_name[len - 1] == 0)
|
||||
@@ -470,7 +483,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
|
||||
;
|
||||
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
||||
{
|
||||
- total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
||||
+ grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
||||
+
|
||||
+ /*
|
||||
+ * In the event that we find a node that's completely garbage, for
|
||||
+ * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size
|
||||
+ * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and
|
||||
+ * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue,
|
||||
+ * and neither should our consumers, but there won't be any error raised
|
||||
+ * even though the device path is junk.
|
||||
+ *
|
||||
+ * This keeps us from passing junk down back to our caller.
|
||||
+ */
|
||||
+ if (len < 4)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ "malformed EFI Device Path node has length=%d", len);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ total_size += len;
|
||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
||||
break;
|
||||
}
|
||||
@@ -515,7 +547,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
||||
void
|
||||
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
{
|
||||
- while (1)
|
||||
+ while (GRUB_EFI_DEVICE_PATH_VALID (dp))
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
@@ -987,7 +1019,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;
|
||||
@@ -1023,5 +1058,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 7365051..9a99f04 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -165,9 +165,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 e9e1192..a700936 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 dec7b06..fc8a564 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -666,6 +666,7 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
|
||||
#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
|
||||
#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
|
||||
#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
|
||||
+#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4)
|
||||
|
||||
/* The End of Device Path nodes. */
|
||||
#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
|
||||
@@ -674,13 +675,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
|
||||
#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
|
||||
|
||||
#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
|
||||
- (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
|
||||
- && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
|
||||
- == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
|
||||
+ (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \
|
||||
+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
|
||||
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
|
||||
+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)))
|
||||
|
||||
#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
|
||||
- ((grub_efi_device_path_t *) ((char *) (dp) \
|
||||
- + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
|
||||
+ (GRUB_EFI_DEVICE_PATH_VALID (dp) \
|
||||
+ ? ((grub_efi_device_path_t *) \
|
||||
+ ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \
|
||||
+ : NULL)
|
||||
|
||||
/* Hardware Device Path. */
|
||||
#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From 098058752e1cee7b457ff45562a81e756ab0b532 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 24/27] efi/chainloader: Propagate errors from copy_file_path()
|
||||
|
||||
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>
|
||||
---
|
||||
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 9a99f04..813dc0e 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -115,7 +115,7 @@ grub_chainloader_boot (void)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
-static void
|
||||
+static grub_err_t
|
||||
copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
const char *str, grub_efi_uint16_t len)
|
||||
{
|
||||
@@ -127,7 +127,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);
|
||||
@@ -140,6 +140,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
fp->path_name[size++] = '\0';
|
||||
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
|
||||
grub_free (path_name);
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_efi_device_path_t *
|
||||
@@ -197,13 +198,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
/* Fill the file path for the directory. */
|
||||
d = (grub_efi_device_path_t *) ((char *) file_path
|
||||
+ ((char *) d - (char *) dp));
|
||||
- copy_file_path ((grub_efi_file_path_device_path_t *) d,
|
||||
- dir_start, dir_end - dir_start);
|
||||
+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
|
||||
+ dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+fail:
|
||||
+ grub_free(file_path);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
/* Fill the file path for the file. */
|
||||
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
|
||||
- copy_file_path ((grub_efi_file_path_device_path_t *) d,
|
||||
- dir_end + 1, grub_strlen (dir_end + 1));
|
||||
+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
|
||||
+ dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
/* Fill the end of device path nodes. */
|
||||
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
179
0245-efi-Fix-use-after-free-in-halt-reboot-path.patch
Normal file
179
0245-efi-Fix-use-after-free-in-halt-reboot-path.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From f7bd9986f607a924bf23b813900a8595f2815f0c Mon Sep 17 00:00:00 2001
|
||||
From: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Date: Mon, 20 Jul 2020 23:03:05 +0000
|
||||
Subject: [PATCH 25/27] efi: Fix use-after-free in halt/reboot path
|
||||
|
||||
commit 92bfc33db984 ("efi: Free malloc regions on exit")
|
||||
introduced memory freeing in grub_efi_fini(), which is
|
||||
used not only by exit path but by halt/reboot one as well.
|
||||
As result of memory freeing, code and data regions used by
|
||||
modules, such as halt, reboot, acpi (used by halt) also got
|
||||
freed. After return to module code, CPU executes, filled
|
||||
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
|
||||
a code. Which leads to #UD exception later.
|
||||
|
||||
grub> halt
|
||||
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
|
||||
RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
|
||||
RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
|
||||
RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
|
||||
RSI - 00000000064DB768, RDI - 000000000832C5C3
|
||||
R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
|
||||
R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
|
||||
R14 - 0000000003E10D80, R15 - 00000000061E2F60
|
||||
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
|
||||
GS - 0000000000000030, SS - 0000000000000030
|
||||
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
|
||||
CR4 - 0000000000000668, CR8 - 0000000000000000
|
||||
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
|
||||
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
|
||||
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
|
||||
IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
|
||||
FXSAVE_STATE - 0000000007F0F4C0
|
||||
|
||||
Proposal here is to continue to free allocated memory for
|
||||
exit boot services path but keep it for halt/reboot path
|
||||
as it won't be much security concern here.
|
||||
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
|
||||
loader flag to be used by efi halt/reboot path.
|
||||
|
||||
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
|
||||
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/arm/efi/init.c | 3 +++
|
||||
grub-core/kern/arm64/efi/init.c | 3 +++
|
||||
grub-core/kern/efi/efi.c | 3 ++-
|
||||
grub-core/kern/efi/init.c | 1 -
|
||||
grub-core/kern/i386/efi/init.c | 9 +++++++--
|
||||
grub-core/kern/ia64/efi/init.c | 9 +++++++--
|
||||
grub-core/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 06df60e..40c3b46 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 6224999..5010cae 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 d6f7bf0..c45c8f4 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 d1afa3a..2ffb520 100644
|
||||
--- a/grub-core/kern/efi/init.c
|
||||
+++ b/grub-core/kern/efi/init.c
|
||||
@@ -131,5 +131,4 @@ grub_efi_fini (void)
|
||||
{
|
||||
grub_efidisk_fini ();
|
||||
grub_console_fini ();
|
||||
- grub_efi_memory_fini ();
|
||||
}
|
||||
diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
|
||||
index da499ab..deb2eac 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 b5ecbd0..f196557 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 7eb1969..38795fe 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 5859f04..29d4136 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 7f82a49..b208642 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.23.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From cb79f0455946270ddaf6b098d8cd71b39f840edc Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 24 Jul 2020 13:57:27 -0400
|
||||
Subject: [PATCH 26/27] loader/linux: Avoid overflow on initrd size calculation
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 471b214..4cd8c20 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.23.0
|
||||
|
||||
169
0247-linux-Fix-integer-overflows-in-initrd-size-handling.patch
Normal file
169
0247-linux-Fix-integer-overflows-in-initrd-size-handling.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 4edf7dc1bf561beb36fe245348a91d3bde699f15 Mon Sep 17 00:00:00 2001
|
||||
From: Colin Watson <cjwatson@debian.org>
|
||||
Date: Sat, 25 Jul 2020 12:15:37 +0100
|
||||
Subject: [PATCH 27/27] linux: Fix integer overflows in initrd size handling
|
||||
|
||||
These could be triggered by a crafted filesystem with very large files.
|
||||
|
||||
Fixes: CVE-2020-15707
|
||||
|
||||
Signed-off-by: Colin Watson <cjwatson@debian.org>
|
||||
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.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 4cd8c20..3fe390f 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.23.0
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From b01dc9aaedb5a5e91e2ca10748fce65406d657c0 Mon Sep 17 00:00:00 2001
|
||||
From: Fedora Ninjas <grub2-owner@fedoraproject.org>
|
||||
Date: Mon, 10 Aug 2020 14:54:34 +0800
|
||||
Subject: [PATCH 7/7] linuxefi: fail kernel validation without shim protocol.
|
||||
|
||||
If certificates that signed grub are installed into db, grub can be
|
||||
booted directly. It will then boot any kernel without signature
|
||||
validation. The booted kernel will think it was booted in secureboot
|
||||
mode and will implement lockdown, yet it could have been tampered.
|
||||
|
||||
This version of the patch skips calling verification, when booted
|
||||
without secureboot. And is indented with gnu ident.
|
||||
|
||||
CVE-2020-15705
|
||||
|
||||
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
|
||||
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
|
||||
Signed-off-by: Baogen Shang <baogen.shang@windriver.com.cn>
|
||||
---
|
||||
grub-core/loader/arm64/linux.c | 12 ++++++++----
|
||||
grub-core/loader/efi/linux.c | 1 +
|
||||
grub-core/loader/i386/efi/linux.c | 13 ++++++++-----
|
||||
3 files changed, 17 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
|
||||
index 8791b35..a18c487 100644
|
||||
--- a/grub-core/loader/arm64/linux.c
|
||||
+++ b/grub-core/loader/arm64/linux.c
|
||||
@@ -383,11 +383,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
|
||||
- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
|
||||
- if (rc < 0)
|
||||
+ if (grub_efi_secure_boot ())
|
||||
{
|
||||
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
||||
- goto fail;
|
||||
+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
|
||||
+ if (rc <= 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
+ N_("%s has invalid signature"), argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index e09f824..927d89a 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
|
||||
};
|
||||
typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
||||
|
||||
+// Returns 1 on success, -1 on error, 0 when not available
|
||||
int
|
||||
grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||
{
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index e5b2736..e613115 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -301,12 +301,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- rc = grub_linuxefi_secure_validate (kernel, filelen);
|
||||
- if (rc < 0)
|
||||
+ if (grub_efi_secure_boot ())
|
||||
{
|
||||
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"),
|
||||
- argv[0]);
|
||||
- goto fail;
|
||||
+ rc = grub_linuxefi_secure_validate (kernel, filelen);
|
||||
+ if (rc <= 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
+ N_("%s has invalid signature"), argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
lh = (struct linux_i386_kernel_header *)kernel;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
34
grub.patches
34
grub.patches
@ -215,6 +215,34 @@ Patch0214: 0214-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch
|
||||
Patch0215: 0215-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch
|
||||
Patch0216: 0216-fix-build-with-rpm-4.16.patch
|
||||
Patch0217: 0217-Only-mark-GRUB-as-BLS-supported-in-OSTree-systems-wi.patch
|
||||
Patch9000: support-TPM2.0-in-grub2-both-legacy-and-efi.patch
|
||||
Patch9001: Workaround-for-EFI-Bug-Plan3.patch
|
||||
Patch9002: bugfix-remove-excess-qutos.patch
|
||||
Patch0218: 0218-support-TPM2.0-in-grub2-both-legacy-and-efi.patch
|
||||
Patch0219: 0219-Workaround-for-EFI-Bug-Plan3.patch
|
||||
Patch0220: 0220-bugfix-remove-excess-qutos.patch
|
||||
Patch0221: 0221-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch
|
||||
Patch0222: 0222-safemath-Add-some-arithmetic-primitives-that-check-f.patch
|
||||
Patch0223: 0223-calloc-Make-sure-we-always-have-an-overflow-checking.patch
|
||||
Patch0224: 0224-calloc-Use-calloc-at-most-places.patch
|
||||
Patch0225: 0225-malloc-Use-overflow-checking-primitives-where-we-do-.patch
|
||||
Patch0226: 0226-iso9660-Don-t-leak-memory-on-realloc-failures.patch
|
||||
Patch0227: 0227-font-Do-not-load-more-than-one-NAME-section.patch
|
||||
Patch0228: 0228-gfxmenu-Fix-double-free-in-load_image.patch
|
||||
Patch0229: 0229-xnu-Fix-double-free-in-grub_xnu_devprop_add_property.patch
|
||||
Patch0230: 0230-lzma-Make-sure-we-don-t-dereference-past-array.patch
|
||||
Patch0231: 0231-term-Fix-overflow-on-user-inputs.patch
|
||||
Patch0232: 0232-udf-Fix-memory-leak.patch
|
||||
Patch0233: 0233-multiboot2-Fix-memory-leak-if-grub_create_loader_cmd.patch
|
||||
Patch0234: 0234-tftp-Do-not-use-priority-queue.patch
|
||||
Patch0235: 0235-relocator-Protect-grub_relocator_alloc_chunk_addr-in.patch
|
||||
Patch0236: 0236-multiboot2-Set-min-address-for-mbi-allocation-to-0x1.patch
|
||||
Patch0237: 0237-relocator-Protect-grub_relocator_alloc_chunk_align-m.patch
|
||||
Patch0238: 0238-script-Remove-unused-fields-from-grub_script_functio.patch
|
||||
Patch0239: 0239-script-Avoid-a-use-after-free-when-redefining-a-func.patch
|
||||
Patch0240: 0240-relocator-Fix-grub_relocator_alloc_chunk_align-top-m.patch
|
||||
Patch0241: 0241-hfsplus-Fix-two-more-overflows.patch
|
||||
Patch0242: 0242-lvm-Fix-two-more-potential-data-dependent-alloc-over.patch
|
||||
Patch0243: 0243-efi-Fix-some-malformed-device-path-arithmetic-errors.patch
|
||||
Patch0244: 0244-efi-chainloader-Propagate-errors-from-copy_file_path.patch
|
||||
Patch0245: 0245-efi-Fix-use-after-free-in-halt-reboot-path.patch
|
||||
Patch0246: 0246-loader-linux-Avoid-overflow-on-initrd-size-calculati.patch
|
||||
Patch0247: 0247-linux-Fix-integer-overflows-in-initrd-size-handling.patch
|
||||
Patch0248: 0248-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||
|
||||
12
grub2.spec
12
grub2.spec
@ -7,7 +7,7 @@
|
||||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.04
|
||||
Release: 2
|
||||
Release: 3
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
License: GPLv3+
|
||||
URL: http://www.gnu.org/software/grub/
|
||||
@ -392,13 +392,19 @@ rm -r /boot/grub2.tmp/ || :
|
||||
%{_datadir}/man/man*
|
||||
|
||||
%changelog
|
||||
* Fri Aug 7 2020 hanzhijun <hanzhijun1@huawei.com> - 2.04-3
|
||||
- Type:cves
|
||||
- Id:CVE-2020-10713 CVE-2020-14308 CVE-2020-14309 CVE-2020-14310 CVE-2020-14311 CVE-2020-15705 CVE-2020-15706 CVE-2020-15707
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2020-10713 CVE-2020-14308 CVE-2020-14309 CVE-2020-14310 CVE-2020-14311 CVE-2020-15705 CVE-2020-15706 CVE-2020-15707
|
||||
|
||||
* Mon Aug 3 2020 hanzhijun <hanzhijun1@huawei.com> - 2.04-2
|
||||
- add CPPFLAGS
|
||||
|
||||
* Mon Aug 1 2020 hanzhijun <hanzhijun1@huawei.com> - 2.04-1
|
||||
* Sat Aug 1 2020 hanzhijun <hanzhijun1@huawei.com> - 2.04-1
|
||||
- update to 2.0.4
|
||||
|
||||
* Fri July 17 2020 chenyaqiang <chenyaqiang@huawei.com> - 2.02-75
|
||||
* Fri Jul 17 2020 chenyaqiang <chenyaqiang@huawei.com> - 2.02-75
|
||||
- remove repeated buildrequest packge “rpm-devel” in grub2.spec
|
||||
|
||||
* Fri Apr 24 2020 fengtao <fengtao40@huawei.com> - 2.02-74
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user