import grub2-2.02-99.el8

This commit is contained in:
CentOS Sources 2021-03-30 11:50:09 -04:00 committed by Stepan Oksanichenko
parent 4d58227411
commit 639656e40c
208 changed files with 36753 additions and 18 deletions

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Fri, 26 Jun 2020 10:51:43 -0400
Subject: [PATCH] multiboot2: Fix memory leak if grub_create_loader_cmdline()
fails
Fixes: CID 292468
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: cd6760b6289
---
grub-core/loader/multiboot_mbi2.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 54078455e2f..872dcd42e97 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -1089,6 +1089,7 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
{
struct module *newmod;
grub_size_t len = 0;
+ grub_err_t err = 0;
newmod = grub_malloc (sizeof (*newmod));
if (!newmod)
@@ -1107,8 +1108,14 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
- grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
+ newmod->cmdline_size);
+ if (err)
+ {
+ grub_free (newmod->cmdline);
+ grub_free (newmod);
+ return err;
+ }
if (modules_last)
modules_last->next = newmod;

View File

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

View File

@ -0,0 +1,147 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 15 Jul 2020 06:42:37 +0000
Subject: [PATCH] relocator: Protect grub_relocator_alloc_chunk_addr() input
args against integer underflow/overflow
Use arithmetic macros from safemath.h to accomplish it. In this commit,
I didn't want to be too paranoid to check every possible math equation
for overflow/underflow. Only obvious places (with non zero chance of
overflow/underflow) were refactored.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: ebb15735f10
---
grub-core/loader/i386/linux.c | 9 +++++++--
grub-core/loader/i386/pc/linux.c | 9 +++++++--
grub-core/loader/i386/xen.c | 12 ++++++++++--
grub-core/loader/xnu.c | 11 +++++++----
4 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 76304f05700..b4a30f607fa 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/efi/sb.h>
#include <grub/tpm.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -593,9 +594,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 783a3cd93bc..540891371f9 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 3073f64d5e5..85b93347b25 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -40,6 +40,7 @@
#include <grub/xen_file.h>
#include <grub/linux.h>
#include <grub/i386/memory.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -635,6 +636,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"));
@@ -699,8 +701,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 dc7d5409e1e..2bf02489bad 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -34,6 +34,7 @@
#include <grub/env.h>
#include <grub/i18n.h>
#include <grub/efi/sb.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
{
grub_err_t err;
grub_relocator_chunk_t ch;
+ grub_addr_t tgt;
+
+ if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt))
+ return GRUB_ERR_OUT_OF_RANGE;
- err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
- grub_xnu_heap_target_start
- + grub_xnu_heap_size, size);
+ err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size);
if (err)
return err;
*src = get_virtual_current_address (ch);
- *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
+ *target = tgt;
grub_xnu_heap_size += size;
grub_dprintf ("xnu", "val=%p\n", *src);
return GRUB_ERR_NONE;

View File

@ -0,0 +1,335 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Wed, 8 Jul 2020 01:44:38 +0000
Subject: [PATCH] relocator: Protect grub_relocator_alloc_chunk_align()
max_addr against integer underflow
This commit introduces integer underflow mitigation in max_addr calculation
in grub_relocator_alloc_chunk_align() invocation.
It consists of 2 fixes:
1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform
sanity check for min/max and size values, and to make safe invocation of
grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all
invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...)
by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...).
2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top
address (0xffffffff - size + 1) or similar.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-commit-id: 10498c8ba17
---
grub-core/lib/i386/relocator.c | 28 +++++++++++-----------------
grub-core/lib/mips/relocator.c | 6 ++----
grub-core/lib/powerpc/relocator.c | 6 ++----
grub-core/lib/x86_64/efi/relocator.c | 7 +++----
grub-core/loader/i386/linux.c | 5 ++---
grub-core/loader/i386/multiboot_mbi.c | 7 +++----
grub-core/loader/i386/pc/linux.c | 6 ++----
grub-core/loader/mips/linux.c | 9 +++------
grub-core/loader/multiboot.c | 2 +-
grub-core/loader/multiboot_elfxx.c | 10 +++++-----
grub-core/loader/multiboot_mbi2.c | 10 +++++-----
grub-core/loader/xnu_resume.c | 2 +-
include/grub/relocator.h | 29 +++++++++++++++++++++++++++++
13 files changed, 69 insertions(+), 58 deletions(-)
diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
index 71dd4f0ab0c..34cbe834fa3 100644
--- a/grub-core/lib/i386/relocator.c
+++ b/grub-core/lib/i386/relocator.c
@@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel,
/* Specific memory range due to Global Descriptor Table for use by payload
that we will store in returned chunk. The address range and preference
are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000,
- 0x9a000 - RELOCATOR_SIZEOF (32),
- RELOCATOR_SIZEOF (32), 16,
- GRUB_RELOCATOR_PREFERENCE_LOW,
- avoid_efi_bootservices);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000,
+ RELOCATOR_SIZEOF (32), 16,
+ GRUB_RELOCATOR_PREFERENCE_LOW,
+ avoid_efi_bootservices);
if (err)
return err;
@@ -125,13 +124,10 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator_chunk_t ch;
/* Put it higher than the byte it checks for A20 check. */
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
- 0xa0000 - RELOCATOR_SIZEOF (16)
- - GRUB_RELOCATOR16_STACK_SIZE,
- RELOCATOR_SIZEOF (16)
- + GRUB_RELOCATOR16_STACK_SIZE, 16,
- GRUB_RELOCATOR_PREFERENCE_NONE,
- 0);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000,
+ RELOCATOR_SIZEOF (16) +
+ GRUB_RELOCATOR16_STACK_SIZE, 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
@@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel,
void *relst;
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
- max_addr - RELOCATOR_SIZEOF (64),
- RELOCATOR_SIZEOF (64), 16,
- GRUB_RELOCATOR_PREFERENCE_NONE,
- 0);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr,
+ RELOCATOR_SIZEOF (64), 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c
index 9d5f49cb93a..743b213e695 100644
--- a/grub-core/lib/mips/relocator.c
+++ b/grub-core/lib/mips/relocator.c
@@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
unsigned i;
grub_addr_t vtarget;
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- (0xffffffff - stateset_size)
- + 1, stateset_size,
- sizeof (grub_uint32_t),
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
+ stateset_size, sizeof (grub_uint32_t),
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c
index bdf2b111be7..8ffb8b68683 100644
--- a/grub-core/lib/powerpc/relocator.c
+++ b/grub-core/lib/powerpc/relocator.c
@@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
unsigned i;
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- (0xffffffff - stateset_size)
- + 1, stateset_size,
- sizeof (grub_uint32_t),
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
+ stateset_size, sizeof (grub_uint32_t),
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
if (err)
return err;
diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c
index 3caef7a4021..7d200a125ee 100644
--- a/grub-core/lib/x86_64/efi/relocator.c
+++ b/grub-core/lib/x86_64/efi/relocator.c
@@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel,
* 64-bit relocator code may live above 4 GiB quite well.
* However, I do not want ask for problems. Just in case.
*/
- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- 0x100000000 - RELOCATOR_SIZEOF (64_efi),
- RELOCATOR_SIZEOF (64_efi), 16,
- GRUB_RELOCATOR_PREFERENCE_NONE, 1);
+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000,
+ RELOCATOR_SIZEOF (64_efi), 16,
+ GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
return err;
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index b4a30f607fa..191f1631e88 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -231,9 +231,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 ca85358f771..9d3466d6ace 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -470,10 +470,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 540891371f9..63736fae950 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -460,10 +460,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 5f383be3d07..27c1db84a44 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -434,12 +434,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 9a8dae5565b..f455e803910 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -407,7 +407,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
- lowest_addr, (0xffffffff - size) + 1,
+ lowest_addr, UP_TO_TOP32 (size),
size, MULTIBOOT_MOD_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
index cc6853692a8..f2318e0d165 100644
--- a/grub-core/loader/multiboot_elfxx.c
+++ b/grub-core/loader/multiboot_elfxx.c
@@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
- err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
- mld->min_addr, mld->max_addr - load_size,
- load_size, mld->align ? mld->align : 1,
- mld->preference, mld->avoid_efi_boot_services);
+ err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch,
+ mld->min_addr, mld->max_addr,
+ load_size, mld->align ? mld->align : 1,
+ mld->preference, mld->avoid_efi_boot_services);
if (err)
{
@@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
continue;
err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0,
- (0xffffffff - sh->sh_size) + 1,
+ UP_TO_TOP32 (sh->sh_size),
sh->sh_size, sh->sh_addralign,
GRUB_RELOCATOR_PREFERENCE_NONE,
mld->avoid_efi_boot_services);
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 872dcd42e97..3cfb47650a0 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -298,10 +298,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,
@@ -747,7 +747,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
- 0, 0xffffffff - bufsize,
+ 0, UP_TO_TOP32 (bufsize),
bufsize, MULTIBOOT_TAG_ALIGN,
GRUB_RELOCATOR_PREFERENCE_NONE, 1);
if (err)
diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
index 534a74438b2..99119558d21 100644
--- a/grub-core/loader/xnu_resume.c
+++ b/grub-core/loader/xnu_resume.c
@@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename)
{
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
- (0xffffffff - hibhead.image_size) + 1,
+ UP_TO_TOP32 (hibhead.image_size),
hibhead.image_size,
GRUB_XNU_PAGESIZE,
GRUB_RELOCATOR_PREFERENCE_NONE, 0);
diff --git a/include/grub/relocator.h b/include/grub/relocator.h
index 24d8672d22c..1b3bdd92ac6 100644
--- a/include/grub/relocator.h
+++ b/include/grub/relocator.h
@@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
int preference,
int avoid_efi_boot_services);
+/*
+ * Wrapper for grub_relocator_alloc_chunk_align() with purpose of
+ * protecting against integer underflow.
+ *
+ * Compare to its callee, max_addr has different meaning here.
+ * It covers entire chunk and not just start address of the chunk.
+ */
+static inline grub_err_t
+grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel,
+ grub_relocator_chunk_t *out,
+ grub_phys_addr_t min_addr,
+ grub_phys_addr_t max_addr,
+ grub_size_t size, grub_size_t align,
+ int preference,
+ int avoid_efi_boot_services)
+{
+ /* Sanity check and ensure following equation (max_addr - size) is safe. */
+ if (max_addr < size || (max_addr - size) < min_addr)
+ return GRUB_ERR_OUT_OF_RANGE;
+
+ return grub_relocator_alloc_chunk_align (rel, out, min_addr,
+ max_addr - size,
+ size, align, preference,
+ avoid_efi_boot_services);
+}
+
+/* Top 32-bit address minus s bytes and plus 1 byte. */
+#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1)
+
#define GRUB_RELOCATOR_PREFERENCE_NONE 0
#define GRUB_RELOCATOR_PREFERENCE_LOW 1
#define GRUB_RELOCATOR_PREFERENCE_HIGH 2

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,109 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 15:48:20 -0400
Subject: [PATCH] lvm: fix two more potential data-dependent alloc overflows
It appears to be possible to make a (possibly invalid) lvm PV with a
metadata size field that overflows our type when adding it to the
address we've allocated. Even if it doesn't, it may be possible to do
so with the math using the outcome of that as an operand. Check them
both.
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Upstream-commit-id: 45ec6046ea0
---
grub-core/disk/lvm.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index d1df640b311..ca09d469990 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,12 @@ grub_lvm_detect (grub_disk_t disk,
{
grub_err_t err;
grub_uint64_t mda_offset, mda_size;
+ grub_size_t ptr;
char buf[GRUB_LVM_LABEL_SIZE];
char vg_id[GRUB_LVM_ID_STRLEN+1];
char pv_id[GRUB_LVM_ID_STRLEN+1];
- char *metadatabuf, *p, *q, *vgname;
+ char *metadatabuf, *mda_end, *vgname;
+ char *p, *q;
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
struct grub_lvm_pv_header *pvh;
struct grub_lvm_disk_locn *dlocn;
@@ -205,19 +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)
@@ -367,8 +382,25 @@ grub_lvm_detect (grub_disk_t disk,
{
const char *iptr;
char *optr;
- lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
- + 1 + 2 * s + 1);
+
+ /* this is kind of hard to read with our safe (but rather
+ * baroque) math primatives, but it boils down to:
+ *
+ * sz0 = vgname_len * 2 + 1
+ * + s * 2 + 1
+ * + sizeof ("lvm/") - 1;
+ */
+ grub_size_t sz0 = vgname_len, sz1 = s;
+
+ if (grub_mul (sz0, 2, &sz0) ||
+ grub_add (sz0, 1, &sz0) ||
+ grub_mul (sz1, 2, &sz1) ||
+ grub_add (sz1, 1, &sz1) ||
+ grub_add (sz0, sz1, &sz0) ||
+ grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
+ goto lvs_fail;
+
+ lv->fullname = grub_malloc (sz0);
if (!lv->fullname)
goto lvs_fail;

View File

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

View File

@ -0,0 +1,248 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 19 Jul 2020 16:53:27 -0400
Subject: [PATCH] efi: fix some malformed device path arithmetic errors.
Several places we take the length of a device path and subtract 4 from
it, without ever checking that it's >= 4. There are also cases where
this kind of malformation will result in unpredictable iteration,
including treating the length from one dp node as the type in the next
node. These are all errors, no matter where the data comes from.
This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
the length is too small. Additionally, it makes several places in the
code check for and return errors in these cases.
Signed-off-by: Peter Jones <pjones@redhat.com>
Upstream-commit-id: 23e68a83990
---
grub-core/kern/efi/efi.c | 67 ++++++++++++++++++++++++++++++++------
grub-core/loader/efi/chainloader.c | 19 +++++++++--
grub-core/loader/i386/xnu.c | 9 ++---
include/grub/efi/api.h | 14 +++++---
4 files changed, 88 insertions(+), 21 deletions(-)
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index b1379b92fb8..03de9cb14e7 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -344,7 +344,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);
@@ -354,9 +354,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;
}
@@ -372,7 +378,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);
@@ -388,8 +394,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)
@@ -464,7 +477,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;
}
@@ -509,7 +541,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);
@@ -981,7 +1013,11 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
/* Return non-zero. */
return 1;
- while (1)
+ if (dp1 == dp2)
+ return 0;
+
+ while (GRUB_EFI_DEVICE_PATH_VALID (dp1)
+ && GRUB_EFI_DEVICE_PATH_VALID (dp2))
{
grub_efi_uint8_t type1, type2;
grub_efi_uint8_t subtype1, subtype2;
@@ -1017,5 +1053,16 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
}
+ /*
+ * There's no "right" answer here, but we probably don't want to call a valid
+ * dp and an invalid dp equal, so pick one way or the other.
+ */
+ if (GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
+ !GRUB_EFI_DEVICE_PATH_VALID (dp2))
+ return 1;
+ else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
+ GRUB_EFI_DEVICE_PATH_VALID (dp2))
+ return -1;
+
return 0;
}
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2da119ad513..c2411b6dab2 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -125,6 +125,12 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
+ if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
+ {
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
+ return;
+ }
+
path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
if (!path_name)
return;
@@ -164,9 +170,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 c760db30fc0..44f7ebfa2b6 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 6c440c61316..a092fddb629 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -671,6 +671,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)
@@ -679,13 +680,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
- (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
- && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
- == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+ (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \
+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)))
#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
- ((grub_efi_device_path_t *) ((char *) (dp) \
- + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+ (GRUB_EFI_DEVICE_PATH_VALID (dp) \
+ ? ((grub_efi_device_path_t *) \
+ ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \
+ : NULL)
/* Hardware Device Path. */
#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1

View File

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

View File

@ -0,0 +1,147 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Burmashev <alexander.burmashev@oracle.com>
Date: Wed, 22 Jul 2020 06:04:38 -0700
Subject: [PATCH] update safemath with fallback code for gcc older than 5.1
The code used in the header was taken from linux kernel commit
f0907827a8a9152aedac2833ed1b674a7b2a44f2. Rasmus Villemoes
<linux@rasmusvillemoes.dk>, the original author of the patch, was
contacted directly, confirmed his authorship of the code, and gave his
permission on treating that dual license as MIT and including into GRUB2
sources
Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com>
---
include/grub/safemath.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 118 insertions(+), 1 deletion(-)
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
index c17b89bba17..1ccac276b59 100644
--- a/include/grub/safemath.h
+++ b/include/grub/safemath.h
@@ -31,7 +31,124 @@
#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
+/*
+ * Copyright 2020 Rasmus Villemoes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+/*
+ * The code used in this header was taken from linux kernel commit
+ * f0907827a8a9152aedac2833ed1b674a7b2a44f2
+ * Rasmus Villemoes <linux@rasmusvillemoes.dk>, the original author of the
+ * patch, was contacted directly, confirmed his authorship of the code, and
+ * gave his permission on treating that dual license as MIT and including into
+ * GRUB2 sources
+ */
+
+#include <grub/types.h>
+#define is_signed_type(type) (((type)(-1)) < (type)1)
+#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
+#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
+#define type_min(T) ((T)((T)-type_max(T)-(T)1))
+
+#define __unsigned_add_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a + __b; \
+ *__d < __a; \
+})
+#define __unsigned_sub_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a - __b; \
+ __a < __b; \
+})
+#define __unsigned_mul_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = __a * __b; \
+ __builtin_constant_p(__b) ? \
+ __b > 0 && __a > type_max(typeof(__a)) / __b :\
+ __a > 0 && __b > type_max(typeof(__b)) / __a; \
+})
+
+#define __signed_add_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (grub_uint64_t)__a + (grub_uint64_t)__b; \
+ (((~(__a ^ __b)) & (*__d ^ __a)) \
+ & type_min(typeof(__a))) != 0; \
+})
+
+#define __signed_sub_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (grub_uint64_t)__a - (grub_uint64_t)__b; \
+ ((((__a ^ __b)) & (*__d ^ __a)) \
+ & type_min(typeof(__a))) != 0; \
+})
+
+#define __signed_mul_overflow(a, b, d) ({ \
+ typeof(+(a)) __a = (a); \
+ typeof(+(b)) __b = (b); \
+ typeof(d) __d = (d); \
+ typeof(+(a)) __tmax = type_max(typeof(+(a))); \
+ typeof(+(a)) __tmin = type_min(typeof(+(a))); \
+ (void) (&__a == &__b); \
+ (void) (&__a == __d); \
+ *__d = (grub_uint64_t)__a * (grub_uint64_t)__b; \
+ (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) ||\
+ (__b < (typeof(__b))-1 && \
+ (__a > __tmin/__b || __a < __tmax/__b)) || \
+ (__b == (typeof(__b))-1 && __a == __tmin); \
+})
+
+#define grub_add(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
+ __signed_add_overflow(a, b, d), \
+ __unsigned_add_overflow(a, b, d))
+
+#define grub_sub(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
+ __signed_sub_overflow(a, b, d), \
+ __unsigned_sub_overflow(a, b, d))
+
+#define grub_mul(a, b, d) \
+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
+ __signed_mul_overflow(a, b, d), \
+ __unsigned_mul_overflow(a, b, d))
+
#endif
#endif /* GRUB_SAFEMATH_H */

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,216 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 23 Jul 2020 15:02:48 -0400
Subject: [PATCH] Fix up some types for gcc 4.8 compat safemath.h
The compat macros aren't as forgiving as __builtin_*_overflow().
Signed-off-by: Peter Jones <pjones@redhat.com>
---
grub-core/disk/lvm.c | 22 ++++++++++++----------
grub-core/font/font.c | 4 ++--
grub-core/fs/btrfs.c | 20 +++++++++++++++-----
grub-core/fs/ext2.c | 3 ++-
grub-core/fs/hfsplus.c | 2 +-
grub-core/fs/iso9660.c | 8 ++++----
grub-core/normal/charset.c | 5 +++--
7 files changed, 39 insertions(+), 25 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index ca09d469990..4fbb3eac0ea 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -103,7 +103,7 @@ grub_lvm_detect (grub_disk_t disk,
{
grub_err_t err;
grub_uint64_t mda_offset, mda_size;
- grub_size_t ptr;
+ grub_uint64_t ptr;
char buf[GRUB_LVM_LABEL_SIZE];
char vg_id[GRUB_LVM_ID_STRLEN+1];
char pv_id[GRUB_LVM_ID_STRLEN+1];
@@ -209,9 +209,9 @@ grub_lvm_detect (grub_disk_t disk,
grub_le_to_cpu64 (mdah->size));
}
- if (grub_add ((grub_size_t)metadatabuf,
- (grub_size_t)grub_le_to_cpu64 (rlocn->offset),
- &ptr))
+ grub_uint64_t mdb = (grub_uint64_t)metadatabuf;
+ grub_uint64_t addend = (grub_uint64_t)grub_le_to_cpu64 (rlocn->offset);
+ if (grub_add (mdb, addend, &ptr))
{
error_parsing_metadata:
#ifdef GRUB_UTIL
@@ -222,7 +222,7 @@ error_parsing_metadata:
p = q = (char *)ptr;
- if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
+ if (grub_add (mdb, mda_size, &ptr))
goto error_parsing_metadata;
mda_end = (char *)ptr;
@@ -391,13 +391,15 @@ error_parsing_metadata:
* + sizeof ("lvm/") - 1;
*/
grub_size_t sz0 = vgname_len, sz1 = s;
+ grub_size_t one = 1, two = 2;
+ grub_size_t lvm_str_sz = sizeof ("lvm/") - 1;
- if (grub_mul (sz0, 2, &sz0) ||
- grub_add (sz0, 1, &sz0) ||
- grub_mul (sz1, 2, &sz1) ||
- grub_add (sz1, 1, &sz1) ||
+ if (grub_mul (sz0, two, &sz0) ||
+ grub_add (sz0, one, &sz0) ||
+ grub_mul (sz1, two, &sz1) ||
+ grub_add (sz1, one, &sz1) ||
grub_add (sz0, sz1, &sz0) ||
- grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
+ grub_add (sz0, lvm_str_sz, &sz0))
goto lvs_fail;
lv->fullname = grub_malloc (sz0);
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index a7b955a1a74..b36a099b856 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -361,10 +361,10 @@ static char *
read_section_as_string (struct font_file_section *section)
{
char *str;
- grub_size_t sz;
+ grub_size_t sz = section->length, one = 1;
grub_ssize_t ret;
- if (grub_add (section->length, 1, &sz))
+ if (grub_add (sz, one, &sz))
return NULL;
str = grub_malloc (sz);
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index 1d801f6c9ee..3faf9056c72 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -323,10 +323,15 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
{
void *newdata;
grub_size_t sz;
+ grub_size_t alloced, datasz, two = 2;
- if (grub_mul (desc->allocated, 2, &desc->allocated) ||
- grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
+ alloced = desc->allocated;
+ datasz = sizeof (desc->data[0]);
+
+ if (grub_mul (alloced, two, &alloced) ||
+ grub_mul (alloced, datasz, &sz))
return GRUB_ERR_OUT_OF_RANGE;
+ desc->allocated = alloced;
newdata = grub_realloc (desc->data, sz);
if (!newdata)
@@ -624,12 +629,17 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan)
{
void *tmp;
grub_size_t sz;
+ grub_size_t alloced = data->n_devices_allocated;
+ grub_size_t attached_sz = sizeof(data->devices_attached[0]);
+ grub_size_t attached = data->n_devices_attached;
+ const grub_size_t one = 1, two = 2;
- if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
- grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
- grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
+ if (grub_mul (attached, two, &alloced) ||
+ grub_add (alloced, one, &alloced) ||
+ grub_mul (alloced, attached_sz, &sz))
goto fail;
+ data->n_devices_allocated = alloced;
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
if (!data->devices_attached)
{
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index b4bd019f49a..3d59cf13125 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -719,7 +719,8 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
}
}
- if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
+ sz = grub_le_to_cpu32 (diro->inode.size);
+ if (grub_add (sz, (grub_size_t)1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 8b17ebba296..e06bcbb9ba3 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -478,7 +478,7 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
grub_ssize_t numread;
grub_size_t sz = node->size;
- if (grub_add (sz, 1, &sz))
+ if (grub_add (sz, (grub_size_t)1, &sz))
return NULL;
symlink = grub_malloc (sz);
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
index 6fc9302bce3..a4403e29dee 100644
--- a/grub-core/fs/iso9660.c
+++ b/grub-core/fs/iso9660.c
@@ -536,7 +536,7 @@ add_part (struct iterate_dir_ctx *ctx,
char *new;
if (grub_add (size, len2, &sz) ||
- grub_add (sz, 1, &sz))
+ grub_add (sz, (grub_size_t)1, &sz))
return;
new = grub_realloc (ctx->symlink, sz);
@@ -580,14 +580,14 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
{
off = grub_strlen (ctx->filename);
if (grub_add (csize, off, &sz) ||
- grub_add (sz, 1, &sz))
+ grub_add (sz, (grub_size_t)1, &sz))
return GRUB_ERR_OUT_OF_RANGE;
ctx->filename = grub_realloc (ctx->filename, sz);
}
else
{
off = 0;
- if (grub_add (csize, 1, &sz))
+ if (grub_add (csize, (grub_size_t)1, &sz))
return GRUB_ERR_OUT_OF_RANGE;
ctx->filename = grub_zalloc (sz);
}
@@ -807,7 +807,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
struct grub_fshelp_node *new_node;
grub_size_t sz;
- if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
+ if (grub_mul (node->alloc_dirents, (grub_size_t)2, &node->alloc_dirents) ||
grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
index 4dfcc31078d..f902b13b44e 100644
--- a/grub-core/normal/charset.c
+++ b/grub-core/normal/charset.c
@@ -479,8 +479,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
n = out->combining_inline;
else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
{
- if (grub_add (out->ncomb, 1, &sz) ||
- grub_mul (sz, sizeof (n[0]), &sz))
+ grub_size_t ncomb = out->ncomb, one = 1, nsz = sizeof (n[0]);
+ if (grub_add (ncomb, one, &sz) ||
+ grub_mul (sz, nsz, &sz))
goto fail;
n = grub_realloc (out->combining_ptr, sz);

View File

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

View File

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

View File

@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Wed, 22 Jul 2020 11:31:43 +0100
Subject: [PATCH] linuxefi: fail kernel validation without shim protocol.
If certificates that signed grub are installed into db, grub can be
booted directly. It will then boot any kernel without signature
validation. The booted kernel will think it was booted in secureboot
mode and will implement lockdown, yet it could have been tampered.
This version of the patch skips calling verification, when booted
without secureboot. And is indented with gnu ident.
CVE-2020-15705
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
---
grub-core/loader/arm64/linux.c | 12 ++++++++----
grub-core/loader/efi/chainloader.c | 1 +
grub-core/loader/efi/linux.c | 1 +
grub-core/loader/i386/efi/linux.c | 13 ++++++++-----
4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index e1110749eb9..7a076c13171 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -381,11 +381,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
- if (rc < 0)
+ if (grub_efi_secure_boot ())
{
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
- goto fail;
+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
+ if (rc <= 0)
+ {
+ grub_error (GRUB_ERR_INVALID_COMMAND,
+ N_("%s has invalid signature"), argv[0]);
+ goto fail;
+ }
}
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 8b99cf23e9d..a93edc975cd 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -1079,6 +1079,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
return 0;
}
+ // -1 fall-through to fail
fail:
if (dev)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index e09f824862b..927d89a90d7 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -33,6 +33,7 @@ struct grub_efi_shim_lock
};
typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
+// Returns 1 on success, -1 on error, 0 when not available
int
grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
{
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index ade7ab8f573..361e503cb52 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -206,12 +206,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "grub_linuxefi", "Kernel");
grub_print_error();
- 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;
+ }
}
params = grub_efi_allocate_pages_max (0x3fffffff,

View File

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

View File

@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Tue, 11 Aug 2020 13:16:39 +0200
Subject: [PATCH] blscfg: Always look for BLS snippets in the root device
The blscfg command trying to load the BLS snippets from different devices
is a left over from when these where located in the ESP in the EFI case.
But now that are always located in the /boot directory, the BLS snippets
have to be loaded from the root device just like the other files that are
in the /boot directory (kernel and initrd images).
This only worked for legacy BIOS because the boot and root variables were
set to the same value. But doesn't work when trying to use a common GRUB
config file that could be shared between an EFI and legacy BIOS install.
That kind of configuration is needed for example on hybrid images that are
booted using either EFI or legacy BIOS firmwares.
Resolves: rhbz#1850193
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
grub-core/commands/blscfg.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index c92e1c84543..70ce5c7bf6f 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -874,14 +874,12 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
#ifdef GRUB_MACHINE_EMU
devid = "host";
-#elif defined(GRUB_MACHINE_EFI)
+#else
devid = grub_env_get ("root");
-#else
- devid = grub_env_get ("boot");
#endif
if (!devid)
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
- N_("variable `%s' isn't set"), "boot");
+ N_("variable `%s' isn't set"), "root");
grub_dprintf ("blscfg", "opening %s\n", devid);
dev = grub_device_open (devid);

View File

@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Tue, 11 Aug 2020 13:16:45 +0200
Subject: [PATCH] blscfg: Don't hardcode an env var as fallback for the BLS
options field
If the BLS fragments don't have an options field or if this was set to an
environment variable that was not defined in the grubenv file, the blscfg
module searches for a default_kernelopts variable that is defined in the
grub.cfg file.
But the blscfg module shouldn't hardcode fallbacks variables and instead
this logic should be handled in the GRUB config file itself.
Also, add a comment explaining where the kernelopts variable is supposed
to be defined and what is the process for the user to change its value.
Resolves: rhbz#1850193
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
util/grub.d/10_linux.in | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 58d18504790..48857bb81d3 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -158,7 +158,17 @@ linux_entry ()
populate_header_warn
cat << EOF
-set default_kernelopts="root=${linux_root_device_thisversion} ro ${args}"
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
+# entries populated from BootLoaderSpec files that use this variable work correctly even
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
+#
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
+if [ -z "\${kernelopts}" ]; then
+ set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
+fi
insmod blscfg
blscfg

View File

@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Mon, 24 Aug 2020 14:46:27 +0200
Subject: [PATCH] tftp: roll over block counter to prevent timeouts with data
packets
The block number is a 16-bit counter which only allows to fetch
files no bigger than 65535 * blksize. To avoid this limit, the
counter is rolled over. This behavior isn't defined in RFC 1350
but is handled by many TFTP servers and it's what GRUB was doing
before implicitly due an overflow.
Fixing that bug led to TFTP timeouts, since GRUB wasn't acking
data packets anymore for files with size bigger than the maximum
mentioned above. Restore the old behavior to prevent this issue.
Resolves: rhbz#1871034
Suggested-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
grub-core/net/tftp.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
index 79c16f9b041..b9a4b607a3d 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -183,8 +183,20 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
return GRUB_ERR_NONE;
}
- /* Ack old/retransmitted block. */
- if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1)
+ /*
+ * Ack old/retransmitted block.
+ *
+ * The block number is a 16-bit counter which only allows to fetch
+ * files no bigger than 65535 * blksize. To avoid this limit, the
+ * counter is rolled over. This behavior isn't defined in RFC 1350
+ * but is handled by many TFTP servers and it's what GRUB was doing
+ * before implicitly due an overflow.
+ *
+ * Fixing that bug led to TFTP timeouts, since GRUB wasn't acking
+ * data packets anymore for files with size bigger than the maximum
+ * mentioned above. Restore the old behavior to prevent this issue.
+ */
+ if (grub_be_to_cpu16 (tftph->u.data.block) < ((data->block + 1) & 0xffffu))
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)

View File

@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Thu, 3 Dec 2020 09:13:24 +0100
Subject: [PATCH] at_keyboard: use set 1 when keyboard is in Translate mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When keyboard controller acts in Translate mode (0x40 mask), then use
set 1 since translation is done.
Otherwise use the mode queried from the controller (usually set 2).
Added "atkeyb" debugging messages in at_keyboard module as well.
Resolves: rhbz#1897587
Tested on:
- Asus N53SN (set 1 used)
- Dell Precision (set 1 used)
- HP Elitebook (set 2 used)
- HP G5430 (set 1 used, keyboard in XT mode!)
- Lenovo P71 & Lenovo T460s (set 2 used)
- QEMU/KVM (set 1 used)
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
grub-core/term/at_keyboard.c | 29 ++++++++++++++++++++++++-----
include/grub/at_keyboard.h | 4 ++++
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
index f0a986eb176..69d99b61df5 100644
--- a/grub-core/term/at_keyboard.c
+++ b/grub-core/term/at_keyboard.c
@@ -135,20 +135,28 @@ query_mode (void)
int e;
e = write_mode (0);
- if (!e)
+ if (!e) {
+ grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n");
return 0;
+ }
do {
keyboard_controller_wait_until_ready ();
ret = grub_inb (KEYBOARD_REG_DATA);
} while (ret == GRUB_AT_ACK);
/* QEMU translates the set even in no-translate mode. */
- if (ret == 0x43 || ret == 1)
+ if (ret == 0x43 || ret == 1) {
+ grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret);
return 1;
- if (ret == 0x41 || ret == 2)
+ }
+ if (ret == 0x41 || ret == 2) {
+ grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret);
return 2;
- if (ret == 0x3f || ret == 3)
+ }
+ if (ret == 0x3f || ret == 3) {
+ grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret);
return 3;
+ }
return 0;
}
@@ -165,7 +173,13 @@ set_scancodes (void)
}
#if !USE_SCANCODE_SET
- ps2_state.current_set = 1;
+ if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) {
+ grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set);
+ ps2_state.current_set = 1;
+ } else {
+ grub_dprintf ("atkeyb", "using queried set %d\n", grub_keyboard_orig_set);
+ ps2_state.current_set = grub_keyboard_orig_set;
+ }
return;
#else
@@ -266,6 +280,7 @@ grub_keyboard_controller_init (void)
grub_keyboard_orig_set = 2;
#else
grub_keyboard_controller_orig = grub_keyboard_controller_read ();
+ grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig);
grub_keyboard_orig_set = query_mode ();
#endif
set_scancodes ();
@@ -275,11 +290,15 @@ grub_keyboard_controller_init (void)
static grub_err_t
grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused)))
{
+/* In !USE_SCANCODE_SET mode, we didn't change anything, so nothing to restore */
+#if USE_SCANCODE_SET
if (ps2_state.current_set == 0)
return GRUB_ERR_NONE;
+ grub_dprintf ("atkeyb", "restoring set %d, controller 0x%x\n", grub_keyboard_orig_set, grub_keyboard_controller_orig);
if (grub_keyboard_orig_set)
write_mode (grub_keyboard_orig_set);
grub_keyboard_controller_write (grub_keyboard_controller_orig);
+#endif
return GRUB_ERR_NONE;
}
diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h
index bcb4d9ba78f..9414dc1b996 100644
--- a/include/grub/at_keyboard.h
+++ b/include/grub/at_keyboard.h
@@ -19,6 +19,10 @@
#ifndef GRUB_AT_KEYBOARD_HEADER
#define GRUB_AT_KEYBOARD_HEADER 1
+/*
+ * Refer to https://wiki.osdev.org/%228042%22_PS/2_Controller for details.
+ */
+
/* Used for sending commands to the controller. */
#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02)
#define KEYBOARD_COMMAND_READ 0x20

View File

@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jan Hlavac <jhlavac@redhat.com>
Date: Fri, 20 Nov 2020 23:51:47 +0100
Subject: [PATCH] grub-install: disable support for EFI platforms
For each platform, GRUB is shipped as a kernel image and a set of
modules. These files are then used by the grub-install utility to
install GRUB on a specific device. However, in order to support UEFI
Secure Boot, the resulting EFI binary must be signed by a recognized
private key. For this reason, for EFI platforms, most distributions also
ship prebuilt EFI binaries signed by a distribution-specific private
key. In this case, however, the grub-install utility should not be used
because it would overwrite the signed EFI binary.
The current fix is suboptimal because it preserves all EFI-related code.
A better solution could be to modularize the code and provide a
build-time option.
Resolves: rhbz#1737444
Signed-off-by: Jan Hlavac <jhlavac@redhat.com>
---
util/grub-install.c | 35 ++++++++++++++++-------------------
docs/grub.texi | 7 +++++++
util/grub-install.8 | 4 +++-
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/util/grub-install.c b/util/grub-install.c
index 3bf0e063a86..65bb2f99ef1 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -888,6 +888,22 @@ main (int argc, char *argv[])
platform = grub_install_get_target (grub_install_source_directory);
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ is_efi = 1;
+ grub_util_error (_("this utility cannot be used for EFI platforms"
+ " because it does not support UEFI Secure Boot"));
+ break;
+ default:
+ is_efi = 0;
+ break;
+ }
+
{
char *platname = grub_install_get_platform_name (platform);
fprintf (stderr, _("Installing for %s platform.\n"), platname);
@@ -994,26 +1010,7 @@ main (int argc, char *argv[])
grub_hostfs_init ();
grub_host_init ();
- switch (platform)
- {
- case GRUB_INSTALL_PLATFORM_I386_EFI:
- case GRUB_INSTALL_PLATFORM_X86_64_EFI:
- case GRUB_INSTALL_PLATFORM_ARM_EFI:
- case GRUB_INSTALL_PLATFORM_ARM64_EFI:
- case GRUB_INSTALL_PLATFORM_IA64_EFI:
- is_efi = 1;
- break;
- default:
- is_efi = 0;
- break;
-
- /* pacify warning. */
- case GRUB_INSTALL_PLATFORM_MAX:
- break;
- }
-
/* Find the EFI System Partition. */
-
if (is_efi)
{
grub_fs_t fs;
diff --git a/docs/grub.texi b/docs/grub.texi
index c54bee31679..fa11cc0aff7 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -6185,6 +6185,13 @@ grub2-install @var{install_device}
The device name @var{install_device} is an OS device name or a GRUB
device name.
+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must
+be signed by a recognized private key. For this reason, for EFI
+platforms, most distributions also ship prebuilt GRUB EFI binaries
+signed by a distribution-specific private key. In this case, however,
+@command{grub2-install} should not be used because it would overwrite
+the signed EFI binary.
+
@command{grub2-install} accepts the following options:
@table @option
diff --git a/util/grub-install.8 b/util/grub-install.8
index 76272a39d2e..02371930fa1 100644
--- a/util/grub-install.8
+++ b/util/grub-install.8
@@ -1,4 +1,4 @@
-.TH GRUB-INSTALL 1 "Wed Feb 26 2014"
+.TH GRUB-INSTALL 1 "Fri Nov 20 2020"
.SH NAME
\fBgrub-install\fR \(em Install GRUB on a device.
@@ -31,6 +31,8 @@
.SH DESCRIPTION
\fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector.
+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must be signed by a recognized private key. For this reason, for EFI platforms, most distributions also ship prebuilt GRUB EFI binaries signed by a distribution-specific private key. In this case, however, the \fBgrub-install\fR utility should not be used because it would overwrite the signed EFI binary.
+
.SH OPTIONS
.TP
\fB--modules\fR=\fIMODULES\fR\!

View File

@ -0,0 +1,112 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Sat, 23 Nov 2019 14:57:41 +0100
Subject: [PATCH] New --with-debug-timestamps configure flag to prepend debug
traces with absolute and relative timestamp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
configure.ac | 18 ++++++++++++++++++
grub-core/kern/misc.c | 20 ++++++++++++++++++++
config.h.in | 1 +
3 files changed, 39 insertions(+)
diff --git a/configure.ac b/configure.ac
index 9323c125469..0059b938a3a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1514,6 +1514,17 @@ else
fi
AC_SUBST([BOOT_TIME_STATS])
+AC_ARG_WITH([debug-timestamps],
+ AS_HELP_STRING([--with-debug-timestamps],
+ [prepend debug traces with absolute and relative timestamps]))
+
+if test x$with_debug_timestamps = xyes; then
+ DEBUG_WITH_TIMESTAMPS=1
+else
+ DEBUG_WITH_TIMESTAMPS=0
+fi
+AC_SUBST([DEBUG_WITH_TIMESTAMPS])
+
AC_ARG_ENABLE([grub-emu-sdl],
[AS_HELP_STRING([--enable-grub-emu-sdl],
[build and install the `grub-emu' debugging utility with SDL support (default=guessed)])])
@@ -2092,6 +2103,7 @@ AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1])
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1])
AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1])
+AM_CONDITIONAL([COND_DEBUG_WITH_TIMESTAMPS], [test x$DEBUG_WITH_TIMESTAMPS = x1])
AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes])
@@ -2187,6 +2199,12 @@ else
echo With boot time statistics: No
fi
+if [ x"$with_debug_timestamps" = xyes ]; then
+echo Debug traces with timestamps: Yes
+else
+echo Debug traces with timestamps: No
+fi
+
if [ x"$efiemu_excuse" = x ]; then
echo efiemu runtime: Yes
else
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index c034f49f97c..11f2974fce5 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -25,6 +25,9 @@
#include <grub/env.h>
#include <grub/i18n.h>
#include <grub/backtrace.h>
+#if DEBUG_WITH_TIMESTAMPS
+#include <grub/time.h>
+#endif
union printf_arg
{
@@ -179,9 +182,26 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
const char *fmt, ...)
{
va_list args;
+#if DEBUG_WITH_TIMESTAMPS
+ static long unsigned int last_time = 0;
+ static int last_had_cr = 1;
+#endif
if (grub_debug_enabled (condition))
{
+#if DEBUG_WITH_TIMESTAMPS
+ /* Don't print timestamp if last printed message isn't terminated yet */
+ if (last_had_cr) {
+ long unsigned int tmabs = (long unsigned int) grub_get_time_ms();
+ long unsigned int tmrel = tmabs - last_time;
+ last_time = tmabs;
+ grub_printf ("%3lu.%03lus +%2lu.%03lus ", tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000);
+ }
+ if (fmt[grub_strlen(fmt)-1] == '\n')
+ last_had_cr = 1;
+ else
+ last_had_cr = 0;
+#endif
grub_printf ("%s:%d: ", file, line);
va_start (args, fmt);
grub_vprintf (fmt, args);
diff --git a/config.h.in b/config.h.in
index 9e8f9911b18..d15480b4163 100644
--- a/config.h.in
+++ b/config.h.in
@@ -12,6 +12,7 @@
/* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@
#define BOOT_TIME_STATS @BOOT_TIME_STATS@
+#define DEBUG_WITH_TIMESTAMPS @DEBUG_WITH_TIMESTAMPS@
/* We don't need those. */
#define MINILZO_CFG_SKIP_LZO_PTR 1

View File

@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Sat, 23 Nov 2019 15:22:16 +0100
Subject: [PATCH] Added debug statements to grub_disk_open() and
grub_disk_close() on success
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
grub-core/kern/disk.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c
index 789f8c05233..7f58c561472 100644
--- a/grub-core/kern/disk.c
+++ b/grub-core/kern/disk.c
@@ -285,6 +285,8 @@ grub_disk_open (const char *name)
return 0;
}
+ grub_dprintf ("disk", "Opening `%s' succeeded.\n", name);
+
return disk;
}
@@ -292,7 +294,7 @@ void
grub_disk_close (grub_disk_t disk)
{
grub_partition_t part;
- grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
+ grub_dprintf ("disk", "Closing `%s'...\n", disk->name);
if (disk->dev && disk->dev->close)
(disk->dev->close) (disk);
@@ -306,8 +308,10 @@ grub_disk_close (grub_disk_t disk)
grub_free (disk->partition);
disk->partition = part;
}
+ grub_dprintf ("disk", "Closing `%s' succeeded.\n", disk->name);
grub_free ((void *) disk->name);
grub_free (disk);
+
}
/* Small read (less than cache size and not pass across cache unit boundaries).

View File

@ -0,0 +1,51 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Mon, 25 Nov 2019 09:29:53 +0100
Subject: [PATCH] Introduce function grub_debug_is_enabled(void) returning 1 if
'debug' is in the environment and not empty
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
grub-core/kern/misc.c | 13 +++++++++++++
include/grub/misc.h | 1 +
2 files changed, 14 insertions(+)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index 11f2974fce5..97378c48b22 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -162,6 +162,19 @@ int grub_err_printf (const char *fmt, ...)
__attribute__ ((alias("grub_printf")));
#endif
+/* Return 1 if 'debug' is set and not empty */
+int
+grub_debug_is_enabled (void)
+{
+ const char *debug;
+
+ debug = grub_env_get ("debug");
+ if (!debug || debug[0] == '\0')
+ return 0;
+
+ return 1;
+}
+
int
grub_debug_enabled (const char * condition)
{
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 1258ec6bbf3..6ca03c4d692 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -367,6 +367,7 @@ grub_puts (const char *s)
}
int EXPORT_FUNC(grub_puts_) (const char *s);
+int EXPORT_FUNC(grub_debug_is_enabled) (void);
int EXPORT_FUNC(grub_debug_enabled) (const char *condition);
void EXPORT_FUNC(grub_real_dprintf) (const char *file,
const int line,

View File

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Sat, 23 Nov 2019 16:23:54 +0100
Subject: [PATCH] Don't clear screen when debugging is enabled
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
grub-core/normal/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 04ae9ed02f6..59fd54eb0f1 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -204,7 +204,8 @@ void
grub_normal_init_page (struct grub_term_output *term,
int y __attribute__((__unused__)))
{
- grub_term_cls (term);
+ if (! grub_debug_is_enabled ())
+ grub_term_cls (term);
#if 0
grub_ssize_t msg_len;

View File

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Fri, 29 Nov 2019 11:02:00 +0100
Subject: [PATCH] grub_file_* instrumentation (new 'file' debug tag)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
---
grub-core/kern/file.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
index 668f8930b19..c2d9a550007 100644
--- a/grub-core/kern/file.c
+++ b/grub-core/kern/file.c
@@ -67,6 +67,8 @@ grub_file_open (const char *name)
const char *file_name;
grub_file_filter_id_t filter;
+ grub_dprintf ("file", "Opening `%s' ...\n", name);
+
device_name = grub_file_get_device_name (name);
if (grub_errno)
goto fail;
@@ -127,6 +129,8 @@ grub_file_open (const char *name)
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
+ grub_dprintf ("file", "Opening `%s' succeeded.\n", name);
+
return file;
fail:
@@ -140,6 +144,8 @@ grub_file_open (const char *name)
grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
sizeof (grub_file_filters_enabled));
+ grub_dprintf ("file", "Opening `%s' failed.\n", name);
+
return 0;
}
@@ -171,6 +177,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
if (len == 0)
return 0;
+
read_hook = file->read_hook;
read_hook_data = file->read_hook_data;
if (!file->read_hook)
@@ -191,11 +198,18 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
grub_err_t
grub_file_close (grub_file_t file)
{
+ grub_dprintf ("file", "Closing `%s' ...\n", file->name);
if (file->fs->close)
(file->fs->close) (file);
if (file->device)
grub_device_close (file->device);
+
+ if (grub_errno == GRUB_ERR_NONE)
+ grub_dprintf ("file", "Closing `%s' succeeded.\n", file->name);
+ else
+ grub_dprintf ("file", "Closing `%s' failed with %d.\n", file->name, grub_errno);
+
grub_free (file->name);
grub_free (file);
return grub_errno;

View File

@ -0,0 +1,136 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Diego Domingos <diegodo@br.ibm.com>
Date: Mon, 14 Dec 2020 17:42:45 +0100
Subject: [PATCH] ieee1275: Avoiding many unecessary open/close
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
---
grub-core/disk/ieee1275/ofdisk.c | 64 ++++++++++++++++++++++------------------
1 file changed, 35 insertions(+), 29 deletions(-)
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index d887d4b6eee..f3a6ecd797f 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -44,7 +44,7 @@ struct ofdisk_hash_ent
};
static grub_err_t
-grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
+grub_ofdisk_get_block_size (grub_uint32_t *block_size,
struct ofdisk_hash_ent *op);
#define OFDISK_HASH_SZ 8
@@ -461,6 +461,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
grub_ssize_t actual;
grub_uint32_t block_size = 0;
grub_err_t err;
+ struct ofdisk_hash_ent *op;
if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
@@ -471,6 +472,35 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
grub_dprintf ("disk", "Opening `%s'.\n", devpath);
+ op = ofdisk_hash_find (devpath);
+ if (!op)
+ op = ofdisk_hash_add (devpath, NULL);
+ if (!op)
+ {
+ grub_free (devpath);
+ return grub_errno;
+ }
+
+ /* Check if the call to open is the same to the last disk already opened */
+ if (last_devpath && !grub_strcmp(op->open_path,last_devpath))
+ {
+ goto finish;
+ }
+
+ /* If not, we need to close the previous disk and open the new one */
+ else {
+ if (last_ihandle){
+ grub_ieee1275_close (last_ihandle);
+ }
+ last_ihandle = 0;
+ last_devpath = NULL;
+
+ grub_ieee1275_open (op->open_path, &last_ihandle);
+ if (! last_ihandle)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+ last_devpath = op->open_path;
+ }
+
if (grub_ieee1275_finddevice (devpath, &dev))
{
grub_free (devpath);
@@ -491,25 +521,18 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
}
+
+ finish:
/* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
{
- struct ofdisk_hash_ent *op;
- op = ofdisk_hash_find (devpath);
- if (!op)
- op = ofdisk_hash_add (devpath, NULL);
- if (!op)
- {
- grub_free (devpath);
- return grub_errno;
- }
disk->id = (unsigned long) op;
disk->data = op->open_path;
- err = grub_ofdisk_get_block_size (devpath, &block_size, op);
+ err = grub_ofdisk_get_block_size (&block_size, op);
if (err)
{
grub_free (devpath);
@@ -532,13 +555,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
static void
grub_ofdisk_close (grub_disk_t disk)
{
- if (disk->data == last_devpath)
- {
- if (last_ihandle)
- grub_ieee1275_close (last_ihandle);
- last_ihandle = 0;
- last_devpath = NULL;
- }
disk->data = 0;
}
@@ -685,7 +701,7 @@ grub_ofdisk_init (void)
}
static grub_err_t
-grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
+grub_ofdisk_get_block_size (grub_uint32_t *block_size,
struct ofdisk_hash_ent *op)
{
struct size_args_ieee1275
@@ -698,16 +714,6 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
grub_ieee1275_cell_t size2;
} args_ieee1275;
- if (last_ihandle)
- grub_ieee1275_close (last_ihandle);
-
- last_ihandle = 0;
- last_devpath = NULL;
-
- grub_ieee1275_open (device, &last_ihandle);
- if (! last_ihandle)
- return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-
*block_size = 0;
if (op->block_size_fails >= 2)

View File

@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Diego Domingos <diegodo@br.ibm.com>
Date: Mon, 14 Dec 2020 17:45:28 +0100
Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for
ofpathname
grub-ofpathname doesn't work with fibre channel because there is no
function currently implemented for it.
This patch enables it by prividing a function that looks for the port
name, building the entire path for OF devices.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
---
grub-core/osdep/linux/ofpath.c | 49 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index a6153d35954..0f5d54e9f2d 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
return ret;
}
+
+static void
+of_fc_port_name(const char *path, const char *subpath, char *port_name)
+{
+ char *bname, *basepath, *p;
+ int fd;
+
+ bname = xmalloc(sizeof(char)*150);
+ basepath = xmalloc(strlen(path));
+
+ /* Generate the path to get port name information from the drive */
+ strncpy(basepath,path,subpath-path);
+ basepath[subpath-path-1] = '\0';
+ p = get_basename(basepath);
+ snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p);
+
+ /* Read the information from the port name */
+ fd = open (bname, O_RDONLY);
+ if (fd < 0)
+ grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno));
+
+ if (read(fd,port_name,sizeof(char)*19) < 0)
+ grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
+
+ sscanf(port_name,"0x%s",port_name);
+
+ close(fd);
+
+ free(bname);
+ free(basepath);
+}
+
#ifdef __sparc__
static char *
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
@@ -577,6 +609,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
digit_string = trailing_digits (device);
if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0)
{
+ if(strstr(of_path,"vfc-client"))
+ {
+ char * port_name = xmalloc(sizeof(char)*17);
+ of_fc_port_name(sysfs_path, p, port_name);
+
+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
+ free(port_name);
+ }
+ else
+ {
unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun;
if (*digit_string == '\0')
{
@@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
snprintf(disk, sizeof (disk),
"/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1));
}
+ }
+ } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){
+ char * port_name = xmalloc(sizeof(char)*17);
+ of_fc_port_name(sysfs_path, p, port_name);
+
+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
+ free(port_name);
}
else
{

View File

@ -0,0 +1,106 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Diego Domingos <diegodo@br.ibm.com>
Date: Mon, 14 Dec 2020 17:47:16 +0100
Subject: [PATCH] ieee1275/powerpc: enables device mapper discovery
this patch enables the device mapper discovery on ofpath.c. Currently,
when we are dealing with a device like /dev/dm-* the ofpath returns null
since there is no function implemented to handle this case.
This patch implements a function that will look into /sys/block/dm-*
devices and search recursively inside slaves directory to find the root
disk.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
---
grub-core/osdep/linux/ofpath.c | 64 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 0f5d54e9f2d..cc849d9c94c 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -37,6 +37,7 @@
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
+#include <dirent.h>
#ifdef __sparc__
typedef enum
@@ -755,13 +756,74 @@ strip_trailing_digits (const char *p)
return new;
}
+static char *
+get_slave_from_dm(const char * device){
+ char *curr_device, *tmp;
+ char *directory;
+ char *ret = NULL;
+
+ directory = grub_strdup (device);
+ tmp = get_basename(directory);
+ curr_device = grub_strdup (tmp);
+ *tmp = '\0';
+
+ /* Recursively check for slaves devices so we can find the root device */
+ while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-')){
+ DIR *dp;
+ struct dirent *ep;
+ char* device_path;
+
+ device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device);
+ dp = opendir(device_path);
+ free(device_path);
+
+ if (dp != NULL)
+ {
+ ep = readdir (dp);
+ while (ep != NULL){
+
+ /* avoid some system directories */
+ if (!strcmp(ep->d_name,"."))
+ goto next_dir;
+ if (!strcmp(ep->d_name,".."))
+ goto next_dir;
+
+ free (curr_device);
+ free (ret);
+ curr_device = grub_strdup (ep->d_name);
+ ret = grub_xasprintf ("%s%s", directory, curr_device);
+ break;
+
+ next_dir:
+ ep = readdir (dp);
+ continue;
+ }
+ closedir (dp);
+ }
+ else
+ grub_util_warn (_("cannot open directory `%s'"), device_path);
+ }
+
+ free (directory);
+ free (curr_device);
+
+ return ret;
+}
+
char *
grub_util_devname_to_ofpath (const char *sys_devname)
{
- char *name_buf, *device, *devnode, *devicenode, *ofpath;
+ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname;
name_buf = xrealpath (sys_devname);
+ realname = get_slave_from_dm (name_buf);
+ if (realname)
+ {
+ free (name_buf);
+ name_buf = realname;
+ }
+
device = get_basename (name_buf);
devnode = strip_trailing_digits (name_buf);
devicenode = strip_trailing_digits (device);

View File

@ -0,0 +1,239 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
Date: Fri, 18 Dec 2020 15:39:26 +0100
Subject: [PATCH] Add 'at_keyboard_fallback_set' var to force the set manually
This seems required with HP DL380p Gen 8 systems.
Indeed, with this system, we can see the following sequence:
1. controller is queried to get current configuration (returns 0x30 which is quite standard)
2. controller is queried to get the current keyboard set in used, using code 0xf0 (first part)
3. controller answers with 0xfa which means "ACK" (== ok)
4. then we send "0" to tell "we want to know which set your are supporting"
5. controller answers with 0xfa ("ACK")
6. controller should then give us 1, 2, 3 or 0x43, 0x41, 0x3f, but here it gives us 0xfe which means "NACK"
Since there seems no way to determine the current set, and in fact the
controller expects set2 to be used, we need to rely on an environment
variable.
Everything has been tested on this system: using 0xFE (resend command),
making sure we wait for ACK in the 2 steps "write_mode", etc.
Below is litterature I used to come up with "there is no other
solution":
- https://wiki.osdev.org/%228042%22_PS/2_Controller
- http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm
- http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/PC%20Keyboard.pdf
---
grub-core/term/at_keyboard.c | 121 ++++++++++++++++++++++++++++++++++---------
1 file changed, 96 insertions(+), 25 deletions(-)
diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
index 69d99b61df5..c805cccbdde 100644
--- a/grub-core/term/at_keyboard.c
+++ b/grub-core/term/at_keyboard.c
@@ -31,6 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_uint8_t grub_keyboard_controller_orig;
static grub_uint8_t grub_keyboard_orig_set;
struct grub_ps2_state ps2_state;
+static int fallback_set;
static int ping_sent;
@@ -76,6 +77,8 @@ at_command (grub_uint8_t data)
break;
return 0;
}
+ if (i == GRUB_AT_TRIES)
+ grub_dprintf ("atkeyb", "at_command() timed out! (stopped after %d tries)\n", i);
return (i != GRUB_AT_TRIES);
}
@@ -105,6 +108,21 @@ grub_keyboard_controller_read (void)
#endif
+static int
+resend_last_result (void)
+{
+ grub_uint8_t ret;
+ keyboard_controller_wait_until_ready ();
+ grub_dprintf ("atkeyb", "resend_last_result: sending 0xfe\n");
+ grub_outb (0xfe, KEYBOARD_REG_DATA);
+ ret = wait_ack ();
+ grub_dprintf ("atkeyb", "resend_last_result: wait_ack() returned 0x%x\n", ret);
+ keyboard_controller_wait_until_ready ();
+ ret = grub_inb (KEYBOARD_REG_DATA);
+ grub_dprintf ("atkeyb", "resend_last_result: read 0x%x from controller\n", ret);
+ return ret;
+}
+
static int
write_mode (int mode)
{
@@ -113,11 +131,14 @@ write_mode (int mode)
{
grub_uint8_t ack;
keyboard_controller_wait_until_ready ();
+ grub_dprintf ("atkeyb", "write_mode: sending 0xf0\n");
grub_outb (0xf0, KEYBOARD_REG_DATA);
keyboard_controller_wait_until_ready ();
+ grub_dprintf ("atkeyb", "write_mode: sending mode %d\n", mode);
grub_outb (mode, KEYBOARD_REG_DATA);
keyboard_controller_wait_until_ready ();
ack = wait_ack ();
+ grub_dprintf ("atkeyb", "write_mode: wait_ack() returned 0x%x\n", ack);
if (ack == GRUB_AT_NACK)
continue;
if (ack == GRUB_AT_ACK)
@@ -125,6 +146,9 @@ write_mode (int mode)
return 0;
}
+ if (i == GRUB_AT_TRIES)
+ grub_dprintf ("atkeyb", "write_mode() timed out! (stopped after %d tries)\n", i);
+
return (i != GRUB_AT_TRIES);
}
@@ -132,31 +156,66 @@ static int
query_mode (void)
{
grub_uint8_t ret;
+ grub_uint64_t endtime;
+ unsigned i;
int e;
+ char *envvar;
- e = write_mode (0);
- if (!e) {
- grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n");
- return 0;
- }
+ for (i = 0; i < GRUB_AT_TRIES; i++) {
+ grub_dprintf ("atkeyb", "query_mode: sending command to controller\n");
+ e = write_mode (0);
+ if (!e) {
+ grub_dprintf ("atkeyb", "query_mode: write_mode(0) failed\n");
+ return 0;
+ }
- do {
- keyboard_controller_wait_until_ready ();
- ret = grub_inb (KEYBOARD_REG_DATA);
- } while (ret == GRUB_AT_ACK);
- /* QEMU translates the set even in no-translate mode. */
- if (ret == 0x43 || ret == 1) {
- grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret);
- return 1;
- }
- if (ret == 0x41 || ret == 2) {
- grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret);
- return 2;
+ endtime = grub_get_time_ms () + 20;
+ do {
+ keyboard_controller_wait_until_ready ();
+ ret = grub_inb (KEYBOARD_REG_DATA);
+ grub_dprintf ("atkeyb", "query_mode/loop: read 0x%x from controller\n", ret);
+ } while ((ret == GRUB_AT_ACK || ret == GRUB_AT_NACK) && grub_get_time_ms () < endtime);
+ if (ret == 0xfe) {
+ grub_dprintf ("atkeyb", "query_mode: asking controller to resend last result\n");
+ ret = resend_last_result();
+ grub_dprintf ("atkeyb", "query_mode: read 0x%x from controller\n", ret);
+ }
+ /* QEMU translates the set even in no-translate mode. */
+ if (ret == 0x43 || ret == 1) {
+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 1\n", ret);
+ return 1;
+ }
+ if (ret == 0x41 || ret == 2) {
+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 2\n", ret);
+ return 2;
+ }
+ if (ret == 0x3f || ret == 3) {
+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 3\n", ret);
+ return 3;
+ }
+ grub_dprintf ("atkeyb", "query_mode: controller returned unexpected value 0x%x, retrying\n", ret);
}
- if (ret == 0x3f || ret == 3) {
- grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret);
- return 3;
+
+ /*
+ * Falling here means we tried querying and the controller returned something
+ * we don't understand, try to use 'at_keyboard_fallback_set' if it exists,
+ * otherwise return 0.
+ */
+ envvar = grub_env_get ("at_keyboard_fallback_set");
+ if (envvar) {
+ fallback_set = grub_strtoul (envvar, 0, 10);
+ if ((grub_errno) || (fallback_set < 1) || (fallback_set > 3)) {
+ grub_dprintf ("atkeyb", "WARNING: ignoring unexpected value '%s' for '%s' variable\n",
+ envvar, "at_keyboard_fallback_set");
+ fallback_set = 0;
+ } else {
+ grub_dprintf ("atkeyb", "query_mode: '%s' specified in environment, returning %d\n",
+ "at_keyboard_fallback_set", fallback_set);
+ }
+ return fallback_set;
}
+ grub_dprintf ("atkeyb", "WARNING: no '%s' specified in environment, returning 0\n",
+ "at_keyboard_fallback_set");
return 0;
}
@@ -165,14 +224,25 @@ set_scancodes (void)
{
/* You must have visited computer museum. Keyboard without scancode set
knowledge. Assume XT. */
- if (!grub_keyboard_orig_set)
- {
- grub_dprintf ("atkeyb", "No sets support assumed\n");
- ps2_state.current_set = 1;
+ if (!grub_keyboard_orig_set) {
+ if (fallback_set) {
+ grub_dprintf ("atkeyb", "No sets support assumed but set forced to %d\n", fallback_set);
+ ps2_state.current_set = fallback_set;
return;
}
+ grub_dprintf ("atkeyb", "No sets support assumed, forcing to set 1\n");
+ ps2_state.current_set = 1;
+ return;
+ }
#if !USE_SCANCODE_SET
+ if (fallback_set) {
+ grub_dprintf ("atkeyb", "queried set is %d but set forced to %d\n",
+ grub_keyboard_orig_set, fallback_set);
+ ps2_state.current_set = fallback_set;
+ return;
+ }
+
if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) {
grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set);
ps2_state.current_set = 1;
@@ -261,6 +331,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
static void
grub_keyboard_controller_init (void)
{
+ grub_dprintf ("atkeyb", "initializing the controller\n");
ps2_state.at_keyboard_status = 0;
/* Drain input buffer. */
while (1)
@@ -282,6 +353,7 @@ grub_keyboard_controller_init (void)
grub_keyboard_controller_orig = grub_keyboard_controller_read ();
grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig);
grub_keyboard_orig_set = query_mode ();
+ grub_dprintf ("atkeyb", "grub_keyboard_orig_set = %d\n", grub_keyboard_orig_set);
#endif
set_scancodes ();
keyboard_controller_led (ps2_state.led_status);
@@ -329,7 +401,6 @@ grub_at_restore_hw (void)
return GRUB_ERR_NONE;
}
-
static struct grub_term_input grub_at_keyboard_term =
{
.name = "at_keyboard",

View File

@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Mon, 29 Oct 2018 13:25:25 +0100
Subject: [PATCH] bufio: Use grub_size_t instead of plain int for size
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
(cherry picked from commit f3f8347569383e7f483f37ca70d41eb1af9f990f)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/io/bufio.c | 6 +++---
include/grub/bufio.h | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c
index 6118bade50d..2781afe0515 100644
--- a/grub-core/io/bufio.c
+++ b/grub-core/io/bufio.c
@@ -43,7 +43,7 @@ typedef struct grub_bufio *grub_bufio_t;
static struct grub_fs grub_bufio_fs;
grub_file_t
-grub_bufio_open (grub_file_t io, int size)
+grub_bufio_open (grub_file_t io, grub_size_t size)
{
grub_file_t file;
grub_bufio_t bufio = 0;
@@ -57,7 +57,7 @@ grub_bufio_open (grub_file_t io, int size)
else if (size > GRUB_BUFIO_MAX_SIZE)
size = GRUB_BUFIO_MAX_SIZE;
- if ((size < 0) || ((unsigned) size > io->size))
+ if (size > io->size)
size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
io->size);
@@ -88,7 +88,7 @@ grub_bufio_open (grub_file_t io, int size)
}
grub_file_t
-grub_buffile_open (const char *name, int size)
+grub_buffile_open (const char *name, grub_size_t size)
{
grub_file_t io, file;
diff --git a/include/grub/bufio.h b/include/grub/bufio.h
index acdd0c882c6..77eb8ee5672 100644
--- a/include/grub/bufio.h
+++ b/include/grub/bufio.h
@@ -22,7 +22,7 @@
#include <grub/file.h>
-grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, int size);
-grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, int size);
+grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, grub_size_t size);
+grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, grub_size_t size);
#endif /* ! GRUB_BUFIO_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,520 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Tue, 7 Feb 2017 02:10:14 +0100
Subject: [PATCH] verifiers: Add possibility to verify kernel and modules
command lines
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
(backported from 4d4a8c96e3593d76fe7b025665ccdecc70a53c1f)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/verifiers.c | 14 ++++++++++++++
grub-core/lib/cmdline.c | 7 ++++---
grub-core/loader/arm/linux.c | 8 ++++++--
grub-core/loader/arm64/linux.c | 10 +++++++---
grub-core/loader/i386/bsd.c | 6 ++++++
grub-core/loader/i386/linux.c | 16 +++++++++++-----
grub-core/loader/i386/multiboot_mbi.c | 16 ++++++++++------
grub-core/loader/i386/pc/linux.c | 13 ++++++++-----
grub-core/loader/i386/pc/plan9.c | 11 +++++++++++
grub-core/loader/i386/xen.c | 7 +++++++
grub-core/loader/ia64/efi/linux.c | 7 +++++++
grub-core/loader/mips/linux.c | 8 ++++++++
grub-core/loader/multiboot_mbi2.c | 8 +++-----
grub-core/loader/powerpc/ieee1275/linux.c | 5 +++--
grub-core/loader/sparc64/ieee1275/linux.c | 5 +++--
grub-core/loader/xnu.c | 9 +++++++++
include/grub/lib/cmdline.h | 5 +++--
include/grub/verify.h | 11 +++++++++++
18 files changed, 131 insertions(+), 35 deletions(-)
diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c
index fde88318d4c..59ea418a2d9 100644
--- a/grub-core/commands/verifiers.c
+++ b/grub-core/commands/verifiers.c
@@ -186,6 +186,20 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
return NULL;
}
+grub_err_t
+grub_verify_string (char *str, enum grub_verify_string_type type)
+{
+ struct grub_file_verifier *ver;
+ FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
+ {
+ grub_err_t err;
+ err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE;
+ if (err)
+ return err;
+ }
+ return GRUB_ERR_NONE;
+}
+
GRUB_MOD_INIT(verifiers)
{
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
index d5c12957cad..463c3c65c79 100644
--- a/grub-core/lib/cmdline.c
+++ b/grub-core/lib/cmdline.c
@@ -75,8 +75,9 @@ unsigned int grub_loader_cmdline_size (int argc, char *argv[])
return size;
}
-int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
- grub_size_t size)
+grub_err_t
+grub_create_loader_cmdline (int argc, char *argv[], char *buf,
+ grub_size_t size, enum grub_verify_string_type type)
{
int i, space;
unsigned int arg_size;
@@ -130,5 +131,5 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
"grub_kernel_cmdline", orig);
grub_print_error();
- return i;
+ return grub_verify_string (orig, type);
}
diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index ea29d7a724a..beceda52030 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -28,6 +28,7 @@
#include <grub/cpu/linux.h>
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -383,8 +384,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_args + sizeof (LINUX_IMAGE) - 1, size);
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_args + sizeof (LINUX_IMAGE) - 1, size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
return GRUB_ERR_NONE;
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 7a076c13171..48ea66596ad 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -33,6 +33,7 @@
#include <grub/efi/pe32.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -403,9 +404,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_args + sizeof (LINUX_IMAGE) - 1,
- cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_args + sizeof (LINUX_IMAGE) - 1,
+ cmdline_size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
if (grub_errno == GRUB_ERR_NONE)
{
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index 8306b415abd..45a71509956 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -36,6 +36,7 @@
#include <grub/bsdlabel.h>
#include <grub/crypto.h>
#include <grub/safemath.h>
+#include <grub/verify.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/int.h>
#endif
@@ -418,6 +419,8 @@ grub_freebsd_add_meta_module (const char *filename, const char *type,
grub_addr_t addr, grub_uint32_t size)
{
const char *name;
+ grub_err_t err;
+
name = grub_strrchr (filename, '/');
if (name)
name++;
@@ -471,6 +474,9 @@ grub_freebsd_add_meta_module (const char *filename, const char *type,
*(p++) = ' ';
}
*p = 0;
+ err = grub_verify_string (cmdline, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ return err;
}
}
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index aa2cbc4e7eb..ef8fcb9e1b6 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -1039,11 +1039,17 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (!linux_cmdline)
goto fail;
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- linux_cmdline
- + sizeof (LINUX_IMAGE) - 1,
- maximal_cmdline_size
- - (sizeof (LINUX_IMAGE) - 1));
+ {
+ grub_err_t err;
+ err = grub_create_loader_cmdline (argc, argv,
+ linux_cmdline
+ + sizeof (LINUX_IMAGE) - 1,
+ maximal_cmdline_size
+ - (sizeof (LINUX_IMAGE) - 1),
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
+ }
len = prot_file_size;
grub_memcpy (prot_mode_mem, kernel + kernel_offset, len);
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index 9d3466d6ace..525446b5687 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -676,10 +676,8 @@ grub_multiboot_init_mbi (int argc, char *argv[])
return grub_errno;
cmdline_size = len;
- grub_create_loader_cmdline (argc, argv, cmdline,
- cmdline_size);
-
- return GRUB_ERR_NONE;
+ return grub_create_loader_cmdline (argc, argv, cmdline,
+ cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE);
}
grub_err_t
@@ -688,6 +686,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
{
struct module *newmod;
grub_size_t len = 0;
+ grub_err_t err;
newmod = grub_malloc (sizeof (*newmod));
if (!newmod)
@@ -707,8 +706,13 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, 4);
- grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size);
+ err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
+ newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ {
+ grub_free (newmod);
+ return grub_errno;
+ }
if (modules_last)
modules_last->next = newmod;
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index b5c28c6580e..f631225f59b 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -348,11 +348,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Create kernel command line. */
grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv,
- (char *)grub_linux_real_chunk
- + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
- maximal_cmdline_size
- - (sizeof (LINUX_IMAGE) - 1));
+ err = grub_create_loader_cmdline (argc, argv,
+ (char *)grub_linux_real_chunk
+ + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
+ maximal_cmdline_size
+ - (sizeof (LINUX_IMAGE) - 1),
+ GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
if (grub_linux_is_bzimage)
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c
index 0351090daf8..37550155df7 100644
--- a/grub-core/loader/i386/pc/plan9.c
+++ b/grub-core/loader/i386/pc/plan9.c
@@ -33,6 +33,7 @@
#include <grub/mm.h>
#include <grub/cpu/relocator.h>
#include <grub/extcmd.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -505,6 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
configptr = grub_stpcpy (configptr, "bootfile=");
configptr = grub_stpcpy (configptr, bootpath);
*configptr++ = '\n';
+ char *cmdline = configptr;
{
int i;
for (i = 1; i < argc; i++)
@@ -513,6 +515,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[])
*configptr++ = '\n';
}
}
+
+ {
+ grub_err_t err;
+ *configptr = '\0';
+ err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
+ }
+
configptr = grub_stpcpy (configptr, fill_ctx.pmap);
{
diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index 82350d3a178..07a4837c532 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/safemath.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -649,6 +650,9 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
grub_create_loader_cmdline (argc - 1, argv + 1,
(char *) xen_state.next_start.cmd_line,
sizeof (xen_state.next_start.cmd_line) - 1);
+ err = grub_verify_string (xen_state.next_start.cmd_line, GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ return err;
file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (!file)
@@ -916,6 +920,9 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
grub_create_loader_cmdline (argc - 1, argv + 1,
get_virtual_current_address (ch), cmdline_len);
+ err = grub_verify_string (get_virtual_current_address (ch), GRUB_VERIFY_MODULE_CMDLINE);
+ if (err)
+ goto fail;
xen_state.module_info_page[xen_state.n_modules].cmdline =
xen_state.max_addr - xen_state.modules_target_start;
diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c
index 750330d4572..e325fe0ee83 100644
--- a/grub-core/loader/ia64/efi/linux.c
+++ b/grub-core/loader/ia64/efi/linux.c
@@ -33,6 +33,7 @@
#include <grub/i18n.h>
#include <grub/env.h>
#include <grub/linux.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -543,6 +544,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
p = grub_stpcpy (p, argv[i]);
}
cmdline[10] = '=';
+
+ *p = '\0';
+
+ err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ goto fail;
boot_param->command_line = (grub_uint64_t) cmdline;
boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table;
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
index 10358854458..20135ce253d 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -327,6 +327,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
linux_argv++;
linux_args += ALIGN_UP (sizeof ("a0"), 4);
+ char *params = linux_args;
+
#ifdef GRUB_MACHINE_MIPS_LOONGSON
{
unsigned mtype = grub_arch_machine;
@@ -352,6 +354,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
}
+ *linux_args = '\0';
+
+ err = grub_verify_string (params, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
/* Reserve space for rd arguments. */
rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 3cfb47650a0..f64a857e394 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -1077,10 +1077,8 @@ grub_multiboot2_init_mbi (int argc, char *argv[])
return grub_errno;
cmdline_size = len;
- grub_create_loader_cmdline (argc, argv, cmdline,
- cmdline_size);
-
- return GRUB_ERR_NONE;
+ return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
}
grub_err_t
@@ -1109,7 +1107,7 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size);
+ newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
if (err)
{
grub_free (newmod->cmdline);
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
index 6e814649f31..c114e7df4fb 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -302,8 +302,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
- size);
+ if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
+ size))
+ goto out;
out:
diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
index 67ef0488324..abe46faa012 100644
--- a/grub-core/loader/sparc64/ieee1275/linux.c
+++ b/grub-core/loader/sparc64/ieee1275/linux.c
@@ -340,8 +340,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
- grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
- size);
+ if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
+ size, GRUB_VERIFY_KERNEL_CMDLINE))
+ goto out;
out:
if (elf)
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index 9f78abb05f9..5944dc5eafc 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -35,6 +35,7 @@
#include <grub/i18n.h>
#include <grub/efi/sb.h>
#include <grub/safemath.h>
+#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -429,6 +430,10 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0;
+ err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
@@ -538,6 +543,10 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
if (ptr != grub_xnu_cmdline)
*(ptr - 1) = 0;
+ err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
+ if (err)
+ return err;
+
#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
err = grub_efiemu_autocore ();
if (err)
diff --git a/include/grub/lib/cmdline.h b/include/grub/lib/cmdline.h
index 1fe8d017971..cdca09b7a16 100644
--- a/include/grub/lib/cmdline.h
+++ b/include/grub/lib/cmdline.h
@@ -21,11 +21,12 @@
#define GRUB_CMDLINE_HEADER 1
#include <grub/types.h>
+#include <grub/verify.h>
#define LINUX_IMAGE "BOOT_IMAGE="
unsigned int grub_loader_cmdline_size (int argc, char *argv[]);
-int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
- grub_size_t size);
+grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf,
+ grub_size_t size, enum grub_verify_string_type type);
#endif /* ! GRUB_CMDLINE_HEADER */
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 298120f5776..9f892d8fedb 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -25,6 +25,12 @@ enum grub_verify_flags
GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2
};
+enum grub_verify_string_type
+ {
+ GRUB_VERIFY_KERNEL_CMDLINE,
+ GRUB_VERIFY_MODULE_CMDLINE,
+ };
+
struct grub_file_verifier
{
struct grub_file_verifier *next;
@@ -48,6 +54,8 @@ struct grub_file_verifier
grub_err_t (*fini) (void *context);
void (*close) (void *context);
+
+ grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type);
};
extern struct grub_file_verifier *grub_file_verifiers;
@@ -63,3 +71,6 @@ grub_verifier_unregister (struct grub_file_verifier *ver)
{
grub_list_remove (GRUB_AS_LIST (ver));
}
+
+grub_err_t
+grub_verify_string (char *str, enum grub_verify_string_type type);

View File

@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Wed, 26 Sep 2018 13:17:52 +0200
Subject: [PATCH] verifiers: Add possibility to defer verification to other
verifiers
This way if a verifier requires verification of a given file it can defer task
to another verifier (another authority) if it is not able to do it itself. E.g.
shim_lock verifier, posted as a subsequent patch, is able to verify only PE
files. This means that it is not able to verify any of GRUB2 modules which have
to be trusted on UEFI systems with secure boot enabled. So, it can defer
verification to other verifier, e.g. PGP one.
I silently assume that other verifiers are trusted and will do good job for us.
Or at least they will not do any harm.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/commands/verifiers.c | 23 ++++++++++++++++++++---
include/grub/verify.h | 4 +++-
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c
index 59ea418a2d9..c638d5f43e0 100644
--- a/grub-core/commands/verifiers.c
+++ b/grub-core/commands/verifiers.c
@@ -83,6 +83,7 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
void *context;
grub_file_t ret = 0;
grub_err_t err;
+ int defer = 0;
grub_dprintf ("verify", "file: %s type: %d\n", io->name, type);
@@ -102,13 +103,27 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
+ if (flags & GRUB_VERIFY_FLAGS_DEFER_AUTH)
+ {
+ defer = 1;
+ continue;
+ }
if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION))
break;
}
if (!ver)
- /* No verifiers wanted to verify. Just return underlying file. */
- return io;
+ {
+ if (defer)
+ {
+ grub_error (GRUB_ERR_ACCESS_DENIED,
+ N_("verification requested but nobody cares: %s"), io->name);
+ goto fail_noclose;
+ }
+
+ /* No verifiers wanted to verify. Just return underlying file. */
+ return io;
+ }
ret = grub_malloc (sizeof (*ret));
if (!ret)
@@ -160,7 +175,9 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
- if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION)
+ if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION ||
+ /* Verification done earlier. So, we are happy here. */
+ flags & GRUB_VERIFY_FLAGS_DEFER_AUTH)
continue;
err = ver->write (context, verified->buf, ret->size);
if (err)
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 9f892d8fedb..79022b42258 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -22,7 +22,9 @@
enum grub_verify_flags
{
GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1,
- GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2
+ GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2,
+ /* Defer verification to another authority. */
+ GRUB_VERIFY_FLAGS_DEFER_AUTH = 4
};
enum grub_verify_string_type

View File

@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Tue, 2 Oct 2018 22:36:43 +0200
Subject: [PATCH] verifiers: Rename verify module to pgp module
Just for clarity. No functional change.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
(cherry picked from commit b07feb8746c3bb845e3f0d33d37c0bded704d14d)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 4 ++--
grub-core/commands/{verify.c => pgp.c} | 0
2 files changed, 2 insertions(+), 2 deletions(-)
rename grub-core/commands/{verify.c => pgp.c} (100%)
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 29c3bf6cd66..809f11feaef 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -915,8 +915,8 @@ module = {
};
module = {
- name = verify;
- common = commands/verify.c;
+ name = pgp;
+ common = commands/pgp.c;
cflags = '$(CFLAGS_POSIX)';
cppflags = '-I$(srcdir)/lib/posix_wrap';
};
diff --git a/grub-core/commands/verify.c b/grub-core/commands/pgp.c
similarity index 100%
rename from grub-core/commands/verify.c
rename to grub-core/commands/pgp.c

View File

@ -0,0 +1,55 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@ubuntu.com>
Date: Wed, 9 Jan 2019 14:54:39 +0000
Subject: [PATCH] pgp: Fix emu build and tests after pgp module renaming
Commit b07feb8746c3bb845e3f0d33d37c0bded704d14d (verifiers: Rename
verify module to pgp module) renamed the "verify" module to "pgp", but
the GRUB_MOD_INIT and GRUB_MOD_FINI macros were left as "verify", which
broke the emu target build; and file_filter_test still referred to the
now non-existent "verify" module. Fix both of these.
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit ed087f0460516737e174222f01e2bf6ccbd45674)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/pgp.c | 4 ++--
tests/file_filter_test.in | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 29e74a64004..5c913c2e2fe 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -950,7 +950,7 @@ struct grub_file_verifier grub_pubkey_verifier =
static grub_extcmd_t cmd, cmd_trust;
static grub_command_t cmd_distrust, cmd_list;
-GRUB_MOD_INIT(verify)
+GRUB_MOD_INIT(pgp)
{
const char *val;
struct grub_module_header *header;
@@ -1009,7 +1009,7 @@ GRUB_MOD_INIT(verify)
grub_verifier_register (&grub_pubkey_verifier);
}
-GRUB_MOD_FINI(verify)
+GRUB_MOD_FINI(pgp)
{
grub_verifier_unregister (&grub_pubkey_verifier);
grub_unregister_extcmd (cmd);
diff --git a/tests/file_filter_test.in b/tests/file_filter_test.in
index bfb6382274e..ed6abcb5af4 100644
--- a/tests/file_filter_test.in
+++ b/tests/file_filter_test.in
@@ -19,7 +19,7 @@ grubshell=@builddir@/grub-shell
. "@builddir@/grub-core/modinfo.sh"
-filters="gzio xzio lzopio verify"
+filters="gzio xzio lzopio pgp"
modules="cat mpi"
for mod in $(cut -d ' ' -f 2 "@builddir@/grub-core/crypto.lst" | sort -u); do

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <leif.lindholm@linaro.org>
Date: Wed, 14 Nov 2018 19:29:16 +0000
Subject: [PATCH] include/grub/file.h: Add device tree file type
The API change of grub_file_open() for adding verifiers did not include
a type for device tree blobs. Add GRUB_FILE_TYPE_DEVICE_TREE_IMAGE to
the grub_file_type enum.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit 7453c2cc32525a5eebe3b268433d0dfc73622917)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
include/grub/file.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/grub/file.h b/include/grub/file.h
index 19dda67f68b..9aae463557a 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -69,6 +69,8 @@ enum grub_file_type
GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE,
+ GRUB_FILE_TYPE_DEVICE_TREE_IMAGE,
+
/* File holding signature. */
GRUB_FILE_TYPE_SIGNATURE,
/* File holding public key to verify signature once. */

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <leif.lindholm@linaro.org>
Date: Wed, 14 Nov 2018 19:29:17 +0000
Subject: [PATCH] grub-core/loader/efi/fdt.c: Fixup grub_file_open() call
The verifiers framework changed the API of grub_file_open(), but did not
fix up all users. Add the file type GRUB_FILE_TYPE_DEVICE_TREE_IMAGE
to the "devicetree" command handler call.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/efi/fdt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index a9dbcfdfeaf..e3ee3ad79d6 100644
--- a/grub-core/loader/efi/fdt.c
+++ b/grub-core/loader/efi/fdt.c
@@ -125,7 +125,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
return GRUB_ERR_NONE;
}
- dtb = grub_file_open (argv[0]);
+ dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE);
if (!dtb)
goto out;

View File

@ -0,0 +1,38 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <leif.lindholm@linaro.org>
Date: Wed, 14 Nov 2018 19:29:18 +0000
Subject: [PATCH] arm64/efi: Fix breakage caused by verifiers
- add variable "err" (used but not defined),
- add GRUB_FILE_TYPE_LINUX_KERNEL to grub_file_open() call.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Conflicts:
grub-core/loader/arm64/linux.c
---
grub-core/loader/arm64/linux.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 48ea66596ad..864724dd4fa 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -338,6 +338,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
struct linux_armxx_kernel_header lh;
struct grub_armxx_linux_pe_header *pe;
int rc;
+ grub_err_t err;
grub_dl_ref (my_mod);
@@ -347,7 +348,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (!file)
goto fail;

View File

@ -0,0 +1,74 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <leif.lindholm@linaro.org>
Date: Wed, 14 Nov 2018 19:29:19 +0000
Subject: [PATCH] arm-uboot, ia64, sparc64: Fix up grub_file_open() calls
The verifiers framework changed the grub_file_open() interface, breaking all
non-x86 linux loaders. Add file types to the grub_file_open() calls to make
them build again.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/arm/linux.c | 6 +++---
grub-core/loader/ia64/efi/linux.c | 2 +-
grub-core/loader/sparc64/ieee1275/linux.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index beceda52030..1e944a2b671 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -363,7 +363,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (!file)
goto fail;
@@ -408,7 +408,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD);
if (!file)
return grub_errno;
@@ -471,7 +471,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)),
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
- dtb = grub_file_open (argv[0]);
+ dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE);
if (!dtb)
return grub_errno;
diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c
index e325fe0ee83..2ad0b0c0407 100644
--- a/grub-core/loader/ia64/efi/linux.c
+++ b/grub-core/loader/ia64/efi/linux.c
@@ -502,7 +502,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (! file)
goto fail;
diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
index abe46faa012..bb47ee0cc64 100644
--- a/grub-core/loader/sparc64/ieee1275/linux.c
+++ b/grub-core/loader/sparc64/ieee1275/linux.c
@@ -306,7 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out;
}
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (!file)
goto out;

View File

@ -0,0 +1,146 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 20 Nov 2018 19:15:37 +0800
Subject: [PATCH] verifiers: fix double close on pgp's sig file descriptor
An error emerged as when I was testing the verifiers branch, so instead
of putting it in pgp prefix, the verifiers is used to reflect what the
patch is based on.
While running verify_detached, grub aborts with error.
verify_detached /@/.snapshots/1/snapshot/boot/grub/grub.cfg
/@/.snapshots/1/snapshot/boot/grub/grub.cfg.sig
alloc magic is broken at 0x7beea660: 0
Aborted. Press any key to exit.
The error is caused by sig file descriptor been closed twice, first time
in grub_verify_signature() to which it is passed as parameter. Second in
grub_cmd_verify_signature() or in whichever opens the sig file
descriptor. The second close is not consider as bug to me either, as in
common rule of what opens a file has to close it to avoid file
descriptor leakage.
After all the design of grub_verify_signature() makes it difficult to keep
a good trace on opened file descriptor from it's caller. Let's refine
the application interface to accept file path rather than descriptor, in
this way the caller doesn't have to care about closing the descriptor by
delegating it to grub_verify_signature() with full tracing to opened
file descriptor by itself.
Also making it clear that sig descriptor is not referenced in error
returning path of grub_verify_signature_init(), so it can be closed
directly by it's caller. This also makes delegating it to
grub_pubkey_close() infeasible to help in relieving file descriptor
leakage as it has to depend on uncertainty of ctxt fields in error
returning path.
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/pgp.c | 35 +++++++++++++++++------------------
include/grub/pubkey.h | 2 +-
2 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 5c913c2e2fe..d39846d8cfe 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -495,13 +495,12 @@ grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig)
grub_dprintf ("crypt", "alive\n");
- ctxt->sig = sig;
-
ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize);
if (!ctxt->hash_context)
return grub_errno;
ctxt->hash->init (ctxt->hash_context);
+ ctxt->sig = sig;
return GRUB_ERR_NONE;
}
@@ -684,16 +683,26 @@ grub_pubkey_close (void *ctxt)
}
grub_err_t
-grub_verify_signature (grub_file_t f, grub_file_t sig,
+grub_verify_signature (grub_file_t f, const char *fsig,
struct grub_public_key *pkey)
{
+ grub_file_t sig;
grub_err_t err;
struct grub_pubkey_context ctxt;
grub_uint8_t *readbuf = NULL;
+ sig = grub_file_open (fsig,
+ GRUB_FILE_TYPE_SIGNATURE
+ | GRUB_FILE_TYPE_NO_DECOMPRESS);
+ if (!sig)
+ return grub_errno;
+
err = grub_verify_signature_init (&ctxt, sig);
if (err)
- return err;
+ {
+ grub_file_close (sig);
+ return err;
+ }
readbuf = grub_zalloc (READBUF_SIZE);
if (!readbuf)
@@ -807,7 +816,7 @@ static grub_err_t
grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
int argc, char **args)
{
- grub_file_t f = NULL, sig = NULL;
+ grub_file_t f = NULL;
grub_err_t err = GRUB_ERR_NONE;
struct grub_public_key *pk = NULL;
@@ -845,19 +854,8 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
goto fail;
}
- sig = grub_file_open (args[1],
- GRUB_FILE_TYPE_SIGNATURE
- | GRUB_FILE_TYPE_NO_DECOMPRESS);
- if (!sig)
- {
- err = grub_errno;
- goto fail;
- }
-
- err = grub_verify_signature (f, sig, pk);
+ err = grub_verify_signature (f, args[1], pk);
fail:
- if (sig)
- grub_file_close (sig);
if (f)
grub_file_close (f);
if (pk)
@@ -902,7 +900,8 @@ grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unuse
err = grub_verify_signature_init (ctxt, sig);
if (err)
{
- grub_pubkey_close (ctxt);
+ grub_free (ctxt);
+ grub_file_close (sig);
return err;
}
*context = ctxt;
diff --git a/include/grub/pubkey.h b/include/grub/pubkey.h
index 4a9d04b4305..fb8be9cbb73 100644
--- a/include/grub/pubkey.h
+++ b/include/grub/pubkey.h
@@ -25,7 +25,7 @@ struct grub_public_key *
grub_load_public_key (grub_file_t f);
grub_err_t
-grub_verify_signature (grub_file_t f, grub_file_t sig,
+grub_verify_signature (grub_file_t f, const char *fsig,
struct grub_public_key *pk);

View File

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Thu, 6 Dec 2018 13:38:15 +0100
Subject: [PATCH] verifiers: Xen fallout cleanup
Xen fallout cleanup after commit ca0a4f689 (verifiers: File type for
fine-grained signature-verification controlling).
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/loader/i386/xen.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
index 07a4837c532..071b530d744 100644
--- a/grub-core/loader/i386/xen.c
+++ b/grub-core/loader/i386/xen.c
@@ -647,10 +647,10 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
grub_xen_reset ();
- grub_create_loader_cmdline (argc - 1, argv + 1,
- (char *) xen_state.next_start.cmd_line,
- sizeof (xen_state.next_start.cmd_line) - 1);
- err = grub_verify_string (xen_state.next_start.cmd_line, GRUB_VERIFY_MODULE_CMDLINE);
+ err = grub_create_loader_cmdline (argc - 1, argv + 1,
+ (char *) xen_state.next_start.cmd_line,
+ sizeof (xen_state.next_start.cmd_line) - 1,
+ GRUB_VERIFY_KERNEL_CMDLINE);
if (err)
return err;
@@ -918,9 +918,9 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
if (err)
goto fail;
- grub_create_loader_cmdline (argc - 1, argv + 1,
- get_virtual_current_address (ch), cmdline_len);
- err = grub_verify_string (get_virtual_current_address (ch), GRUB_VERIFY_MODULE_CMDLINE);
+ err = grub_create_loader_cmdline (argc - 1, argv + 1,
+ get_virtual_current_address (ch), cmdline_len,
+ GRUB_VERIFY_MODULE_CMDLINE);
if (err)
goto fail;

View File

@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Thu, 6 Dec 2018 13:43:05 +0100
Subject: [PATCH] verifiers: ARM Xen fallout cleanup
ARM Xen fallout cleanup after commit ca0a4f689 (verifiers: File type for
fine-grained signature-verification controlling).
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
[javierm: remove grub_file_filter_disable_compression() call leftovers]
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Conflicts:
grub-core/loader/arm64/xen_boot.c
---
grub-core/loader/arm64/xen_boot.c | 9 +++++----
include/grub/file.h | 5 +++++
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
index f35b16caa92..318c833de57 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -427,9 +427,10 @@ grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)),
grub_dprintf ("xen_loader", "Init module and node info\n");
- if (nounzip)
- grub_file_filter_disable_compression ();
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_MODULE
+ | (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS
+ : GRUB_FILE_TYPE_NONE));
+
if (!file)
goto fail;
@@ -461,7 +462,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_HYPERVISOR);
if (!file)
goto fail;
diff --git a/include/grub/file.h b/include/grub/file.h
index 9aae463557a..cbbd294655b 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -42,6 +42,11 @@ enum grub_file_type
/* Multiboot module. */
GRUB_FILE_TYPE_MULTIBOOT_MODULE,
+ /* Xen hypervisor - used on ARM only. */
+ GRUB_FILE_TYPE_XEN_HYPERVISOR,
+ /* Xen module - used on ARM only. */
+ GRUB_FILE_TYPE_XEN_MODULE,
+
GRUB_FILE_TYPE_BSD_KERNEL,
GRUB_FILE_TYPE_FREEBSD_ENV,
GRUB_FILE_TYPE_FREEBSD_MODULE,

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Thu, 14 Mar 2019 16:18:31 +0100
Subject: [PATCH] verifiers: IA-64 fallout cleanup
IA-64 fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines).
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/loader/ia64/efi/linux.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c
index 2ad0b0c0407..cfeb2c145bb 100644
--- a/grub-core/loader/ia64/efi/linux.c
+++ b/grub-core/loader/ia64/efi/linux.c
@@ -547,8 +547,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
*p = '\0';
- err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
- if (err)
+ if (grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE))
goto fail;
boot_param->command_line = (grub_uint64_t) cmdline;

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Thu, 14 Mar 2019 19:45:17 +0100
Subject: [PATCH] verifiers: PowerPC fallout cleanup
PowerPC fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines) and ca0a4f689 (verifiers: File
type for fine-grained signature-verification controlling).
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/loader/powerpc/ieee1275/linux.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
index c114e7df4fb..818b2a86d1a 100644
--- a/grub-core/loader/powerpc/ieee1275/linux.c
+++ b/grub-core/loader/powerpc/ieee1275/linux.c
@@ -270,7 +270,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out;
}
- elf = grub_elf_open (argv[0]);
+ elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (! elf)
goto out;
@@ -303,7 +303,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
- size))
+ size, GRUB_VERIFY_KERNEL_CMDLINE))
goto out;
out:

View File

@ -0,0 +1,27 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Mon, 18 Mar 2019 13:09:22 +0100
Subject: [PATCH] verifiers: MIPS fallout cleanup
MIPS fallout cleanup after commit 4d4a8c96e (verifiers: Add possibility
to verify kernel and modules command lines).
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/loader/mips/linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
index 20135ce253d..e4ed95921df 100644
--- a/grub-core/loader/mips/linux.c
+++ b/grub-core/loader/mips/linux.c
@@ -314,7 +314,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1,
- size);
+ size, GRUB_VERIFY_KERNEL_CMDLINE);
#else
linux_argv = extra;
argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Tue, 18 Feb 2020 18:08:18 +0800
Subject: [PATCH] verifiers: Fix calling uninitialized function pointer
The necessary check for NULL before use of function ver->close is not
taking place in the failure path. This patch simply adds the missing
check and fixes the problem that GRUB hangs indefinitely after booting
rogue image without valid signature if secure boot is turned on.
Now it displays like this for booting rogue UEFI image:
error: bad shim signature
error: you need to load the kernel first
Press any key to continue...
and then you can go back to boot menu by pressing any key or after a few
seconds expired.
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/verifiers.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c
index c638d5f43e0..599d79b757e 100644
--- a/grub-core/commands/verifiers.c
+++ b/grub-core/commands/verifiers.c
@@ -196,7 +196,8 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
return ret;
fail:
- ver->close (context);
+ if (ver->close)
+ ver->close (context);
fail_noclose:
verified_free (verified);
grub_free (ret);

View File

@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 12 May 2020 17:26:26 +1000
Subject: [PATCH] rhel: extra file type fixes
Signed-off-by: Daniel Axtens <dja@axtens.net>
[javierm: fix a couple of build errors caused by mismerges]
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
grub-core/commands/blscfg.c | 2 +-
grub-core/loader/arm64/linux.c | 1 +
grub-core/loader/i386/efi/linux.c | 9 +++++----
grub-core/net/net.c | 2 +-
grub-core/normal/main.c | 2 +-
grub-core/osdep/generic/blocklist.c | 4 ++--
6 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index 70ce5c7bf6f..795a9f9f178 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -463,7 +463,7 @@ static int read_entry (
p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
- f = grub_file_open (p);
+ f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG);
if (!f)
goto finish;
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 864724dd4fa..e1923cf7257 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -31,6 +31,7 @@
#include <grub/efi/memory.h>
#include <grub/efi/linux.h>
#include <grub/efi/pe32.h>
+#include <grub/efi/sb.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#include <grub/verify.h>
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index 361e503cb52..576f8c07eaf 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -101,8 +101,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
for (i = 0; i < argc; i++)
{
- grub_file_filter_disable_compression ();
- files[i] = grub_file_open (argv[i]);
+ files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD |
+ GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! files[i])
goto fail;
nfiles++;
@@ -182,7 +182,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- file = grub_file_open (argv[0]);
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
if (! file)
goto fail;
@@ -302,7 +302,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv,
linux_cmdline + sizeof (LINUX_IMAGE) - 1,
- lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1));
+ lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
+ GRUB_VERIFY_KERNEL_CMDLINE);
grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline);
grub_dprintf ("linux", "setting lh->cmd_line_ptr\n");
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 0e72bbb9b39..1fd104aeaf2 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1907,7 +1907,7 @@ grub_net_search_configfile (char *config)
grub_dprintf ("net", "probe %s\n", config);
grub_file_t file;
- file = grub_file_open (config);
+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG);
if (file)
{
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index cee71a4c2ab..49141039f8f 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -363,7 +363,7 @@ grub_try_normal (const char *variable)
if (config)
{
grub_file_t file;
- file = grub_file_open (config);
+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG);
if (file)
{
grub_file_close (file);
diff --git a/grub-core/osdep/generic/blocklist.c b/grub-core/osdep/generic/blocklist.c
index 74024fd06f3..ab1f96da62d 100644
--- a/grub-core/osdep/generic/blocklist.c
+++ b/grub-core/osdep/generic/blocklist.c
@@ -60,7 +60,7 @@ grub_install_get_blocklist (grub_device_t root_dev,
grub_disk_cache_invalidate_all ();
grub_file_filter_disable_compression ();
- file = grub_file_open (core_path_dev);
+ file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE);
if (file)
{
if (grub_file_size (file) != core_size)
@@ -118,7 +118,7 @@ grub_install_get_blocklist (grub_device_t root_dev,
grub_file_t file;
/* Now read the core image to determine where the sectors are. */
grub_file_filter_disable_compression ();
- file = grub_file_open (core_path_dev);
+ file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE);
if (! file)
grub_util_error ("%s", grub_errmsg);

View File

@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Tue, 2 Oct 2018 18:49:26 +0200
Subject: [PATCH] dl: Add support for persistent modules
This type of modules cannot be unloaded. This is useful if a given
functionality, e.g. UEFI secure boot shim signature verification, should
not be disabled if it was enabled at some point in time. Somebody may
say that we can use standalone GRUB2 here. That is true. However, the
code is not so big nor complicated hence it make sense to support
modularized configs too.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
(cherry picked from commit ee7808e2197cbf5e8515d90ecbd81c9d0dd6fc15)
---
grub-core/commands/minicmd.c | 3 +++
include/grub/dl.h | 13 +++++++++++++
2 files changed, 16 insertions(+)
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
index 46bf135e8f0..6d66b7c453a 100644
--- a/grub-core/commands/minicmd.c
+++ b/grub-core/commands/minicmd.c
@@ -137,6 +137,9 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
if (! mod)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
+ if (grub_dl_is_persistent (mod))
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module");
+
if (grub_dl_unref (mod) <= 0)
grub_dl_unload (mod);
diff --git a/include/grub/dl.h b/include/grub/dl.h
index 7b5bfb07ce6..f7cfe64823c 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -177,6 +177,7 @@ struct grub_dl
{
char *name;
int ref_count;
+ int persistent;
grub_dl_dep_t dep;
grub_dl_segment_t segment;
Elf_Sym *symtab;
@@ -242,6 +243,18 @@ grub_dl_get (const char *name)
return 0;
}
+static inline void
+grub_dl_set_persistent (grub_dl_t mod)
+{
+ mod->persistent = 1;
+}
+
+static inline int
+grub_dl_is_persistent (grub_dl_t mod)
+{
+ return mod->persistent;
+}
+
#endif
void * EXPORT_FUNC(grub_resolve_symbol) (const char *name);

View File

@ -0,0 +1,309 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rashmica Gupta <rashmica.g@gmail.com>
Date: Thu, 11 Jun 2020 11:26:23 +1000
Subject: [PATCH] Add suport for signing grub with an appended signature
Add infrastructure to allow firmware to verify the integrity of grub
by use of a Linux-kernel-module-style appended signature. We initially
target powerpc-ieee1275, but the code should be extensible to other
platforms.
Usually these signatures are appended to a file without modifying the
ELF file itself. (This is what the 'sign-file' tool does, for example.)
The verifier loads the signed file from the file system and looks at the
end of the file for the appended signature. However, on powerpc-ieee1275
platforms, the bootloader is often stored directly in the PReP partition
as raw bytes without a file-system. This makes determining the location
of an appended signature more difficult.
To address this, we add a new ELF note.
The name field of shall be the string "Appended-Signature", zero-padded
to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
for the string "ASig"). It must be the final section in the ELF binary.
The description shall contain the appended signature structure as defined
by the Linux kernel. The description will also be padded to be a multiple
of 4 bytes. The padding shall be added before the appended signature
structure (not at the end) so that the final bytes of a signed ELF file
are the appended signature magic.
A subsequent patch documents how to create a grub core.img validly signed
under this scheme.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
---
You can experiment with this code with a patched version of SLOF
that verifies these signatures. You can find one at:
https://github.com/daxtens/SLOF
I will be proposing this for inclusion in a future Power Architecture
Platform Reference (PAPR).
---
util/grub-install-common.c | 16 +++++++++++++---
util/grub-mkimage.c | 11 +++++++++++
util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++++-
util/mkimage.c | 10 +++++-----
include/grub/util/install.h | 8 ++++++--
include/grub/util/mkimage.h | 4 ++--
6 files changed, 75 insertions(+), 13 deletions(-)
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index cf993c059ad..561e671ff34 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -303,10 +303,12 @@ handle_install_list (struct install_list *il, const char *val,
static char **pubkeys;
static size_t npubkeys;
static grub_compression_t compression;
+static size_t appsig_size;
int
grub_install_parse (int key, char *arg)
{
+ const char *end;
switch (key)
{
case 'C':
@@ -395,6 +397,12 @@ grub_install_parse (int key, char *arg)
grub_util_error (_("Unrecognized compression `%s'"), arg);
case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
return 1;
+ case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE:
+ grub_errno = 0;
+ appsig_size = grub_strtol(arg, &end, 10);
+ if (grub_errno)
+ return 0;
+ return 1;
default:
return 0;
}
@@ -493,10 +501,12 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'"
" --output '%s' "
" --dtb '%s' "
- "--format '%s' --compression '%s' %s %s\n",
+ "--format '%s' --compression '%s' "
+ "--appended-signature-size %zu %s %s\n",
dir, prefix,
outname, dtb ? : "", mkimage_target,
- compnames[compression], note ? "--note" : "", s);
+ compnames[compression], appsig_size,
+ note ? "--note" : "", s);
free (s);
tgt = grub_install_get_image_target (mkimage_target);
@@ -506,7 +516,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
grub_install_generate_image (dir, prefix, fp, outname,
modules.entries, memdisk_path,
pubkeys, npubkeys, config_path, tgt,
- note, compression, dtb);
+ note, appsig_size, compression, dtb);
while (dc--)
grub_install_pop_module ();
}
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index 98d24cc06ea..65a015d8a04 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -82,6 +82,7 @@ static struct argp_option options[] = {
{"format", 'O', N_("FORMAT"), 0, 0, 0},
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
+ {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
{ 0, 0, 0, 0, 0, 0 }
};
@@ -124,6 +125,7 @@ struct arguments
char *font;
char *config;
int note;
+ size_t appsig_size;
const struct grub_install_image_target_desc *image_target;
grub_compression_t comp;
};
@@ -134,6 +136,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
+ const char* end;
switch (key)
{
@@ -166,6 +169,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->note = 1;
break;
+ case 'S':
+ grub_errno = 0;
+ arguments->appsig_size = grub_strtol(arg, &end, 10);
+ if (grub_errno)
+ return 0;
+ break;
+
case 'm':
if (arguments->memdisk)
free (arguments->memdisk);
@@ -309,6 +319,7 @@ main (int argc, char *argv[])
arguments.memdisk, arguments.pubkeys,
arguments.npubkeys, arguments.config,
arguments.image_target, arguments.note,
+ arguments.appsig_size,
arguments.comp, arguments.dtb);
grub_util_file_sync (fp);
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index f9aa1a033b5..1bb5eb84c14 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -82,6 +82,15 @@ struct grub_ieee1275_note
struct grub_ieee1275_note_desc descriptor;
};
+#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
+#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
+
+struct grub_appended_signature_note
+{
+ Elf32_Nhdr header;
+ char name[ALIGN_UP(sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)];
+};
+
#define GRUB_XEN_NOTE_NAME "Xen"
struct fixup_block_list
@@ -205,7 +214,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
void
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
- int note, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
Elf_Addr target_addr,
struct grub_mkimage_layout *layout)
{
@@ -219,6 +228,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
int shnum = 4;
int string_size = sizeof (".text") + sizeof ("mods") + 1;
+ if (appsig_size)
+ {
+ phnum++;
+ footer_size += ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
+ }
+
if (image_target->id != IMAGE_LOONGSON_ELF)
phnum += 2;
@@ -449,6 +464,28 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
}
+ if (appsig_size) {
+ int note_size = ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
+ struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *)
+ (elf_img + program_size + header_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
+
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
+ /* needs to sit at the end, so we round this up and sign some zero padding */
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(appsig_size, 4));
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
+ strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (note_size);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
+ }
+
{
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
+ shnum * sizeof (*shdr));
diff --git a/util/mkimage.c b/util/mkimage.c
index e22d82afa61..a81120f26be 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -777,7 +777,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
char *memdisk_path, char **pubkey_paths,
size_t npubkeys, char *config_path,
const struct grub_install_image_target_desc *image_target,
- int note, grub_compression_t comp, const char *dtb_path)
+ int note, size_t appsig_size, grub_compression_t comp, const char *dtb_path)
{
char *kernel_img, *core_img;
size_t total_module_size, core_size;
@@ -1694,11 +1694,11 @@ grub_install_generate_image (const char *dir, const char *prefix,
else
target_addr = image_target->link_addr;
if (image_target->voidp_sizeof == 4)
- grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
- target_addr, &layout);
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
+ &core_size, target_addr, &layout);
else
- grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
- target_addr, &layout);
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
+ &core_size, target_addr, &layout);
}
break;
}
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 0dba8b67f93..ba5e6a2ea8f 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -63,6 +63,9 @@
/* TRANSLATORS: "embed" is a verb (command description). "*/ \
{ "pubkey", 'k', N_("FILE"), 0, \
N_("embed FILE as public key for signature checking"), 0}, \
+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
+ 1}, \
{ "verbose", 'v', 0, 0, \
N_("print verbose messages."), 1 }
@@ -119,7 +122,8 @@ enum grub_install_options {
GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY,
GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
- GRUB_INSTALL_OPTIONS_DTB
+ GRUB_INSTALL_OPTIONS_DTB,
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
};
extern char *grub_install_source_directory;
@@ -179,7 +183,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
size_t npubkeys,
char *config_path,
const struct grub_install_image_target_desc *image_target,
- int note,
+ int note, size_t appsig_size,
grub_compression_t comp, const char *dtb_file);
const struct grub_install_image_target_desc *
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
index b3a5ca132bc..cef7fffa7ae 100644
--- a/include/grub/util/mkimage.h
+++ b/include/grub/util/mkimage.h
@@ -50,12 +50,12 @@ grub_mkimage_load_image64 (const char *kernel_path,
const struct grub_install_image_target_desc *image_target);
void
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
- int note, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
Elf32_Addr target_addr,
struct grub_mkimage_layout *layout);
void
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
- int note, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
Elf64_Addr target_addr,
struct grub_mkimage_layout *layout);

View File

@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 02:00:57 +1000
Subject: [PATCH] docs/grub: Document signing grub under UEFI
Before adding information about how grub is signed with an appended
signature scheme, it's worth adding some information about how it
can currently be signed for UEFI.
(adjusted from upstream - s/grub/grub2/ in the docs)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index fa11cc0aff7..acace6c0737 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5610,6 +5610,7 @@ environment variables and commands are listed in the same order.
@menu
* Authentication and authorisation:: Users and access control
* Using digital signatures:: Booting digitally signed code
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
@end menu
@node Authentication and authorisation
@@ -5687,7 +5688,7 @@ commands.
GRUB's @file{core.img} can optionally provide enforcement that all files
subsequently read from disk are covered by a valid digital signature.
-This document does @strong{not} cover how to ensure that your
+This section does @strong{not} cover how to ensure that your
platform's firmware (e.g., Coreboot) validates @file{core.img}.
If environment variable @code{check_signatures}
@@ -5772,6 +5773,22 @@ or BIOS) configuration to cause the machine to boot from a different
(attacker-controlled) device. GRUB is at best only one link in a
secure boot chain.
+@node Signing GRUB itself
+@section Signing GRUB itself
+
+To ensure a complete secure-boot chain, there must be a way for the code that
+loads GRUB to verify the integrity of the core image.
+
+This is ultimately platform-specific and individual platforms can define their
+own mechanisms. However, there are general-purpose mechanisms that can be used
+with GRUB.
+
+@section Signing GRUB for UEFI secure boot
+
+On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed
+with a tool such as @command{pesign} or @command{sbsign}. It will also be
+necessary to enrol the public key used into a relevant firmware key database.
+
@node Platform limitations
@chapter Platform limitations

View File

@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 02:19:36 +1000
Subject: [PATCH] docs/grub: Document signing grub with an appended signature
Signing grub for firmware that verifies an appended signature is a
bit fiddly. I don't want people to have to figure it out from scratch
so document it here.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/docs/grub.texi b/docs/grub.texi
index acace6c0737..61c92a1e03d 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5789,6 +5789,48 @@ On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed
with a tool such as @command{pesign} or @command{sbsign}. It will also be
necessary to enrol the public key used into a relevant firmware key database.
+@section Signing GRUB with an appended signature
+
+The @file{core.img} itself can be signed with a Linux kernel module-style
+appended signature.
+
+To support IEEE1275 platforms where the boot image is often loaded directly
+from a disk partition rather than from a file system, the @file{core.img}
+can specify the size and location of the appended signature with an ELF
+note added by @command{grub-install}.
+
+An image can be signed this way using the @command{sign-file} command from
+the Linux kernel:
+
+@example
+@group
+# grub.key is your private key and certificate.der is your public key
+
+# Determine the size of the appended signature. It depends on the signing
+# certificate and the hash algorithm
+touch empty
+sign-file SHA256 grub.key certificate.der empty empty.sig
+SIG_SIZE=`stat -c '%s' empty.sig`
+rm empty empty.sig
+
+# Build a grub image with $SIG_SIZE reserved for the signature
+grub-install --appended-signature-size $SIG_SIZE --modules="..." ...
+
+# Replace the reserved size with a signature:
+# cut off the last $SIG_SIZE bytes with truncate's minus modifier
+truncate -s -$SIG_SIZE /boot/grub/powerpc-ieee1275/core.elf core.elf.unsigned
+# sign the trimmed file with an appended signature, restoring the correct size
+sign-file SHA256 grub.key certificate.der core.elf.unsigned core.elf.signed
+
+# Don't forget to install the signed image as required
+# (e.g. on powerpc-ieee1275, to the PReP partition)
+@end group
+@end example
+
+As with UEFI secure boot, it is necessary to build in the required modules,
+or sign them separately.
+
+
@node Platform limitations
@chapter Platform limitations

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 01:00:11 +1000
Subject: [PATCH] docs/grub: grub-install is no longer a shell script
Since commit cd46aa6cefab in 2013, grub-install hasn't been a shell
script. The para doesn't really add that much, especially since it's
the user manual, so just drop it.
(adjust docs: s/grub/grub2)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 7 -------
1 file changed, 7 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 61c92a1e03d..34517e67439 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -695,13 +695,6 @@ floppy instead of exposing the USB drive as a hard disk (they call it
This install doesn't conflict with standard install as long as they are in
separate directories.
-Note that @command{grub2-install} is actually just a shell script and the
-real task is done by other tools such as @command{grub2-mkimage}. Therefore,
-you may run those commands directly to install GRUB, without using
-@command{grub2-install}. Don't do that, however, unless you are very familiar
-with the internals of GRUB. Installing a boot loader on a running OS may be
-extremely dangerous.
-
On EFI systems for fixed disk install you have to mount EFI System Partition.
If you mount it at @file{/boot/efi} then you don't need any special arguments:

View File

@ -0,0 +1,36 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 02:04:01 +1000
Subject: [PATCH] docs/grub: --pubkey has been supported for some time
--pubkey is supported, so we can now document it.
(adjust docs: s/grub/grub2)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 34517e67439..a833364d5ff 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5695,15 +5695,9 @@ verified with a public key currently trusted by GRUB
validation fails, then file @file{foo} cannot be opened. This failure
may halt or otherwise impact the boot process.
-@comment Unfortunately --pubkey is not yet supported by grub2-install,
-@comment but we should not bring up internal detail grub2-mkimage here
-@comment in the user guide (as opposed to developer's manual).
-
-@comment An initial trusted public key can be embedded within the GRUB
-@comment @file{core.img} using the @code{--pubkey} option to
-@comment @command{grub2-mkimage} (@pxref{Invoking grub2-install}). Presently it
-@comment is necessary to write a custom wrapper around @command{grub2-mkimage}
-@comment using the @code{--grub-mkimage} flag to @command{grub2-install}.
+An initial trusted public key can be embedded within the GRUB
+@file{core.img} using the @code{--pubkey} option to
+@command{grub2-install} (@pxref{Invoking grub2-install}).
GRUB uses GPG-style detached signatures (meaning that a file
@file{foo.sig} will be produced when file @file{foo} is signed), and

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 00:13:21 +1000
Subject: [PATCH] dl: provide a fake grub_dl_set_persistent for the emu target
Trying to start grub-emu with a module that calls grub_dl_set_persistent
will crash because grub-emu fakes modules and passes NULL to the module
init function.
Provide an empty function for the emu case.
Fixes: ee7808e2197c (dl: Add support for persistent modules)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
include/grub/dl.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/grub/dl.h b/include/grub/dl.h
index f7cfe64823c..877821dcb04 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -243,11 +243,22 @@ grub_dl_get (const char *name)
return 0;
}
+#ifdef GRUB_MACHINE_EMU
+/*
+ * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT.
+ * So we fake this out to avoid a NULL deref.
+ */
+static inline void
+grub_dl_set_persistent (grub_dl_t mod __attribute__((unused)))
+{
+}
+#else
static inline void
grub_dl_set_persistent (grub_dl_t mod)
{
mod->persistent = 1;
}
+#endif
static inline int
grub_dl_is_persistent (grub_dl_t mod)

View File

@ -0,0 +1,96 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 29 Jul 2020 17:46:16 +1000
Subject: [PATCH] verifiers: provide unsafe module list
Other verifiers that implement secure boot may want to be able to
use this list and behaviour.
Upstream, this factors the list out of the shim_lock verifier.
However, that hasn't hit the RHEL8.4 tree yet, so instead
of factoring it out of that we just create it.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/verifiers.c | 46 ++++++++++++++++++++++++++++++++++++++++++
include/grub/verify.h | 13 ++++++++++++
2 files changed, 59 insertions(+)
diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c
index 599d79b757e..f64343ac90b 100644
--- a/grub-core/commands/verifiers.c
+++ b/grub-core/commands/verifiers.c
@@ -218,6 +218,52 @@ grub_verify_string (char *str, enum grub_verify_string_type type)
return GRUB_ERR_NONE;
}
+/* List of modules which may allow for verifcation to be bypassed. */
+static const char *const disabled_mods[] = { "iorw", "memrw", "wrmsr", NULL };
+
+/*
+ * Does the module in file `io' allow for the a verifier to be bypassed?
+ *
+ * Returns 1 if so, otherwise 0.
+ */
+char
+grub_is_dangerous_module (grub_file_t io)
+{
+ char *b, *e;
+ int i;
+
+ /* Establish GRUB module name. */
+ b = grub_strrchr (io->name, '/');
+ e = grub_strrchr (io->name, '.');
+
+ b = b ? (b + 1) : io->name;
+ e = e ? e : io->name + grub_strlen (io->name);
+ e = (e > b) ? e : io->name + grub_strlen (io->name);
+
+ for (i = 0; disabled_mods[i]; i++)
+ if (!grub_strncmp (b, disabled_mods[i],
+ grub_strlen (b) - grub_strlen (e)))
+ return 1;
+ return 0;
+}
+
+/*
+ * Is there already an unsafe module in memory?
+ * Returns the name if one is loaded, otherwise NULL.
+ */
+const char *
+grub_dangerous_module_loaded (void)
+{
+ int i;
+
+ for (i = 0; disabled_mods[i]; i++)
+ if (grub_dl_get (disabled_mods[i]))
+ {
+ return disabled_mods[i];
+ }
+ return NULL;
+}
+
GRUB_MOD_INIT(verifiers)
{
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open);
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 79022b42258..60c13e7ea8e 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -76,3 +76,16 @@ grub_verifier_unregister (struct grub_file_verifier *ver)
grub_err_t
grub_verify_string (char *str, enum grub_verify_string_type type);
+
+/*
+ * Does the module in file `io' allow for the a verifier to be bypassed?
+ *
+ * Returns 1 if so, otherwise 0.
+ */
+char grub_is_dangerous_module (grub_file_t io);
+
+/*
+ * Is there already an unsafe module in memory?
+ * Returns the name if one is loaded, otherwise NULL.
+ */
+const char *grub_dangerous_module_loaded (void);

View File

@ -0,0 +1,191 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 1 Oct 2020 20:23:48 +1000
Subject: [PATCH] pgp: factor out rsa_pad
rsa_pad does the PKCS#1 v1.5 padding for the RSA signature scheme.
We want to use it in other RSA signature verification applications.
I considered and rejected putting it in lib/crypto.c. That file doesn't
currently require any MPI functions, but rsa_pad does. That's not so
much of a problem for the grub kernel and modules, but crypto.c also
gets built into all the grub utilities. So - despite the utils not
using any asymmetric ciphers - we would need to built the entire MPI
infrastructure in to them.
A better and simpler solution is just to spin rsa_pad out into its own
PKCS#1 v1.5 module.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 8 ++++++
grub-core/commands/pgp.c | 28 ++-------------------
grub-core/lib/pkcs1_v15.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
include/grub/pkcs1_v15.h | 27 +++++++++++++++++++++
4 files changed, 96 insertions(+), 26 deletions(-)
create mode 100644 grub-core/lib/pkcs1_v15.c
create mode 100644 include/grub/pkcs1_v15.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 809f11feaef..99615c07b94 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2387,6 +2387,14 @@ module = {
cppflags = '$(CPPFLAGS_GCRY)';
};
+module = {
+ name = pkcs1_v15;
+ common = lib/pkcs1_v15.c;
+
+ cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';
+ cppflags = '$(CPPFLAGS_GCRY)';
+};
+
module = {
name = all_video;
common = lib/fake_module.c;
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index d39846d8cfe..bb6543819f0 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -24,6 +24,7 @@
#include <grub/file.h>
#include <grub/command.h>
#include <grub/crypto.h>
+#include <grub/pkcs1_v15.h>
#include <grub/i18n.h>
#include <grub/gcrypt/gcrypt.h>
#include <grub/pubkey.h>
@@ -411,32 +412,7 @@ static int
rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
const gcry_md_spec_t *hash, struct grub_public_subkey *sk)
{
- grub_size_t tlen, emlen, fflen;
- grub_uint8_t *em, *emptr;
- unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]);
- int ret;
- tlen = hash->mdlen + hash->asnlen;
- emlen = (nbits + 7) / 8;
- if (emlen < tlen + 11)
- return 1;
-
- em = grub_malloc (emlen);
- if (!em)
- return 1;
-
- em[0] = 0x00;
- em[1] = 0x01;
- fflen = emlen - tlen - 3;
- for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
- *emptr = 0xff;
- *emptr++ = 0x00;
- grub_memcpy (emptr, hash->asnoid, hash->asnlen);
- emptr += hash->asnlen;
- grub_memcpy (emptr, hval, hash->mdlen);
-
- ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
- grub_free (em);
- return ret;
+ return grub_crypto_rsa_pad(hmpi, hval, hash, sk->mpis[0]);
}
struct grub_pubkey_context
diff --git a/grub-core/lib/pkcs1_v15.c b/grub-core/lib/pkcs1_v15.c
new file mode 100644
index 00000000000..dbacd563d01
--- /dev/null
+++ b/grub-core/lib/pkcs1_v15.c
@@ -0,0 +1,59 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 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/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/gcrypt/gcrypt.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/*
+ * Given a hash value 'hval', of hash specification 'hash', perform
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
+ * (see RFC 8017 s 9.2) and place the result in 'hmpi'.
+ */
+gcry_err_code_t
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
+ const gcry_md_spec_t * hash, gcry_mpi_t mod)
+{
+ grub_size_t tlen, emlen, fflen;
+ grub_uint8_t *em, *emptr;
+ unsigned nbits = gcry_mpi_get_nbits (mod);
+ int ret;
+ tlen = hash->mdlen + hash->asnlen;
+ emlen = (nbits + 7) / 8;
+ if (emlen < tlen + 11)
+ return GPG_ERR_TOO_SHORT;
+
+ em = grub_malloc (emlen);
+ if (!em)
+ return 1;
+
+ em[0] = 0x00;
+ em[1] = 0x01;
+ fflen = emlen - tlen - 3;
+ for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
+ *emptr = 0xff;
+ *emptr++ = 0x00;
+ grub_memcpy (emptr, hash->asnoid, hash->asnlen);
+ emptr += hash->asnlen;
+ grub_memcpy (emptr, hval, hash->mdlen);
+
+ ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
+ grub_free (em);
+ return ret;
+}
diff --git a/include/grub/pkcs1_v15.h b/include/grub/pkcs1_v15.h
new file mode 100644
index 00000000000..5c338c84a15
--- /dev/null
+++ b/include/grub/pkcs1_v15.h
@@ -0,0 +1,27 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 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/>.
+ */
+
+/*
+ * Given a hash value 'hval', of hash specification 'hash', perform
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
+ * (See RFC 8017 s 9.2)
+ */
+gcry_err_code_t
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
+ const gcry_md_spec_t * hash, gcry_mpi_t mod);
+

View File

@ -0,0 +1,71 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 2 Oct 2020 10:49:26 +1000
Subject: [PATCH] crypto: move storage for grub_crypto_pk_* to crypto.c
The way gcry_rsa and friends (the asymmetric ciphers) are loaded for the
pgp module is a bit quirky.
include/grub/crypto.h contains:
extern struct gcry_pk_spec *grub_crypto_pk_rsa;
commands/pgp.c contains the actual storage:
struct gcry_pk_spec *grub_crypto_pk_rsa;
And the module itself saves to the storage in pgp.c:
GRUB_MOD_INIT(gcry_rsa)
{
grub_crypto_pk_rsa = &_gcry_pubkey_spec_rsa;
}
This is annoying: gcry_rsa now has a dependency on pgp!
We want to be able to bring in gcry_rsa without bringing in PGP,
so move the storage to crypto.c.
Previously, gcry_rsa depended on pgp and mpi. Now it depends on
crypto and mpi. As pgp depends on crypto, this doesn't add any new
module dependencies using the PGP verfier.
[FWIW, the story is different for the symmetric ciphers. cryptodisk
and friends (zfs encryption etc) use grub_crypto_lookup_cipher_by_name()
to get a cipher handle. That depends on grub_ciphers being populated
by people calling grub_cipher_register. import_gcry.py ensures that the
symmetric ciphers call it.]
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/pgp.c | 4 ----
grub-core/lib/crypto.c | 4 ++++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index bb6543819f0..75de32c2a00 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -147,10 +147,6 @@ const char *hashes[] = {
[0x0b] = "sha224"
};
-struct gcry_pk_spec *grub_crypto_pk_dsa;
-struct gcry_pk_spec *grub_crypto_pk_ecdsa;
-struct gcry_pk_spec *grub_crypto_pk_rsa;
-
static int
dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
const gcry_md_spec_t *hash, struct grub_public_subkey *sk);
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
index e6c78d16d39..ff62fa30e1a 100644
--- a/grub-core/lib/crypto.c
+++ b/grub-core/lib/crypto.c
@@ -121,6 +121,10 @@ grub_md_unregister (gcry_md_spec_t *cipher)
}
}
+struct gcry_pk_spec *grub_crypto_pk_dsa;
+struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+struct gcry_pk_spec *grub_crypto_pk_rsa;
+
void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
grub_size_t inlen)

View File

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 2 May 2020 00:27:57 +1000
Subject: [PATCH] posix_wrap: tweaks in preparation for libtasn1
- Define SIZEOF_UNSIGNED_LONG_INT, it's the same as
SIZEOF_UNSIGNED_LONG.
- Define WORD_BIT, the size in bits of an int. This is a defined
in the Single Unix Specification and in gnulib's limits.h. gnulib
assumes it's 32 bits on all our platforms, including 64 bit
platforms, so we also use that value.
- Provide strto[u]l[l] preprocessor macros that resolve to
grub_strto[u]l[l]. To avoid gcrypt redefining strtoul, we
also define HAVE_STRTOUL here.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/lib/posix_wrap/limits.h | 1 +
grub-core/lib/posix_wrap/stdlib.h | 8 ++++++++
grub-core/lib/posix_wrap/sys/types.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h
index 95529540398..474a923b074 100644
--- a/grub-core/lib/posix_wrap/limits.h
+++ b/grub-core/lib/posix_wrap/limits.h
@@ -31,5 +31,6 @@
#define INT_MAX GRUB_INT_MAX
#define CHAR_BIT 8
+#define WORD_BIT 32
#endif
diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
index 7a8d385e973..4634db09f29 100644
--- a/grub-core/lib/posix_wrap/stdlib.h
+++ b/grub-core/lib/posix_wrap/stdlib.h
@@ -58,4 +58,12 @@ abs (int c)
return (c >= 0) ? c : -c;
}
+#define strtol grub_strtol
+
+/* for libgcrypt */
+#define HAVE_STRTOUL
+#define strtoul grub_strtoul
+
+#define strtoull grub_strtoull
+
#endif
diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h
index 854eb0122ef..f63412c8da0 100644
--- a/grub-core/lib/posix_wrap/sys/types.h
+++ b/grub-core/lib/posix_wrap/sys/types.h
@@ -51,6 +51,7 @@ typedef grub_uint8_t byte;
typedef grub_addr_t uintptr_t;
#define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG
+#define SIZEOF_UNSIGNED_LONG_INT GRUB_CPU_SIZEOF_LONG
#define SIZEOF_UNSIGNED_INT 4
#define SIZEOF_UNSIGNED_LONG_LONG 8
#define SIZEOF_UNSIGNED_SHORT 2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,307 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 1 May 2020 17:12:23 +1000
Subject: [PATCH] libtasn1: disable code not needed in grub
We don't expect to be able to write ASN.1, only read it,
so we can disable some code.
Do that with #if 0/#endif, rather than deletion. This means
that the difference between upstream and grub is smaller,
which should make updating libtasn1 easier in the future.
With these exclusions we also avoid the need for minmax.h,
which is convenient because it means we don't have to
import it from gnulib.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/lib/libtasn1/lib/coding.c | 12 ++++++++++--
grub-core/lib/libtasn1/lib/decoding.c | 2 ++
grub-core/lib/libtasn1/lib/element.c | 4 ++--
grub-core/lib/libtasn1/lib/errors.c | 3 +++
grub-core/lib/libtasn1/lib/structure.c | 10 ++++++----
include/grub/libtasn1.h | 15 +++++++++++++++
6 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c
index 245ea64cf0a..52def598368 100644
--- a/grub-core/lib/libtasn1/lib/coding.c
+++ b/grub-core/lib/libtasn1/lib/coding.c
@@ -30,11 +30,11 @@
#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
-#include "minmax.h"
#include <structure.h>
#define MAX_TAG_LEN 16
+#if 0
/******************************************************/
/* Function : _asn1_error_description_value_not_found */
/* Description: creates the ErrorDescription string */
@@ -58,6 +58,7 @@ _asn1_error_description_value_not_found (asn1_node node,
Estrcat (ErrorDescription, "' not found");
}
+#endif
/**
* asn1_length_der:
@@ -244,6 +245,7 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
return ASN1_SUCCESS;
}
+#if 0
/******************************************************/
/* Function : _asn1_time_der */
/* Description: creates the DER coding for a TIME */
@@ -281,7 +283,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
return ASN1_SUCCESS;
}
-
+#endif
/*
void
@@ -520,6 +522,7 @@ asn1_bit_der (const unsigned char *str, int bit_len,
}
+#if 0
/******************************************************/
/* Function : _asn1_complete_explicit_tag */
/* Description: add the length coding to the EXPLICIT */
@@ -596,6 +599,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
return ASN1_SUCCESS;
}
+#endif
const tag_and_class_st _asn1_tags[] = {
[ASN1_ETYPE_GENERALSTRING] =
@@ -648,6 +652,8 @@ const tag_and_class_st _asn1_tags[] = {
unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]);
+
+#if 0
/******************************************************/
/* Function : _asn1_insert_tag_der */
/* Description: creates the DER coding of tags of one */
@@ -1413,3 +1419,5 @@ error:
asn1_delete_structure (&node);
return err;
}
+
+#endif
\ No newline at end of file
diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c
index ff04eb778cb..42f9a92b5d4 100644
--- a/grub-core/lib/libtasn1/lib/decoding.c
+++ b/grub-core/lib/libtasn1/lib/decoding.c
@@ -1613,6 +1613,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription);
}
+#if 0
/**
* asn1_der_decoding_element:
* @structure: pointer to an ASN1 structure
@@ -1643,6 +1644,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName,
{
return asn1_der_decoding(structure, ider, len, errorDescription);
}
+#endif
/**
* asn1_der_decoding_startEnd:
diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c
index 997eb2725dc..539008d8e94 100644
--- a/grub-core/lib/libtasn1/lib/element.c
+++ b/grub-core/lib/libtasn1/lib/element.c
@@ -191,7 +191,7 @@ _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
return ASN1_SUCCESS;
}
-
+#if 0
/**
* asn1_write_value:
* @node_root: pointer to a structure
@@ -645,7 +645,7 @@ asn1_write_value (asn1_node node_root, const char *name,
return ASN1_SUCCESS;
}
-
+#endif
#define PUT_VALUE( ptr, ptr_size, data, data_size) \
*len = data_size; \
diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c
index cee74daf795..42785e8622b 100644
--- a/grub-core/lib/libtasn1/lib/errors.c
+++ b/grub-core/lib/libtasn1/lib/errors.c
@@ -57,6 +57,8 @@ static const libtasn1_error_entry error_algorithms[] = {
{0, 0}
};
+
+#if 0
/**
* asn1_perror:
* @error: is an error returned by a libtasn1 function.
@@ -73,6 +75,7 @@ asn1_perror (int error)
const char *str = asn1_strerror (error);
fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)");
}
+#endif
/**
* asn1_strerror:
diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c
index 8189c56a4c9..fcfde01a393 100644
--- a/grub-core/lib/libtasn1/lib/structure.c
+++ b/grub-core/lib/libtasn1/lib/structure.c
@@ -76,7 +76,7 @@ _asn1_find_left (asn1_node_const node)
return node->left;
}
-
+#if 0
int
_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name,
char *vector_name)
@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer, char *output_file_name,
return ASN1_SUCCESS;
}
-
+#endif
/**
* asn1_array2tree:
@@ -718,7 +718,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name,
return res;
}
-
+#if 0
/**
* asn1_print_structure:
* @out: pointer to the output file (e.g. stdout).
@@ -1058,7 +1058,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name,
}
}
}
-
+#endif
/**
@@ -1153,6 +1153,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue)
return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
}
+#if 0
/**
* asn1_copy_node:
* @dst: Destination asn1 node.
@@ -1202,6 +1203,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name,
return result;
}
+#endif
/**
* asn1_dup_node:
diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h
index 6fd7a30dc35..785eda2ae3f 100644
--- a/include/grub/libtasn1.h
+++ b/include/grub/libtasn1.h
@@ -319,6 +319,8 @@ typedef struct asn1_data_node_st asn1_data_node_st;
/* Functions definitions */
/***********************************/
+/* These functions are not used in grub and should not be referenced. */
+#if 0
extern ASN1_API int
asn1_parser2tree (const char *file,
asn1_node * definitions, char *error_desc);
@@ -327,14 +329,17 @@ extern ASN1_API int
asn1_parser2array (const char *inputFileName,
const char *outputFileName,
const char *vectorName, char *error_desc);
+#endif
extern ASN1_API int
asn1_array2tree (const asn1_static_node * array,
asn1_node * definitions, char *errorDescription);
+#if 0
extern ASN1_API void
asn1_print_structure (FILE * out, asn1_node_const structure,
const char *name, int mode);
+#endif
extern ASN1_API int
asn1_create_element (asn1_node_const definitions,
@@ -347,9 +352,11 @@ extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int
extern ASN1_API int
asn1_delete_element (asn1_node structure, const char *element_name);
+#if 0
extern ASN1_API int
asn1_write_value (asn1_node node_root, const char *name,
const void *ivalue, int len);
+#endif
extern ASN1_API int
asn1_read_value (asn1_node_const root, const char *name,
@@ -365,9 +372,11 @@ extern ASN1_API int
extern ASN1_API int
asn1_number_of_elements (asn1_node_const element, const char *name, int *num);
+#if 0
extern ASN1_API int
asn1_der_coding (asn1_node_const element, const char *name,
void *ider, int *len, char *ErrorDescription);
+#endif
extern ASN1_API int
asn1_der_decoding2 (asn1_node *element, const void *ider,
@@ -378,12 +387,14 @@ extern ASN1_API int
asn1_der_decoding (asn1_node * element, const void *ider,
int ider_len, char *errorDescription);
+#if 0
/* Do not use. Use asn1_der_decoding() instead. */
extern ASN1_API int
asn1_der_decoding_element (asn1_node * structure,
const char *elementName,
const void *ider, int len,
char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED;
+#endif
extern ASN1_API int
asn1_der_decoding_startEnd (asn1_node element,
@@ -408,13 +419,17 @@ extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const
const char
*oidValue);
+#if 0
__LIBTASN1_PURE__
extern ASN1_API const char *asn1_check_version (const char *req_version);
+#endif
__LIBTASN1_PURE__
extern ASN1_API const char *asn1_strerror (int error);
+#if 0
extern ASN1_API void asn1_perror (int error);
+#endif
#define ASN1_MAX_TAG_SIZE 4
#define ASN1_MAX_LENGTH_SIZE 9

View File

@ -0,0 +1,202 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 1 May 2020 20:44:29 +1000
Subject: [PATCH] libtasn1: changes for grub compatibility
Do a few things to make libtasn1 compile as part of grub:
- replace strcat. grub removed strcat so replace it with the appropriate
calls to memcpy and strlen.
- replace c_isdigit with grub_isdigit (and don't import c-ctype from
gnulib) grub_isdigit provides the same functionality as c_isdigit: it
determines if the input is an ASCII digit without regard for locale.
- replace GL_ATTRIBUTE_PURE with __attribute__((pure)) which been
supported since gcc-2.96. This avoids messing around with gnulib.
- adjust libtasn1.h: drop the ASN1_API logic, it's not needed for our
modules. Unconditionally support const and pure attributes and adjust
header paths.
- adjust header paths to "grub/libtasn1.h".
- replace a 64 bit division with a call to grub_divmod64, preventing
creation of __udivdi3 calls on 32 bit platforms.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/lib/libtasn1/lib/decoding.c | 11 ++++++-----
grub-core/lib/libtasn1/lib/element.c | 3 ++-
grub-core/lib/libtasn1/lib/gstr.c | 4 ++--
grub-core/lib/libtasn1/lib/parser_aux.c | 7 ++++---
grub-core/lib/libtasn1/lib/int.h | 4 ++--
include/grub/libtasn1.h | 26 ++++++--------------------
6 files changed, 22 insertions(+), 33 deletions(-)
diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c
index 42f9a92b5d4..7856858b272 100644
--- a/grub-core/lib/libtasn1/lib/decoding.c
+++ b/grub-core/lib/libtasn1/lib/decoding.c
@@ -32,7 +32,8 @@
#include <element.h>
#include <limits.h>
#include <intprops.h>
-#include <c-ctype.h>
+
+#define c_isdigit grub_isdigit
#ifdef DEBUG
# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
@@ -2008,8 +2009,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element,
(p2->type & CONST_ASSIGN))
{
strcpy (name, definitions->name);
- strcat (name, ".");
- strcat (name, p2->name);
+ memcpy (name + strlen(name), ".", sizeof(" . "));
+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1);
len = sizeof (value);
result = asn1_read_value (definitions, name, value, &len);
@@ -2026,8 +2027,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element,
if (p2)
{
strcpy (name, definitions->name);
- strcat (name, ".");
- strcat (name, p2->name);
+ memcpy (name + strlen(name), ".", sizeof(" . "));
+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1);
result = asn1_create_element (definitions, name, &aux);
if (result == ASN1_SUCCESS)
diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c
index 539008d8e94..ed761ff56bd 100644
--- a/grub-core/lib/libtasn1/lib/element.c
+++ b/grub-core/lib/libtasn1/lib/element.c
@@ -30,9 +30,10 @@
#include "parser_aux.h"
#include <gstr.h>
#include "structure.h"
-#include "c-ctype.h"
#include "element.h"
+#define c_isdigit grub_isdigit
+
void
_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size)
{
diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c
index e91a3a151c0..e33875c2c7c 100644
--- a/grub-core/lib/libtasn1/lib/gstr.c
+++ b/grub-core/lib/libtasn1/lib/gstr.c
@@ -36,13 +36,13 @@ _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
if (dest_tot_size - dest_size > str_size)
{
- strcat (dest, src);
+ memcpy (dest + dest_size, src, str_size + 1);
}
else
{
if (dest_tot_size - dest_size > 0)
{
- strncat (dest, src, (dest_tot_size - dest_size) - 1);
+ memcpy (dest + dest_size, src, (dest_tot_size - dest_size) - 1);
dest[dest_tot_size - 1] = 0;
}
}
diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c
index d5dbbf8765d..89c9be69dc2 100644
--- a/grub-core/lib/libtasn1/lib/parser_aux.c
+++ b/grub-core/lib/libtasn1/lib/parser_aux.c
@@ -26,7 +26,8 @@
#include "gstr.h"
#include "structure.h"
#include "element.h"
-#include "c-ctype.h"
+
+#define c_isdigit grub_isdigit
char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
@@ -40,7 +41,7 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou
#ifdef __clang__
__attribute__((no_sanitize("integer")))
#endif
-_GL_ATTRIBUTE_PURE
+__attribute__((__pure__))
static unsigned int
_asn1_hash_name (const char *x)
{
@@ -634,7 +635,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
count = 0;
do
{
- d = val / 10;
+ d = grub_divmod64(val, 10, NULL);
r = val - d * 10;
temp[start + count] = '0' + (char) r;
count++;
diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h
index ea1625786c1..4a568efee9c 100644
--- a/grub-core/lib/libtasn1/lib/int.h
+++ b/grub-core/lib/libtasn1/lib/int.h
@@ -35,7 +35,7 @@
#include <sys/types.h>
#endif
-#include <libtasn1.h>
+#include "grub/libtasn1.h"
#define ASN1_SMALL_VALUE_SIZE 16
@@ -115,7 +115,7 @@ extern const tag_and_class_st _asn1_tags[];
#define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b)
#define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b)
#define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b)
-#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b)
+#define _asn1_strcat(a,b) memcpy((char *)a + strlen((const char *)a), (const char *)b, strlen((const char *)b) + 1)
#if SIZEOF_UNSIGNED_LONG_INT == 8
# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b)
diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h
index 785eda2ae3f..28dbf16c4e0 100644
--- a/include/grub/libtasn1.h
+++ b/include/grub/libtasn1.h
@@ -38,29 +38,15 @@
#ifndef LIBTASN1_H
#define LIBTASN1_H
-#ifndef ASN1_API
-#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY
-#define ASN1_API __attribute__((__visibility__("default")))
-#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC
-#define ASN1_API __declspec(dllexport)
-#elif defined _MSC_VER && ! defined ASN1_STATIC
-#define ASN1_API __declspec(dllimport)
-#else
+/* grub: ASN1_API is not used */
#define ASN1_API
-#endif
-#endif
-#ifdef __GNUC__
-# define __LIBTASN1_CONST__ __attribute__((const))
-# define __LIBTASN1_PURE__ __attribute__((pure))
-#else
-# define __LIBTASN1_CONST__
-# define __LIBTASN1_PURE__
-#endif
+/* grub: all our supported compilers support these attributes */
+#define __LIBTASN1_CONST__ __attribute__((const))
+#define __LIBTASN1_PURE__ __attribute__((pure))
-#include <sys/types.h>
-#include <time.h>
-#include <stdio.h> /* for FILE* */
+#include <grub/types.h>
+#include <grub/time.h>
#ifdef __cplusplus
extern "C"

View File

@ -0,0 +1,70 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 5 Jun 2020 17:47:25 +1000
Subject: [PATCH] libtasn1: compile into asn1 module
Create a wrapper file that specifies the module license.
Set up the makefile so it is built.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 15 +++++++++++++++
grub-core/lib/libtasn1_wrap/wrap.c | 26 ++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 99615c07b94..c2d922e6d48 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2436,3 +2436,18 @@ module = {
common = loader/i386/xen_file64.c;
extra_dist = loader/i386/xen_fileXX.c;
};
+
+module = {
+ name = asn1;
+ common = lib/libtasn1/lib/decoding.c;
+ common = lib/libtasn1/lib/coding.c;
+ common = lib/libtasn1/lib/element.c;
+ common = lib/libtasn1/lib/structure.c;
+ common = lib/libtasn1/lib/parser_aux.c;
+ common = lib/libtasn1/lib/gstr.c;
+ common = lib/libtasn1/lib/errors.c;
+ common = lib/libtasn1_wrap/wrap.c;
+ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
+ // -Wno-type-limits comes from libtasn1's configure.ac
+ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits';
+};
diff --git a/grub-core/lib/libtasn1_wrap/wrap.c b/grub-core/lib/libtasn1_wrap/wrap.c
new file mode 100644
index 00000000000..622ba942e33
--- /dev/null
+++ b/grub-core/lib/libtasn1_wrap/wrap.c
@@ -0,0 +1,26 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020 IBM Corporation
+ *
+ * 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/>.
+ */
+
+#include <grub/dl.h>
+
+/*
+ * libtasn1 is provided under LGPL2.1+, which is compatible
+ * with GPL3+. As Grub as a whole is under GPL3+, this module
+ * is therefore under GPL3+ also.
+ */
+GRUB_MOD_LICENSE ("GPLv3+");

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,255 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alastair D'Silva <alastair@d-silva.org>
Date: Mon, 6 Jul 2020 13:33:04 +1000
Subject: [PATCH] grub-install: support embedding x509 certificates
To support verification of appended signatures, we need a way to
embed the necessary public keys. Existing appended signature schemes
in the Linux kernel use X.509 certificates, so allow certificates to
be embedded in the grub core image in the same way as PGP keys.
Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/pgp.c | 2 +-
util/grub-install-common.c | 23 ++++++++++++++++++++++-
util/grub-mkimage.c | 15 +++++++++++++--
util/mkimage.c | 41 ++++++++++++++++++++++++++++++++++++++---
include/grub/kernel.h | 3 ++-
include/grub/util/install.h | 7 +++++--
6 files changed, 81 insertions(+), 10 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 75de32c2a00..55d354be0ae 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp)
grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
/* Not an ELF module, skip. */
- if (header->type != OBJ_TYPE_PUBKEY)
+ if (header->type != OBJ_TYPE_GPG_PUBKEY)
continue;
pseudo_file.fs = &pseudo_fs;
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 561e671ff34..fa6b65347ea 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -302,6 +302,8 @@ handle_install_list (struct install_list *il, const char *val,
static char **pubkeys;
static size_t npubkeys;
+static char **x509keys;
+static size_t nx509keys;
static grub_compression_t compression;
static size_t appsig_size;
@@ -334,6 +336,12 @@ grub_install_parse (int key, char *arg)
* (npubkeys + 1));
pubkeys[npubkeys++] = xstrdup (arg);
return 1;
+ case 'x':
+ x509keys = xrealloc (x509keys,
+ sizeof (x509keys[0])
+ * (nx509keys + 1));
+ x509keys[nx509keys++] = xstrdup (arg);
+ return 1;
case GRUB_INSTALL_OPTIONS_VERBOSITY:
verbosity++;
@@ -460,6 +468,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
slen += 20 + grub_strlen (*pk);
+ for (pk = x509keys; pk < x509keys + nx509keys; pk++)
+ slen += 10 + grub_strlen (*pk);
+
for (md = modules.entries; *md; md++)
{
slen += 10 + grub_strlen (*md);
@@ -488,6 +499,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
*p++ = ' ';
}
+ for (pk = x509keys; pk < x509keys + nx509keys; pk++)
+ {
+ p = grub_stpcpy (p, "--x509 '");
+ p = grub_stpcpy (p, *pk);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+
for (md = modules.entries; *md; md++)
{
*p++ = '\'';
@@ -515,7 +534,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
grub_install_generate_image (dir, prefix, fp, outname,
modules.entries, memdisk_path,
- pubkeys, npubkeys, config_path, tgt,
+ pubkeys, npubkeys,
+ x509keys, nx509keys,
+ config_path, tgt,
note, appsig_size, compression, dtb);
while (dc--)
grub_install_pop_module ();
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index 65a015d8a04..394d2dc5fc9 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -75,7 +75,8 @@ static struct argp_option options[] = {
/* TRANSLATORS: "embed" is a verb (command description). "*/
{"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
/* TRANSLATORS: "embed" is a verb (command description). "*/
- {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
+ {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for PGP signature checking"), 0},
+ {"x509", 'x', N_("FILE"), 0, N_("embed FILE as an x509 certificate for appended signature checking"), 0},
/* TRANSLATORS: NOTE is a name of segment. */
{"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
@@ -122,6 +123,8 @@ struct arguments
char *dtb;
char **pubkeys;
size_t npubkeys;
+ char **x509keys;
+ size_t nx509keys;
char *font;
char *config;
int note;
@@ -202,6 +205,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
break;
+ case 'x':
+ arguments->x509keys = xrealloc (arguments->x509keys,
+ sizeof (arguments->x509keys[0])
+ * (arguments->nx509keys + 1));
+ arguments->x509keys[arguments->nx509keys++] = xstrdup (arg);
+ break;
+
case 'c':
if (arguments->config)
free (arguments->config);
@@ -317,7 +327,8 @@ main (int argc, char *argv[])
grub_install_generate_image (arguments.dir, arguments.prefix, fp,
arguments.output, arguments.modules,
arguments.memdisk, arguments.pubkeys,
- arguments.npubkeys, arguments.config,
+ arguments.npubkeys, arguments.x509keys,
+ arguments.nx509keys, arguments.config,
arguments.image_target, arguments.note,
arguments.appsig_size,
arguments.comp, arguments.dtb);
diff --git a/util/mkimage.c b/util/mkimage.c
index a81120f26be..2529de4bb78 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -774,8 +774,10 @@ grub_install_get_image_targets_string (void)
void
grub_install_generate_image (const char *dir, const char *prefix,
FILE *out, const char *outname, char *mods[],
- char *memdisk_path, char **pubkey_paths,
- size_t npubkeys, char *config_path,
+ char *memdisk_path,
+ char **pubkey_paths, size_t npubkeys,
+ char **x509key_paths, size_t nx509keys,
+ char *config_path,
const struct grub_install_image_target_desc *image_target,
int note, size_t appsig_size, grub_compression_t comp, const char *dtb_path)
{
@@ -819,6 +821,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
}
}
+ {
+ size_t i;
+ for (i = 0; i < nx509keys; i++)
+ {
+ size_t curs;
+ curs = ALIGN_ADDR (grub_util_get_image_size (x509key_paths[i]));
+ grub_util_info ("the size of x509 public key %u is 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned) i, (unsigned long long) curs);
+ total_module_size += curs + sizeof (struct grub_module_header);
+ }
+ }
+
if (memdisk_path)
{
memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
@@ -933,7 +948,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
curs = grub_util_get_image_size (pubkey_paths[i]);
header = (struct grub_module_header *) (kernel_img + offset);
- header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
+ header->type = grub_host_to_target32 (OBJ_TYPE_GPG_PUBKEY);
header->size = grub_host_to_target32 (curs + sizeof (*header));
offset += sizeof (*header);
@@ -942,6 +957,26 @@ grub_install_generate_image (const char *dir, const char *prefix,
}
}
+ {
+ size_t i;
+ for (i = 0; i < nx509keys; i++)
+ {
+ size_t curs;
+ struct grub_module_header *header;
+
+ curs = grub_util_get_image_size (x509key_paths[i]);
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_X509_PUBKEY);
+ header->size = grub_host_to_target32 (curs + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (x509key_paths[i], kernel_img + offset);
+ offset += ALIGN_ADDR (curs);
+ }
+ }
+
+
if (memdisk_path)
{
struct grub_module_header *header;
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index 9548d552aad..75a057d4666 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -28,7 +28,8 @@ enum
OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG,
OBJ_TYPE_PREFIX,
- OBJ_TYPE_PUBKEY,
+ OBJ_TYPE_GPG_PUBKEY,
+ OBJ_TYPE_X509_PUBKEY,
OBJ_TYPE_DTB
};
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index ba5e6a2ea8f..95059285bd4 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -63,6 +63,8 @@
/* TRANSLATORS: "embed" is a verb (command description). "*/ \
{ "pubkey", 'k', N_("FILE"), 0, \
N_("embed FILE as public key for signature checking"), 0}, \
+ { "x509key", 'x', N_("FILE"), 0, \
+ N_("embed FILE as an x509 certificate for signature checking"), 0}, \
{ "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
"SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
1}, \
@@ -179,8 +181,9 @@ void
grub_install_generate_image (const char *dir, const char *prefix,
FILE *out,
const char *outname, char *mods[],
- char *memdisk_path, char **pubkey_paths,
- size_t npubkeys,
+ char *memdisk_path,
+ char **pubkey_paths, size_t npubkeys,
+ char **x509key_paths, size_t nx509keys,
char *config_path,
const struct grub_install_image_target_desc *image_target,
int note, size_t appsig_size,

View File

@ -0,0 +1,639 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 01:35:10 +1000
Subject: [PATCH] appended signatures: import GNUTLS's ASN.1 description files
In order to parse PKCS#7 messages and X.509 certificates with libtasn1,
we need some information about how they are encoded.
We get these from GNUTLS, which has the benefit that they support the
features we need and are well tested.
The GNUTLS license is LGPLv2.1+, which is GPLv3 compatible, allowing
us to import it without issue.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/appendedsig/gnutls_asn1_tab.c | 121 ++++++
grub-core/commands/appendedsig/pkix_asn1_tab.c | 484 +++++++++++++++++++++++
2 files changed, 605 insertions(+)
create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c
create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c
diff --git a/grub-core/commands/appendedsig/gnutls_asn1_tab.c b/grub-core/commands/appendedsig/gnutls_asn1_tab.c
new file mode 100644
index 00000000000..ddd1314e63b
--- /dev/null
+++ b/grub-core/commands/appendedsig/gnutls_asn1_tab.c
@@ -0,0 +1,121 @@
+#include <grub/mm.h>
+#include <grub/libtasn1.h>
+
+const asn1_static_node gnutls_asn1_tab[] = {
+ { "GNUTLS", 536872976, NULL },
+ { NULL, 1073741836, NULL },
+ { "RSAPublicKey", 1610612741, NULL },
+ { "modulus", 1073741827, NULL },
+ { "publicExponent", 3, NULL },
+ { "RSAPrivateKey", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "modulus", 1073741827, NULL },
+ { "publicExponent", 1073741827, NULL },
+ { "privateExponent", 1073741827, NULL },
+ { "prime1", 1073741827, NULL },
+ { "prime2", 1073741827, NULL },
+ { "exponent1", 1073741827, NULL },
+ { "exponent2", 1073741827, NULL },
+ { "coefficient", 1073741827, NULL },
+ { "otherPrimeInfos", 16386, "OtherPrimeInfos"},
+ { "ProvableSeed", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "seed", 7, NULL },
+ { "OtherPrimeInfos", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "OtherPrimeInfo"},
+ { "OtherPrimeInfo", 1610612741, NULL },
+ { "prime", 1073741827, NULL },
+ { "exponent", 1073741827, NULL },
+ { "coefficient", 3, NULL },
+ { "AlgorithmIdentifier", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "parameters", 541081613, NULL },
+ { "algorithm", 1, NULL },
+ { "DigestInfo", 1610612741, NULL },
+ { "digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"},
+ { "digest", 7, NULL },
+ { "DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
+ { "DSAPublicKey", 1073741827, NULL },
+ { "DSAParameters", 1610612741, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 3, NULL },
+ { "DSASignatureValue", 1610612741, NULL },
+ { "r", 1073741827, NULL },
+ { "s", 3, NULL },
+ { "DSAPrivateKey", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 1073741827, NULL },
+ { "Y", 1073741827, NULL },
+ { "priv", 3, NULL },
+ { "DHParameter", 1610612741, NULL },
+ { "prime", 1073741827, NULL },
+ { "base", 1073741827, NULL },
+ { "privateValueLength", 16387, NULL },
+ { "ECParameters", 1610612754, NULL },
+ { "namedCurve", 12, NULL },
+ { "ECPrivateKey", 1610612741, NULL },
+ { "Version", 1073741827, NULL },
+ { "privateKey", 1073741831, NULL },
+ { "parameters", 1610637314, "ECParameters"},
+ { NULL, 2056, "0"},
+ { "publicKey", 536895494, NULL },
+ { NULL, 2056, "1"},
+ { "PrincipalName", 1610612741, NULL },
+ { "name-type", 1610620931, NULL },
+ { NULL, 2056, "0"},
+ { "name-string", 536879115, NULL },
+ { NULL, 1073743880, "1"},
+ { NULL, 27, NULL },
+ { "KRB5PrincipalName", 1610612741, NULL },
+ { "realm", 1610620955, NULL },
+ { NULL, 2056, "0"},
+ { "principalName", 536879106, "PrincipalName"},
+ { NULL, 2056, "1"},
+ { "RSAPSSParameters", 1610612741, NULL },
+ { "hashAlgorithm", 1610637314, "AlgorithmIdentifier"},
+ { NULL, 2056, "0"},
+ { "maskGenAlgorithm", 1610637314, "AlgorithmIdentifier"},
+ { NULL, 2056, "1"},
+ { "saltLength", 1610653699, NULL },
+ { NULL, 1073741833, "20"},
+ { NULL, 2056, "2"},
+ { "trailerField", 536911875, NULL },
+ { NULL, 1073741833, "1"},
+ { NULL, 2056, "3"},
+ { "GOSTParameters", 1610612741, NULL },
+ { "publicKeyParamSet", 1073741836, NULL },
+ { "digestParamSet", 16396, NULL },
+ { "GOSTParametersOld", 1610612741, NULL },
+ { "publicKeyParamSet", 1073741836, NULL },
+ { "digestParamSet", 1073741836, NULL },
+ { "encryptionParamSet", 16396, NULL },
+ { "GOSTPrivateKey", 1073741831, NULL },
+ { "GOSTPrivateKeyOld", 1073741827, NULL },
+ { "IssuerSignTool", 1610612741, NULL },
+ { "signTool", 1073741858, NULL },
+ { "cATool", 1073741858, NULL },
+ { "signToolCert", 1073741858, NULL },
+ { "cAToolCert", 34, NULL },
+ { "Gost28147-89-EncryptedKey", 1610612741, NULL },
+ { "encryptedKey", 1073741831, NULL },
+ { "maskKey", 1610637319, NULL },
+ { NULL, 4104, "0"},
+ { "macKey", 7, NULL },
+ { "SubjectPublicKeyInfo", 1610612741, NULL },
+ { "algorithm", 1073741826, "AlgorithmIdentifier"},
+ { "subjectPublicKey", 6, NULL },
+ { "GostR3410-TransportParameters", 1610612741, NULL },
+ { "encryptionParamSet", 1073741836, NULL },
+ { "ephemeralPublicKey", 1610637314, "SubjectPublicKeyInfo"},
+ { NULL, 4104, "0"},
+ { "ukm", 7, NULL },
+ { "GostR3410-KeyTransport", 536870917, NULL },
+ { "sessionEncryptedKey", 1073741826, "Gost28147-89-EncryptedKey"},
+ { "transportParameters", 536895490, "GostR3410-TransportParameters"},
+ { NULL, 4104, "0"},
+ { NULL, 0, NULL }
+};
diff --git a/grub-core/commands/appendedsig/pkix_asn1_tab.c b/grub-core/commands/appendedsig/pkix_asn1_tab.c
new file mode 100644
index 00000000000..adef69d95ce
--- /dev/null
+++ b/grub-core/commands/appendedsig/pkix_asn1_tab.c
@@ -0,0 +1,484 @@
+#include <grub/mm.h>
+#include <grub/libtasn1.h>
+
+const asn1_static_node pkix_asn1_tab[] = {
+ { "PKIX1", 536875024, NULL },
+ { NULL, 1073741836, NULL },
+ { "PrivateKeyUsagePeriod", 1610612741, NULL },
+ { "notBefore", 1610637349, NULL },
+ { NULL, 4104, "0"},
+ { "notAfter", 536895525, NULL },
+ { NULL, 4104, "1"},
+ { "AuthorityKeyIdentifier", 1610612741, NULL },
+ { "keyIdentifier", 1610637319, NULL },
+ { NULL, 4104, "0"},
+ { "authorityCertIssuer", 1610637314, "GeneralNames"},
+ { NULL, 4104, "1"},
+ { "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
+ { NULL, 4104, "2"},
+ { "SubjectKeyIdentifier", 1073741831, NULL },
+ { "KeyUsage", 1073741830, NULL },
+ { "DirectoryString", 1610612754, NULL },
+ { "teletexString", 1612709918, NULL },
+ { "MAX", 524298, "1"},
+ { "printableString", 1612709919, NULL },
+ { "MAX", 524298, "1"},
+ { "universalString", 1612709920, NULL },
+ { "MAX", 524298, "1"},
+ { "utf8String", 1612709922, NULL },
+ { "MAX", 524298, "1"},
+ { "bmpString", 1612709921, NULL },
+ { "MAX", 524298, "1"},
+ { "ia5String", 538968093, NULL },
+ { "MAX", 524298, "1"},
+ { "SubjectAltName", 1073741826, "GeneralNames"},
+ { "GeneralNames", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "GeneralName"},
+ { "GeneralName", 1610612754, NULL },
+ { "otherName", 1610620930, "AnotherName"},
+ { NULL, 4104, "0"},
+ { "rfc822Name", 1610620957, NULL },
+ { NULL, 4104, "1"},
+ { "dNSName", 1610620957, NULL },
+ { NULL, 4104, "2"},
+ { "x400Address", 1610620941, NULL },
+ { NULL, 4104, "3"},
+ { "directoryName", 1610620939, NULL },
+ { NULL, 1073743880, "4"},
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "ediPartyName", 1610620941, NULL },
+ { NULL, 4104, "5"},
+ { "uniformResourceIdentifier", 1610620957, NULL },
+ { NULL, 4104, "6"},
+ { "iPAddress", 1610620935, NULL },
+ { NULL, 4104, "7"},
+ { "registeredID", 536879116, NULL },
+ { NULL, 4104, "8"},
+ { "AnotherName", 1610612741, NULL },
+ { "type-id", 1073741836, NULL },
+ { "value", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "type-id", 1, NULL },
+ { "IssuerAltName", 1073741826, "GeneralNames"},
+ { "BasicConstraints", 1610612741, NULL },
+ { "cA", 1610645508, NULL },
+ { NULL, 131081, NULL },
+ { "pathLenConstraint", 537411587, NULL },
+ { "0", 10, "MAX"},
+ { "CRLDistributionPoints", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "DistributionPoint"},
+ { "DistributionPoint", 1610612741, NULL },
+ { "distributionPoint", 1610637314, "DistributionPointName"},
+ { NULL, 2056, "0"},
+ { "reasons", 1610637314, "ReasonFlags"},
+ { NULL, 4104, "1"},
+ { "cRLIssuer", 536895490, "GeneralNames"},
+ { NULL, 4104, "2"},
+ { "DistributionPointName", 1610612754, NULL },
+ { "fullName", 1610620930, "GeneralNames"},
+ { NULL, 4104, "0"},
+ { "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
+ { NULL, 4104, "1"},
+ { "ReasonFlags", 1073741830, NULL },
+ { "ExtKeyUsageSyntax", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 12, NULL },
+ { "AuthorityInfoAccessSyntax", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "AccessDescription"},
+ { "AccessDescription", 1610612741, NULL },
+ { "accessMethod", 1073741836, NULL },
+ { "accessLocation", 2, "GeneralName"},
+ { "Attribute", 1610612741, NULL },
+ { "type", 1073741836, NULL },
+ { "values", 536870927, NULL },
+ { NULL, 13, NULL },
+ { "AttributeTypeAndValue", 1610612741, NULL },
+ { "type", 1073741836, NULL },
+ { "value", 13, NULL },
+ { "Name", 1610612754, NULL },
+ { "rdnSequence", 536870923, NULL },
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "DistinguishedName", 1610612747, NULL },
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "RelativeDistinguishedName", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "AttributeTypeAndValue"},
+ { "Certificate", 1610612741, NULL },
+ { "tbsCertificate", 1073741826, "TBSCertificate"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "TBSCertificate", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "serialNumber", 1073741826, "CertificateSerialNumber"},
+ { "signature", 1073741826, "AlgorithmIdentifier"},
+ { "issuer", 1073741826, "Name"},
+ { "validity", 1073741826, "Validity"},
+ { "subject", 1073741826, "Name"},
+ { "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
+ { "issuerUniqueID", 1610637314, "UniqueIdentifier"},
+ { NULL, 4104, "1"},
+ { "subjectUniqueID", 1610637314, "UniqueIdentifier"},
+ { NULL, 4104, "2"},
+ { "extensions", 536895490, "Extensions"},
+ { NULL, 2056, "3"},
+ { "CertificateSerialNumber", 1073741827, NULL },
+ { "Validity", 1610612741, NULL },
+ { "notBefore", 1073741826, "Time"},
+ { "notAfter", 2, "Time"},
+ { "Time", 1610612754, NULL },
+ { "utcTime", 1073741860, NULL },
+ { "generalTime", 37, NULL },
+ { "UniqueIdentifier", 1073741830, NULL },
+ { "SubjectPublicKeyInfo", 1610612741, NULL },
+ { "algorithm", 1073741826, "AlgorithmIdentifier"},
+ { "subjectPublicKey", 6, NULL },
+ { "Extensions", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Extension"},
+ { "Extension", 1610612741, NULL },
+ { "extnID", 1073741836, NULL },
+ { "critical", 1610645508, NULL },
+ { NULL, 131081, NULL },
+ { "extnValue", 7, NULL },
+ { "CertificateList", 1610612741, NULL },
+ { "tbsCertList", 1073741826, "TBSCertList"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "TBSCertList", 1610612741, NULL },
+ { "version", 1073758211, NULL },
+ { "signature", 1073741826, "AlgorithmIdentifier"},
+ { "issuer", 1073741826, "Name"},
+ { "thisUpdate", 1073741826, "Time"},
+ { "nextUpdate", 1073758210, "Time"},
+ { "revokedCertificates", 1610629131, NULL },
+ { NULL, 536870917, NULL },
+ { "userCertificate", 1073741826, "CertificateSerialNumber"},
+ { "revocationDate", 1073741826, "Time"},
+ { "crlEntryExtensions", 16386, "Extensions"},
+ { "crlExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "0"},
+ { "AlgorithmIdentifier", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "parameters", 541081613, NULL },
+ { "algorithm", 1, NULL },
+ { "Dss-Sig-Value", 1610612741, NULL },
+ { "r", 1073741827, NULL },
+ { "s", 3, NULL },
+ { "Dss-Parms", 1610612741, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 3, NULL },
+ { "pkcs-7-ContentInfo", 1610612741, NULL },
+ { "contentType", 1073741836, NULL },
+ { "content", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "contentType", 1, NULL },
+ { "pkcs-7-DigestInfo", 1610612741, NULL },
+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "digest", 7, NULL },
+ { "pkcs-7-SignedData", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
+ { "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
+ { "certificates", 1610637314, "pkcs-7-CertificateSet"},
+ { NULL, 4104, "0"},
+ { "crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
+ { NULL, 4104, "1"},
+ { "signerInfos", 2, "pkcs-7-SignerInfos"},
+ { "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL },
+ { NULL, 2, "AlgorithmIdentifier"},
+ { "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL },
+ { "eContentType", 1073741836, NULL },
+ { "eContent", 536895501, NULL },
+ { NULL, 2056, "0"},
+ { "pkcs-7-CertificateRevocationLists", 1610612751, NULL },
+ { NULL, 13, NULL },
+ { "pkcs-7-CertificateChoices", 1610612754, NULL },
+ { "certificate", 13, NULL },
+ { "pkcs-7-CertificateSet", 1610612751, NULL },
+ { NULL, 2, "pkcs-7-CertificateChoices"},
+ { "IssuerAndSerialNumber", 1610612741, NULL },
+ { "issuer", 1073741826, "Name"},
+ { "serialNumber", 2, "CertificateSerialNumber"},
+ { "pkcs-7-SignerInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "sid", 1073741826, "SignerIdentifier"},
+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signedAttrs", 1610637314, "SignedAttributes"},
+ { NULL, 4104, "0"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741831, NULL },
+ { "unsignedAttrs", 536895490, "SignedAttributes"},
+ { NULL, 4104, "1"},
+ { "SignedAttributes", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Attribute"},
+ { "SignerIdentifier", 1610612754, NULL },
+ { "issuerAndSerialNumber", 1073741826, "IssuerAndSerialNumber"},
+ { "subjectKeyIdentifier", 536879111, NULL },
+ { NULL, 4104, "0"},
+ { "pkcs-7-SignerInfos", 1610612751, NULL },
+ { NULL, 2, "pkcs-7-SignerInfo"},
+ { "pkcs-10-CertificationRequestInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "subject", 1073741826, "Name"},
+ { "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
+ { "attributes", 536879106, "Attributes"},
+ { NULL, 4104, "0"},
+ { "Attributes", 1610612751, NULL },
+ { NULL, 2, "Attribute"},
+ { "pkcs-10-CertificationRequest", 1610612741, NULL },
+ { "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "pkcs-9-at-challengePassword", 1879048204, NULL },
+ { "iso", 1073741825, "1"},
+ { "member-body", 1073741825, "2"},
+ { "us", 1073741825, "840"},
+ { "rsadsi", 1073741825, "113549"},
+ { "pkcs", 1073741825, "1"},
+ { NULL, 1073741825, "9"},
+ { NULL, 1, "7"},
+ { "pkcs-9-challengePassword", 1610612754, NULL },
+ { "printableString", 1073741855, NULL },
+ { "utf8String", 34, NULL },
+ { "pkcs-9-localKeyId", 1073741831, NULL },
+ { "pkcs-8-PrivateKeyInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "privateKey", 1073741831, NULL },
+ { "attributes", 536895490, "Attributes"},
+ { NULL, 4104, "0"},
+ { "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL },
+ { "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "encryptedData", 2, "pkcs-8-EncryptedData"},
+ { "pkcs-8-EncryptedData", 1073741831, NULL },
+ { "pkcs-5-des-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "8"},
+ { "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "8"},
+ { "pkcs-5-aes128-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "pkcs-5-aes192-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "pkcs-5-aes256-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "Gost28147-89-Parameters", 1610612741, NULL },
+ { "iv", 1073741831, NULL },
+ { "encryptionParamSet", 12, NULL },
+ { "pkcs-5-PBE-params", 1610612741, NULL },
+ { "salt", 1073741831, NULL },
+ { "iterationCount", 3, NULL },
+ { "pkcs-5-PBES2-params", 1610612741, NULL },
+ { "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
+ { "encryptionScheme", 2, "AlgorithmIdentifier"},
+ { "pkcs-5-PBKDF2-params", 1610612741, NULL },
+ { "salt", 1610612754, NULL },
+ { "specified", 1073741831, NULL },
+ { "otherSource", 2, "AlgorithmIdentifier"},
+ { "iterationCount", 1611137027, NULL },
+ { "1", 10, "MAX"},
+ { "keyLength", 1611153411, NULL },
+ { "1", 10, "MAX"},
+ { "prf", 16386, "AlgorithmIdentifier"},
+ { "pkcs-12-PFX", 1610612741, NULL },
+ { "version", 1610874883, NULL },
+ { "v3", 1, "3"},
+ { "authSafe", 1073741826, "pkcs-7-ContentInfo"},
+ { "macData", 16386, "pkcs-12-MacData"},
+ { "pkcs-12-PbeParams", 1610612741, NULL },
+ { "salt", 1073741831, NULL },
+ { "iterations", 3, NULL },
+ { "pkcs-12-MacData", 1610612741, NULL },
+ { "mac", 1073741826, "pkcs-7-DigestInfo"},
+ { "macSalt", 1073741831, NULL },
+ { "iterations", 536903683, NULL },
+ { NULL, 9, "1"},
+ { "pkcs-12-AuthenticatedSafe", 1610612747, NULL },
+ { NULL, 2, "pkcs-7-ContentInfo"},
+ { "pkcs-12-SafeContents", 1610612747, NULL },
+ { NULL, 2, "pkcs-12-SafeBag"},
+ { "pkcs-12-SafeBag", 1610612741, NULL },
+ { "bagId", 1073741836, NULL },
+ { "bagValue", 1614815245, NULL },
+ { NULL, 1073743880, "0"},
+ { "badId", 1, NULL },
+ { "bagAttributes", 536887311, NULL },
+ { NULL, 2, "Attribute"},
+ { "pkcs-12-CertBag", 1610612741, NULL },
+ { "certId", 1073741836, NULL },
+ { "certValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "certId", 1, NULL },
+ { "pkcs-12-CRLBag", 1610612741, NULL },
+ { "crlId", 1073741836, NULL },
+ { "crlValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "crlId", 1, NULL },
+ { "pkcs-12-SecretBag", 1610612741, NULL },
+ { "secretTypeId", 1073741836, NULL },
+ { "secretValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "secretTypeId", 1, NULL },
+ { "pkcs-7-Data", 1073741831, NULL },
+ { "pkcs-7-EncryptedData", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
+ { "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
+ { NULL, 4104, "1"},
+ { "pkcs-7-EncryptedContentInfo", 1610612741, NULL },
+ { "contentType", 1073741836, NULL },
+ { "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
+ { "encryptedContent", 536895495, NULL },
+ { NULL, 4104, "0"},
+ { "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
+ { "pkcs-7-UnprotectedAttributes", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Attribute"},
+ { "ProxyCertInfo", 1610612741, NULL },
+ { "pCPathLenConstraint", 1611153411, NULL },
+ { "0", 10, "MAX"},
+ { "proxyPolicy", 2, "ProxyPolicy"},
+ { "ProxyPolicy", 1610612741, NULL },
+ { "policyLanguage", 1073741836, NULL },
+ { "policy", 16391, NULL },
+ { "certificatePolicies", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "PolicyInformation"},
+ { "PolicyInformation", 1610612741, NULL },
+ { "policyIdentifier", 1073741836, NULL },
+ { "policyQualifiers", 538984459, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "PolicyQualifierInfo"},
+ { "PolicyQualifierInfo", 1610612741, NULL },
+ { "policyQualifierId", 1073741836, NULL },
+ { "qualifier", 541065229, NULL },
+ { "policyQualifierId", 1, NULL },
+ { "CPSuri", 1073741853, NULL },
+ { "UserNotice", 1610612741, NULL },
+ { "noticeRef", 1073758210, "NoticeReference"},
+ { "explicitText", 16386, "DisplayText"},
+ { "NoticeReference", 1610612741, NULL },
+ { "organization", 1073741826, "DisplayText"},
+ { "noticeNumbers", 536870923, NULL },
+ { NULL, 3, NULL },
+ { "DisplayText", 1610612754, NULL },
+ { "ia5String", 1612709917, NULL },
+ { "200", 524298, "1"},
+ { "visibleString", 1612709923, NULL },
+ { "200", 524298, "1"},
+ { "bmpString", 1612709921, NULL },
+ { "200", 524298, "1"},
+ { "utf8String", 538968098, NULL },
+ { "200", 524298, "1"},
+ { "OCSPRequest", 1610612741, NULL },
+ { "tbsRequest", 1073741826, "TBSRequest"},
+ { "optionalSignature", 536895490, "Signature"},
+ { NULL, 2056, "0"},
+ { "TBSRequest", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "requestorName", 1610637314, "GeneralName"},
+ { NULL, 2056, "1"},
+ { "requestList", 1610612747, NULL },
+ { NULL, 2, "Request"},
+ { "requestExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "2"},
+ { "Signature", 1610612741, NULL },
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741830, NULL },
+ { "certs", 536895499, NULL },
+ { NULL, 1073743880, "0"},
+ { NULL, 2, "Certificate"},
+ { "Request", 1610612741, NULL },
+ { "reqCert", 1073741826, "CertID"},
+ { "singleRequestExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "0"},
+ { "CertID", 1610612741, NULL },
+ { "hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "issuerNameHash", 1073741831, NULL },
+ { "issuerKeyHash", 1073741831, NULL },
+ { "serialNumber", 2, "CertificateSerialNumber"},
+ { "OCSPResponse", 1610612741, NULL },
+ { "responseStatus", 1073741826, "OCSPResponseStatus"},
+ { "responseBytes", 536895490, "ResponseBytes"},
+ { NULL, 2056, "0"},
+ { "OCSPResponseStatus", 1610874901, NULL },
+ { "successful", 1073741825, "0"},
+ { "malformedRequest", 1073741825, "1"},
+ { "internalError", 1073741825, "2"},
+ { "tryLater", 1073741825, "3"},
+ { "sigRequired", 1073741825, "5"},
+ { "unauthorized", 1, "6"},
+ { "ResponseBytes", 1610612741, NULL },
+ { "responseType", 1073741836, NULL },
+ { "response", 7, NULL },
+ { "BasicOCSPResponse", 1610612741, NULL },
+ { "tbsResponseData", 1073741826, "ResponseData"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741830, NULL },
+ { "certs", 536895499, NULL },
+ { NULL, 1073743880, "0"},
+ { NULL, 2, "Certificate"},
+ { "ResponseData", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "responderID", 1073741826, "ResponderID"},
+ { "producedAt", 1073741861, NULL },
+ { "responses", 1610612747, NULL },
+ { NULL, 2, "SingleResponse"},
+ { "responseExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "1"},
+ { "ResponderID", 1610612754, NULL },
+ { "byName", 1610620939, NULL },
+ { NULL, 1073743880, "1"},
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "byKey", 536879111, NULL },
+ { NULL, 2056, "2"},
+ { "SingleResponse", 1610612741, NULL },
+ { "certID", 1073741826, "CertID"},
+ { "certStatus", 1073741826, "CertStatus"},
+ { "thisUpdate", 1073741861, NULL },
+ { "nextUpdate", 1610637349, NULL },
+ { NULL, 2056, "0"},
+ { "singleExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "1"},
+ { "CertStatus", 1610612754, NULL },
+ { "good", 1610620948, NULL },
+ { NULL, 4104, "0"},
+ { "revoked", 1610620930, "RevokedInfo"},
+ { NULL, 4104, "1"},
+ { "unknown", 536879106, "UnknownInfo"},
+ { NULL, 4104, "2"},
+ { "RevokedInfo", 1610612741, NULL },
+ { "revocationTime", 1073741861, NULL },
+ { "revocationReason", 537157653, NULL },
+ { NULL, 1073743880, "0"},
+ { "unspecified", 1, "0"},
+ { "UnknownInfo", 1073741844, NULL },
+ { "NameConstraints", 1610612741, NULL },
+ { "permittedSubtrees", 1610637314, "GeneralSubtrees"},
+ { NULL, 4104, "0"},
+ { "excludedSubtrees", 536895490, "GeneralSubtrees"},
+ { NULL, 4104, "1"},
+ { "GeneralSubtrees", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "GeneralSubtree"},
+ { "GeneralSubtree", 1610612741, NULL },
+ { "base", 1073741826, "GeneralName"},
+ { "minimum", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 4104, "0"},
+ { "maximum", 536895491, NULL },
+ { NULL, 4104, "1"},
+ { "TlsFeatures", 536870923, NULL },
+ { NULL, 3, NULL },
+ { NULL, 0, NULL }
+};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,719 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 01:35:43 +1000
Subject: [PATCH] appended signatures: support verifying appended signatures
Building on the parsers and the ability to embed x509 certificates, as
well as the existing gcrypt functionality, add a module for verifying
appended signatures.
This includes:
- a verifier that requires that kernels and grub modules have appended
signatures. It shares lots of logic with shim-lock verifier about what
files need to be verified and what modules are unsafe to have loaded.
- commands to manage the list of trusted certificates for verification.
Similar to the PGP verifier, if a certificate is embedded in the core
image, verification will be enforced unless disabled on the the grub
command line or by load_env.
Thus, as with the PGP verifier, it is not a complete secure-boot solution:
other mechanisms must be used to ensure that a user cannot drop to the
grub shell and disable verification.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 12 +
grub-core/commands/appendedsig/appendedsig.c | 644 +++++++++++++++++++++++++++
include/grub/file.h | 2 +
3 files changed, 658 insertions(+)
create mode 100644 grub-core/commands/appendedsig/appendedsig.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index fd1229c6328..1cf6b60f82e 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -921,6 +921,18 @@ module = {
cppflags = '-I$(srcdir)/lib/posix_wrap';
};
+module = {
+ name = appendedsig;
+ common = commands/appendedsig/appendedsig.c;
+ common = commands/appendedsig/x509.c;
+ common = commands/appendedsig/pkcs7.c;
+ common = commands/appendedsig/asn1util.c;
+ common = commands/appendedsig/gnutls_asn1_tab.c;
+ common = commands/appendedsig/pkix_asn1_tab.c;
+ cflags = '$(CFLAGS_POSIX)';
+ cppflags = '-I$(srcdir)/lib/posix_wrap';
+};
+
module = {
name = verifiers;
common = commands/verifiers.c;
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
new file mode 100644
index 00000000000..5d8897be5c8
--- /dev/null
+++ b/grub-core/commands/appendedsig/appendedsig.c
@@ -0,0 +1,644 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020 IBM Corporation.
+ *
+ * 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/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/command.h>
+#include <grub/crypto.h>
+#include <grub/pkcs1_v15.h>
+#include <grub/i18n.h>
+#include <grub/gcrypt/gcrypt.h>
+#include <grub/kernel.h>
+#include <grub/extcmd.h>
+#include <grub/verify.h>
+#include <grub/libtasn1.h>
+#include <grub/env.h>
+
+#include "appendedsig.h"
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+const char magic[] = "~Module signature appended~\n";
+
+/*
+ * This structure is extracted from scripts/sign-file.c in the linux kernel
+ * source. It was licensed as LGPLv2.1+, which is GPLv3+ compatible.
+ */
+struct module_signature
+{
+ grub_uint8_t algo; /* Public-key crypto algorithm [0] */
+ grub_uint8_t hash; /* Digest algorithm [0] */
+ grub_uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */
+ grub_uint8_t signer_len; /* Length of signer's name [0] */
+ grub_uint8_t key_id_len; /* Length of key identifier [0] */
+ grub_uint8_t __pad[3];
+ grub_uint32_t sig_len; /* Length of signature data */
+} GRUB_PACKED;
+
+
+/* This represents an entire, parsed, appended signature */
+struct grub_appended_signature
+{
+ grub_size_t signature_len; /* Length of PKCS#7 data +
+ * metadata + magic */
+
+ struct module_signature sig_metadata; /* Module signature metadata */
+ struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
+};
+
+/* Trusted certificates for verifying appended signatures */
+struct x509_certificate *grub_trusted_key;
+
+/*
+ * Force gcry_rsa to be a module dependency.
+ *
+ * If we use grub_crypto_pk_rsa, then then the gcry_rsa module won't be built
+ * in if you add 'appendedsig' to grub-install --modules. You would need to
+ * add 'gcry_rsa' too. That's confusing and seems suboptimal, especially when
+ * we only support RSA.
+ *
+ * Dynamic loading also causes some concerns. We can't load gcry_rsa from the
+ * the filesystem after we install the verifier - we won't be able to verify
+ * it without having it already present. We also shouldn't load it before we
+ * install the verifier, because that would mean it wouldn't be verified - an
+ * attacker could insert any code they wanted into the module.
+ *
+ * So instead, reference the internal symbol from gcry_rsa. That creates a
+ * direct dependency on gcry_rsa, so it will be built in when this module
+ * is built in. Being built in (assuming the core image is itself signed!)
+ * also resolves our concerns about loading from the filesystem.
+ */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+
+static int check_sigs = 0;
+
+static char *
+grub_env_write_sec (struct grub_env_var *var __attribute__((unused)),
+ const char *val)
+{
+ check_sigs = (*val == '1') || (*val == 'e');
+ return grub_strdup (check_sigs ? "enforce" : "no");
+}
+
+static grub_err_t
+read_cert_from_file (grub_file_t f, struct x509_certificate *certificate)
+{
+ grub_err_t err;
+ grub_uint8_t *buf = NULL;
+ grub_ssize_t read_size;
+ grub_off_t total_read_size = 0;
+ grub_off_t file_size = grub_file_size (f);
+
+
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Cannot parse a certificate file of unknown size"));
+
+ buf = grub_zalloc (file_size);
+ if (!buf)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("Could not allocate buffer for certificate file contents"));
+
+ while (total_read_size < file_size)
+ {
+ read_size =
+ grub_file_read (f, &buf[total_read_size],
+ file_size - total_read_size);
+ if (read_size < 0)
+ {
+ err = grub_error (GRUB_ERR_READ_ERROR,
+ N_("Error reading certificate file"));
+ goto cleanup_buf;
+ }
+ total_read_size += read_size;
+ }
+
+ err = certificate_import (buf, total_read_size, certificate);
+ if (err != GRUB_ERR_NONE)
+ goto cleanup_buf;
+
+ return GRUB_ERR_NONE;
+
+cleanup_buf:
+ grub_free (buf);
+ return err;
+}
+
+static grub_err_t
+extract_appended_signature (grub_uint8_t * buf, grub_size_t bufsize,
+ struct grub_appended_signature *sig)
+{
+ grub_err_t err;
+ grub_size_t pkcs7_size;
+ grub_size_t remaining_len;
+ grub_uint8_t *appsigdata = buf + bufsize - grub_strlen (magic);
+
+ if (bufsize < grub_strlen (magic))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for signature magic"));
+
+ if (grub_memcmp (appsigdata, (grub_uint8_t *) magic, grub_strlen (magic)))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("Missing or invalid signature magic"));
+
+ remaining_len = bufsize - grub_strlen (magic);
+
+ if (remaining_len < sizeof (struct module_signature))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for signature metadata"));
+
+ appsigdata -= sizeof (struct module_signature);
+
+ /* extract the metadata */
+ grub_memcpy (&(sig->sig_metadata), appsigdata,
+ sizeof (struct module_signature));
+
+ remaining_len -= sizeof (struct module_signature);
+
+ if (sig->sig_metadata.id_type != 2)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("Wrong signature type"));
+
+#ifdef GRUB_TARGET_WORDS_BIGENDIAN
+ pkcs7_size = sig->sig_metadata.sig_len;
+#else
+ pkcs7_size = __builtin_bswap32 (sig->sig_metadata.sig_len);
+#endif
+
+ if (pkcs7_size > remaining_len)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for PKCS#7 message"));
+
+ grub_dprintf ("appendedsig", "sig len %" PRIuGRUB_SIZE "\n", pkcs7_size);
+
+ sig->signature_len =
+ grub_strlen (magic) + sizeof (struct module_signature) + pkcs7_size;
+
+ /* rewind pointer and parse pkcs7 data */
+ appsigdata -= pkcs7_size;
+
+ err = parse_pkcs7_signedData (appsigdata, pkcs7_size, &sig->pkcs7);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_verify_appended_signature (grub_uint8_t * buf, grub_size_t bufsize)
+{
+ grub_err_t err = GRUB_ERR_NONE;
+ grub_size_t datasize;
+ void *context;
+ unsigned char *hash;
+ gcry_mpi_t hashmpi;
+ gcry_err_code_t rc;
+ struct x509_certificate *pk;
+ struct grub_appended_signature sig;
+
+ if (!grub_trusted_key)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("No trusted keys to verify against"));
+
+ err = extract_appended_signature (buf, bufsize, &sig);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ datasize = bufsize - sig.signature_len;
+
+ context = grub_zalloc (sig.pkcs7.hash->contextsize);
+ if (!context)
+ return grub_errno;
+
+ sig.pkcs7.hash->init (context);
+ sig.pkcs7.hash->write (context, buf, datasize);
+ sig.pkcs7.hash->final (context);
+ hash = sig.pkcs7.hash->read (context);
+ grub_dprintf ("appendedsig",
+ "data size %" PRIxGRUB_SIZE ", hash %02x%02x%02x%02x...\n",
+ datasize, hash[0], hash[1], hash[2], hash[3]);
+
+ err = GRUB_ERR_BAD_SIGNATURE;
+ for (pk = grub_trusted_key; pk; pk = pk->next)
+ {
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, sig.pkcs7.hash, pk->mpis[0]);
+ if (rc)
+ {
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("Error padding hash for RSA verification: %d"),
+ rc);
+ goto cleanup;
+ }
+
+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &sig.pkcs7.sig_mpi,
+ pk->mpis, NULL, NULL);
+ gcry_mpi_release (hashmpi);
+
+ if (rc == 0)
+ {
+ grub_dprintf ("appendedsig", "verify with key '%s' succeeded\n",
+ pk->subject);
+ err = GRUB_ERR_NONE;
+ break;
+ }
+
+ grub_dprintf ("appendedsig", "verify with key '%s' failed with %d\n",
+ pk->subject, rc);
+ }
+
+ /* If we didn't verify, provide a neat message */
+ if (err != GRUB_ERR_NONE)
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("Failed to verify signature against a trusted key"));
+
+cleanup:
+ grub_free (context);
+ pkcs7_signedData_release (&sig.pkcs7);
+
+ return err;
+}
+
+static grub_err_t
+grub_cmd_verify_signature (grub_command_t cmd __attribute__((unused)),
+ int argc, char **args)
+{
+ grub_file_t f;
+ grub_err_t err = GRUB_ERR_NONE;
+ grub_uint8_t *data;
+ grub_ssize_t read_size;
+ grub_off_t file_size, total_read_size = 0;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ grub_dprintf ("appendedsig", "verifying %s\n", args[0]);
+
+ f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
+ if (!f)
+ {
+ err = grub_errno;
+ goto cleanup;
+ }
+
+ file_size = grub_file_size (f);
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Cannot verify the signature of a file of unknown size"));
+
+ data = grub_malloc (file_size);
+ if (!data)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("Could not allocate data buffer size "
+ PRIuGRUB_UINT64_T " for verification"), file_size);
+
+ while (total_read_size < file_size)
+ {
+ read_size =
+ grub_file_read (f, &data[total_read_size],
+ file_size - total_read_size);
+ if (read_size < 0)
+ {
+ err = grub_error (GRUB_ERR_READ_ERROR,
+ N_("Error reading file to verify"));
+ goto cleanup_data;
+ }
+ total_read_size += read_size;
+ }
+
+ err = grub_verify_appended_signature (data, file_size);
+
+cleanup_data:
+ grub_free (data);
+cleanup:
+ if (f)
+ grub_file_close (f);
+ return err;
+}
+
+static grub_err_t
+grub_cmd_distrust (grub_command_t cmd __attribute__((unused)),
+ int argc, char **args)
+{
+ unsigned long cert_num, i;
+ struct x509_certificate *cert, *prev;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected"));
+
+ grub_errno = GRUB_ERR_NONE;
+ cert_num = grub_strtoul (args[0], NULL, 10);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (cert_num < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Certificate number too small - numbers start at 1"));
+
+ if (cert_num == 1)
+ {
+ cert = grub_trusted_key;
+ grub_trusted_key = cert->next;
+
+ certificate_release (cert);
+ grub_free (cert);
+ return GRUB_ERR_NONE;
+ }
+ i = 2;
+ prev = grub_trusted_key;
+ cert = grub_trusted_key->next;
+ while (cert)
+ {
+ if (i == cert_num)
+ {
+ prev->next = cert->next;
+ certificate_release (cert);
+ grub_free (cert);
+ return GRUB_ERR_NONE;
+ }
+ i++;
+ prev = cert;
+ cert = cert->next;
+ }
+
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("No certificate number %d found - only %d certificates in the store"),
+ cert_num, i - 1);
+}
+
+static grub_err_t
+grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
+ int argc, char **args)
+{
+ grub_file_t certf;
+ struct x509_certificate *cert = NULL;
+ grub_err_t err;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ certf = grub_file_open (args[0],
+ GRUB_FILE_TYPE_CERTIFICATE_TRUST
+ | GRUB_FILE_TYPE_NO_DECOMPRESS);
+ if (!certf)
+ return grub_errno;
+
+
+ cert = grub_zalloc (sizeof (struct x509_certificate));
+ if (!cert)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("Could not allocate memory for certificate"));
+
+ err = read_cert_from_file (certf, cert);
+ grub_file_close (certf);
+ if (err != GRUB_ERR_NONE)
+ {
+ grub_free (cert);
+ return err;
+ }
+ grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
+ cert->subject);
+
+ cert->next = grub_trusted_key;
+ grub_trusted_key = cert;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_list (grub_command_t cmd __attribute__((unused)),
+ int argc __attribute__((unused)),
+ char **args __attribute__((unused)))
+{
+ struct x509_certificate *cert;
+ int cert_num = 1;
+ grub_size_t i;
+
+ for (cert = grub_trusted_key; cert; cert = cert->next)
+ {
+ grub_printf (N_("Certificate %d:\n"), cert_num);
+
+ grub_printf (N_("\tSerial: "));
+ for (i = 0; i < cert->serial_len - 1; i++)
+ {
+ grub_printf ("%02x:", cert->serial[i]);
+ }
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
+
+ grub_printf ("\tCN: %s\n\n", cert->subject);
+ cert_num++;
+
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+appendedsig_init (grub_file_t io, enum grub_file_type type,
+ void **context __attribute__((unused)),
+ enum grub_verify_flags *flags)
+{
+ const char *dangerous_mod;
+
+ if (!check_sigs)
+ {
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ }
+
+ switch (type & GRUB_FILE_TYPE_MASK)
+ {
+ case GRUB_FILE_TYPE_GRUB_MODULE:
+ if (grub_is_dangerous_module (io))
+ return grub_error (GRUB_ERR_ACCESS_DENIED,
+ N_("module cannot be loaded in appended signature mode: %s"),
+ io->name);
+
+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
+
+ case GRUB_FILE_TYPE_ACPI_TABLE:
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
+ return GRUB_ERR_NONE;
+
+ case GRUB_FILE_TYPE_CERTIFICATE_TRUST:
+ /*
+ * This is a certificate to add to trusted keychain.
+ *
+ * This needs to be verified or blocked. Ideally we'd write an x509
+ * verifier, but we lack the hubris required to take this on. Instead,
+ * require that it have an appended signature.
+ */
+
+ /* Fall through */
+
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
+ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
+ case GRUB_FILE_TYPE_BSD_KERNEL:
+ case GRUB_FILE_TYPE_XNU_KERNEL:
+ case GRUB_FILE_TYPE_PLAN9_KERNEL:
+
+ dangerous_mod = grub_dangerous_module_loaded ();
+ if (dangerous_mod)
+ return grub_error (GRUB_ERR_ACCESS_DENIED,
+ N_("cannot proceed due to dangerous module in memory: %s"),
+ dangerous_mod);
+
+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
+
+ default:
+ /*
+ * powerpc only supports the linux loader. If you support more,
+ * (especially chain loaded binaries) make sure they're checked!
+ */
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ }
+}
+
+static grub_err_t
+appendedsig_write (void *ctxt __attribute__((unused)),
+ void *buf, grub_size_t size)
+{
+ return grub_verify_appended_signature (buf, size);
+}
+
+struct grub_file_verifier grub_appendedsig_verifier = {
+ .name = "appendedsig",
+ .init = appendedsig_init,
+ .write = appendedsig_write,
+};
+
+static grub_ssize_t
+pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
+{
+ grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
+ return len;
+}
+
+/* Filesystem descriptor. */
+static struct grub_fs pseudo_fs = {
+ .name = "pseudo",
+ .read = pseudo_read
+};
+
+static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
+
+GRUB_MOD_INIT (appendedsig)
+{
+ int rc;
+ struct grub_module_header *header;
+ const char *val;
+
+ val = grub_env_get ("check_appended_signatures");
+ grub_dprintf ("appendedsig", "check_appended_signatures='%s'\n", val);
+
+ if (val && (val[0] == '1' || val[0] == 'e'))
+ check_sigs = 1;
+ else
+ check_sigs = 0;
+
+ grub_trusted_key = NULL;
+
+ grub_register_variable_hook ("check_appended_signatures", 0,
+ grub_env_write_sec);
+ grub_env_export ("check_appended_signatures");
+
+ rc = asn1_init ();
+ if (rc)
+ grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc,
+ asn1_strerror (rc));
+
+ FOR_MODULES (header)
+ {
+ struct grub_file pseudo_file;
+ struct x509_certificate *pk = NULL;
+ grub_err_t err;
+
+ /* Not an ELF module, skip. */
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
+ continue;
+
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
+ pseudo_file.fs = &pseudo_fs;
+ pseudo_file.size = header->size - sizeof (struct grub_module_header);
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
+
+ grub_dprintf ("appendedsig",
+ "Found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
+ pseudo_file.size);
+
+ pk = grub_zalloc (sizeof (struct x509_certificate));
+ if (!pk)
+ {
+ grub_fatal ("Out of memory loading initial certificates");
+ }
+
+ err = read_cert_from_file (&pseudo_file, pk);
+ if (err != GRUB_ERR_NONE)
+ grub_fatal ("Error loading initial key: %s", grub_errmsg);
+
+ grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
+
+ pk->next = grub_trusted_key;
+ grub_trusted_key = pk;
+ }
+
+ if (!val || val[0] == '\0')
+ {
+ grub_env_set ("check_appended_signatures",
+ grub_trusted_key ? "enforce" : "no");
+ }
+
+ cmd_trust =
+ grub_register_command ("trust_certificate", grub_cmd_trust,
+ N_("X509_CERTIFICATE"),
+ N_("Add X509_CERTIFICATE to trusted certificates."));
+ cmd_list =
+ grub_register_command ("list_certificates", grub_cmd_list, 0,
+ N_("Show the list of trusted x509 certificates."));
+ cmd_verify =
+ grub_register_command ("verify_appended", grub_cmd_verify_signature,
+ N_("FILE"),
+ N_("Verify FILE against the trusted x509 certificates."));
+ cmd_distrust =
+ grub_register_command ("distrust_certificate", grub_cmd_distrust,
+ N_("CERT_NUMBER"),
+ N_("Remove CERT_NUMBER (as listed by list_certificates) from trusted certificates."));
+
+ grub_verifier_register (&grub_appendedsig_verifier);
+ grub_dl_set_persistent (mod);
+}
+
+GRUB_MOD_FINI (appendedsig)
+{
+ /*
+ * grub_dl_set_persistent should prevent this from actually running, but
+ * it does still run under emu.
+ */
+
+ grub_verifier_unregister (&grub_appendedsig_verifier);
+ grub_unregister_command (cmd_verify);
+ grub_unregister_command (cmd_list);
+ grub_unregister_command (cmd_trust);
+ grub_unregister_command (cmd_distrust);
+}
diff --git a/include/grub/file.h b/include/grub/file.h
index cbbd294655b..2e337dbd68d 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -82,6 +82,8 @@ enum grub_file_type
GRUB_FILE_TYPE_PUBLIC_KEY,
/* File holding public key to add to trused keys. */
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST,
+ /* File holding x509 certificiate to add to trusted keys. */
+ GRUB_FILE_TYPE_CERTIFICATE_TRUST,
/* File of which we intend to print a blocklist to the user. */
GRUB_FILE_TYPE_PRINT_BLOCKLIST,
/* File we intend to use for test loading or testing speed. */

View File

@ -0,0 +1,897 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 01:31:02 +1000
Subject: [PATCH] appended signatures: verification tests
These tests are run through all_functional_test and test a range
of commands and behaviours.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 6 +
grub-core/tests/appended_signature_test.c | 281 +++++++++++++++
grub-core/tests/lib/functional_test.c | 1 +
grub-core/tests/appended_signatures.h | 557 ++++++++++++++++++++++++++++++
4 files changed, 845 insertions(+)
create mode 100644 grub-core/tests/appended_signature_test.c
create mode 100644 grub-core/tests/appended_signatures.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 1cf6b60f82e..8914083d13f 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2040,6 +2040,12 @@ module = {
common = tests/setjmp_test.c;
};
+module = {
+ name = appended_signature_test;
+ common = tests/appended_signature_test.c;
+ common = tests/appended_signatures.h;
+};
+
module = {
name = signature_test;
common = tests/signature_test.c;
diff --git a/grub-core/tests/appended_signature_test.c b/grub-core/tests/appended_signature_test.c
new file mode 100644
index 00000000000..88a485200d8
--- /dev/null
+++ b/grub-core/tests/appended_signature_test.c
@@ -0,0 +1,281 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020 IBM Corporation.
+ *
+ * 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/>.
+ */
+
+#include <grub/time.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/env.h>
+#include <grub/test.h>
+#include <grub/mm.h>
+#include <grub/procfs.h>
+#include <grub/file.h>
+
+#include "appended_signatures.h"
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define DEFINE_TEST_CASE(case_name) \
+static char * \
+get_ ## case_name (grub_size_t *sz) \
+{ \
+ char *ret; \
+ *sz = case_name ## _len; \
+ ret = grub_malloc (*sz); \
+ if (ret) \
+ grub_memcpy (ret, case_name, *sz); \
+ return ret; \
+} \
+\
+static struct grub_procfs_entry case_name ## _entry = \
+{ \
+ .name = #case_name, \
+ .get_contents = get_ ## case_name \
+}
+
+#define DO_TEST(case_name, is_valid) \
+{ \
+ grub_procfs_register (#case_name, &case_name ## _entry); \
+ do_verify ("(proc)/" #case_name, is_valid); \
+ grub_procfs_unregister (&case_name ## _entry); \
+}
+
+
+DEFINE_TEST_CASE (hi_signed);
+DEFINE_TEST_CASE (hi_signed_sha256);
+DEFINE_TEST_CASE (hj_signed);
+DEFINE_TEST_CASE (short_msg);
+DEFINE_TEST_CASE (unsigned_msg);
+DEFINE_TEST_CASE (hi_signed_2nd);
+
+static char *
+get_certificate_der (grub_size_t * sz)
+{
+ char *ret;
+ *sz = certificate_der_len;
+ ret = grub_malloc (*sz);
+ if (ret)
+ grub_memcpy (ret, certificate_der, *sz);
+ return ret;
+}
+
+static struct grub_procfs_entry certificate_der_entry = {
+ .name = "certificate.der",
+ .get_contents = get_certificate_der
+};
+
+static char *
+get_certificate2_der (grub_size_t * sz)
+{
+ char *ret;
+ *sz = certificate2_der_len;
+ ret = grub_malloc (*sz);
+ if (ret)
+ grub_memcpy (ret, certificate2_der, *sz);
+ return ret;
+}
+
+static struct grub_procfs_entry certificate2_der_entry = {
+ .name = "certificate2.der",
+ .get_contents = get_certificate2_der
+};
+
+static char *
+get_certificate_printable_der (grub_size_t * sz)
+{
+ char *ret;
+ *sz = certificate_printable_der_len;
+ ret = grub_malloc (*sz);
+ if (ret)
+ grub_memcpy (ret, certificate_printable_der, *sz);
+ return ret;
+}
+
+static struct grub_procfs_entry certificate_printable_der_entry = {
+ .name = "certificate_printable.der",
+ .get_contents = get_certificate_printable_der
+};
+
+
+static void
+do_verify (const char *f, int is_valid)
+{
+ grub_command_t cmd;
+ char *args[] = { (char *) f, NULL };
+ grub_err_t err;
+
+ cmd = grub_command_find ("verify_appended");
+ if (!cmd)
+ {
+ grub_test_assert (0, "can't find command `%s'", "verify_appended");
+ return;
+ }
+ err = (cmd->func) (cmd, 1, args);
+ if (is_valid)
+ {
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "verification of %s failed: %d: %s", f, grub_errno,
+ grub_errmsg);
+ }
+ else
+ {
+ grub_test_assert (err == GRUB_ERR_BAD_SIGNATURE,
+ "verification of %s unexpectedly succeeded", f);
+ }
+ grub_errno = GRUB_ERR_NONE;
+
+}
+
+static void
+appended_signature_test (void)
+{
+ grub_command_t cmd_trust, cmd_distrust;
+ char *trust_args[] = { (char *) "(proc)/certificate.der", NULL };
+ char *trust_args2[] = { (char *) "(proc)/certificate2.der", NULL };
+ char *trust_args_printable[] = { (char *) "(proc)/certificate_printable.der",
+ NULL };
+ char *distrust_args[] = { (char *) "1", NULL };
+ char *distrust2_args[] = { (char *) "2", NULL };
+ grub_err_t err;
+
+ grub_procfs_register ("certificate.der", &certificate_der_entry);
+ grub_procfs_register ("certificate2.der", &certificate2_der_entry);
+ grub_procfs_register ("certificate_printable.der",
+ &certificate_printable_der_entry);
+
+ cmd_trust = grub_command_find ("trust_certificate");
+ if (!cmd_trust)
+ {
+ grub_test_assert (0, "can't find command `%s'", "trust_certificate");
+ return;
+ }
+ err = (cmd_trust->func) (cmd_trust, 1, trust_args);
+
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "loading certificate failed: %d: %s", grub_errno,
+ grub_errmsg);
+
+ /* If we have no certificate the remainder of the tests are meaningless */
+ if (err != GRUB_ERR_NONE)
+ return;
+
+ /*
+ * Reload the command: this works around some 'interesting' behaviour in the
+ * dynamic command dispatcher. The first time you call cmd->func you get a
+ * dispatcher that loads the module, finds the real cmd, calls it, and then
+ * releases some internal storage. This means it's not safe to call a second
+ * time and we need to reload it.
+ */
+ cmd_trust = grub_command_find ("trust_certificate");
+
+ DO_TEST (hi_signed, 1);
+ DO_TEST (hi_signed_sha256, 1);
+ DO_TEST (hj_signed, 0);
+ DO_TEST (short_msg, 0);
+ DO_TEST (unsigned_msg, 0);
+
+ /*
+ * in enforcing mode, we shouldn't be able to load a certificate that isn't
+ * signed by an existing trusted key.
+ *
+ * However, procfs files automatically skip the verification test, so we can't
+ * easily test this.
+ */
+
+ /*
+ * verify that testing with 2 trusted certs works
+ */
+ DO_TEST (hi_signed_2nd, 0);
+
+ err = (cmd_trust->func) (cmd_trust, 1, trust_args2);
+
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "loading certificate 2 failed: %d: %s", grub_errno,
+ grub_errmsg);
+
+ if (err != GRUB_ERR_NONE)
+ return;
+
+ DO_TEST (hi_signed_2nd, 1);
+ DO_TEST (hi_signed, 1);
+
+ /*
+ * Check certificate removal. They're added to the _top_ of the list and
+ * removed by position in the list. Current the list looks like [#2, #1].
+ *
+ * First test removing the second certificate in the list, which is
+ * certificate #1, giving us just [#2].
+ */
+ cmd_distrust = grub_command_find ("distrust_certificate");
+ if (!cmd_distrust)
+ {
+ grub_test_assert (0, "can't find command `%s'", "distrust_certificate");
+ return;
+ }
+
+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust2_args);
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "distrusting certificate 1 failed: %d: %s", grub_errno,
+ grub_errmsg);
+ DO_TEST (hi_signed_2nd, 1);
+ DO_TEST (hi_signed, 0);
+
+ /*
+ * Now reload certificate #1. This will make the list look like [#1, #2]
+ */
+ err = (cmd_trust->func) (cmd_trust, 1, trust_args);
+
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "reloading certificate 1 failed: %d: %s", grub_errno,
+ grub_errmsg);
+ DO_TEST (hi_signed, 1);
+
+ /* Remove the first certificate in the list, giving us just [#2] */
+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust_args);
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "distrusting certificate 1 (first time) failed: %d: %s",
+ grub_errno, grub_errmsg);
+ DO_TEST (hi_signed_2nd, 1);
+ DO_TEST (hi_signed, 0);
+
+ /*
+ * Remove the first certificate again, giving an empty list.
+ *
+ * verify_appended should fail if there are no certificates to verify against.
+ */
+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust_args);
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "distrusting certificate 1 (second time) failed: %d: %s",
+ grub_errno, grub_errmsg);
+ DO_TEST (hi_signed_2nd, 0);
+
+ /*
+ * Lastly, check a certificate that uses printableString rather than
+ * utf8String loads properly.
+ */
+ err = (cmd_trust->func) (cmd_trust, 1, trust_args_printable);
+ grub_test_assert (err == GRUB_ERR_NONE,
+ "distrusting printable certificate failed: %d: %s",
+ grub_errno, grub_errmsg);
+
+ grub_procfs_unregister (&certificate_der_entry);
+ grub_procfs_unregister (&certificate2_der_entry);
+ grub_procfs_unregister (&certificate_printable_der_entry);
+}
+
+GRUB_FUNCTIONAL_TEST (appended_signature_test, appended_signature_test);
diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c
index 96781fb39b5..403fa5c789a 100644
--- a/grub-core/tests/lib/functional_test.c
+++ b/grub-core/tests/lib/functional_test.c
@@ -73,6 +73,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)),
grub_dl_load ("xnu_uuid_test");
grub_dl_load ("pbkdf2_test");
grub_dl_load ("signature_test");
+ grub_dl_load ("appended_signature_test");
grub_dl_load ("sleep_test");
grub_dl_load ("bswap_test");
grub_dl_load ("ctz_test");
diff --git a/grub-core/tests/appended_signatures.h b/grub-core/tests/appended_signatures.h
new file mode 100644
index 00000000000..aa3dc6278e3
--- /dev/null
+++ b/grub-core/tests/appended_signatures.h
@@ -0,0 +1,557 @@
+unsigned char certificate_der[] = {
+ 0x30, 0x82, 0x03, 0x88, 0x30, 0x82, 0x02, 0x70, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d,
+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x49, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x0c, 0x1f, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65,
+ 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
+ 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d,
+ 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+ 0x01, 0x16, 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e,
+ 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x30, 0x30,
+ 0x37, 0x30, 0x39, 0x30, 0x36, 0x32, 0x32, 0x30, 0x37, 0x5a, 0x18, 0x0f,
+ 0x32, 0x31, 0x32, 0x30, 0x30, 0x36, 0x31, 0x35, 0x30, 0x36, 0x32, 0x32,
+ 0x30, 0x37, 0x5a, 0x30, 0x52, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x0c, 0x28, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70,
+ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
+ 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67,
+ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x31, 0x1d, 0x30, 0x1b,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16,
+ 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e,
+ 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xcd, 0xe8, 0x1c, 0x08, 0x68, 0x2e, 0xcb, 0xfe, 0x8c, 0x4b, 0x3b, 0x61,
+ 0xe7, 0x8e, 0x80, 0x58, 0x85, 0x85, 0xea, 0xc8, 0x3b, 0x42, 0xba, 0x72,
+ 0x84, 0x65, 0x20, 0xbc, 0x48, 0xa2, 0x25, 0x49, 0x6e, 0x1c, 0xb9, 0x7d,
+ 0xeb, 0xc1, 0x0c, 0xa8, 0xb7, 0xcc, 0x13, 0x78, 0xba, 0x11, 0xa4, 0x98,
+ 0xd7, 0xd0, 0x7c, 0xdd, 0xf5, 0x5a, 0xb7, 0xcd, 0x31, 0x0e, 0xcd, 0x9e,
+ 0xa7, 0x19, 0xf0, 0xbd, 0x0f, 0xa6, 0xfe, 0x8a, 0x11, 0x97, 0xed, 0x8b,
+ 0xe5, 0x16, 0xa6, 0x21, 0x13, 0x36, 0xad, 0x05, 0x49, 0xec, 0x29, 0x12,
+ 0x38, 0xa7, 0x4b, 0x0f, 0xa1, 0xfb, 0x72, 0xc0, 0xc0, 0x09, 0x67, 0x78,
+ 0xa8, 0xb6, 0xd6, 0x1a, 0x39, 0xc0, 0xa8, 0xbf, 0x5f, 0x14, 0x89, 0x5c,
+ 0xbc, 0x41, 0x0c, 0x0c, 0x5d, 0x42, 0x2e, 0x1c, 0xdf, 0x1f, 0x1d, 0xc9,
+ 0x43, 0x94, 0x5b, 0x6e, 0x8f, 0x15, 0x8c, 0x8f, 0x94, 0x73, 0x4f, 0x97,
+ 0x54, 0xf1, 0x86, 0x8a, 0xbc, 0xe4, 0xe4, 0x93, 0xc1, 0x5e, 0xc2, 0x3e,
+ 0x31, 0x5e, 0xd4, 0x85, 0x57, 0x14, 0xd0, 0x11, 0x07, 0x65, 0xf4, 0x7c,
+ 0x8f, 0x07, 0x57, 0xe1, 0x22, 0xd4, 0x78, 0x47, 0x65, 0x4e, 0xa9, 0xb3,
+ 0xaa, 0xce, 0xc7, 0x36, 0xfe, 0xda, 0x66, 0x02, 0xb6, 0x8d, 0x18, 0x2f,
+ 0x3b, 0x41, 0x8d, 0x02, 0x08, 0x72, 0x4b, 0x69, 0xbd, 0x1e, 0x58, 0xfc,
+ 0x1b, 0x64, 0x04, 0x52, 0x35, 0x35, 0xe2, 0x3d, 0x3e, 0xde, 0xd6, 0x64,
+ 0xf4, 0xec, 0x57, 0x7e, 0x65, 0x59, 0x00, 0xa6, 0xd3, 0x4b, 0x09, 0x93,
+ 0x2a, 0x95, 0x0f, 0x30, 0xb6, 0xa1, 0x8c, 0xe7, 0x8b, 0x49, 0xa4, 0x1d,
+ 0x25, 0x2d, 0x65, 0x48, 0x8a, 0x0f, 0xcf, 0x2a, 0xa2, 0xe1, 0xef, 0x72,
+ 0x92, 0xc3, 0xf5, 0x21, 0x37, 0x83, 0x9b, 0x6d, 0x0b, 0x1b, 0xb3, 0xa2,
+ 0x32, 0x38, 0x11, 0xb1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30,
+ 0x5b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+ 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04,
+ 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+ 0x16, 0x04, 0x14, 0xe5, 0x2a, 0x4f, 0xf2, 0x84, 0x91, 0x57, 0x91, 0xaf,
+ 0x12, 0xd2, 0xf1, 0xa1, 0x87, 0x73, 0x0f, 0x90, 0x25, 0xa0, 0x7a, 0x30,
+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+ 0x56, 0xd1, 0xfd, 0xe2, 0x1e, 0x7e, 0x1c, 0x63, 0x4f, 0x47, 0xdb, 0xe4,
+ 0xc4, 0x51, 0x04, 0x03, 0x9a, 0x48, 0x35, 0x6e, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+ 0x82, 0x01, 0x01, 0x00, 0x65, 0x82, 0xd5, 0x88, 0x30, 0xe2, 0x2c, 0x47,
+ 0xf3, 0x31, 0x39, 0xa1, 0x75, 0x9a, 0xb0, 0x8a, 0x6c, 0x4b, 0xac, 0xdf,
+ 0x09, 0x7b, 0x90, 0xb6, 0x9e, 0x76, 0x62, 0x94, 0xc1, 0x3a, 0x99, 0x49,
+ 0x68, 0x29, 0x47, 0x42, 0xc3, 0x06, 0xcb, 0x88, 0x75, 0xe6, 0x79, 0x13,
+ 0x8c, 0x4b, 0x49, 0x6a, 0xb5, 0x56, 0x95, 0xc0, 0x42, 0x21, 0x9b, 0xd4,
+ 0x61, 0xd0, 0x02, 0x41, 0xdd, 0x20, 0x61, 0xe5, 0x91, 0xdf, 0x75, 0x00,
+ 0x25, 0x0e, 0x99, 0x65, 0x5c, 0x54, 0x49, 0x32, 0xa3, 0xe2, 0xcd, 0xa1,
+ 0x5f, 0x40, 0xf3, 0xc5, 0x81, 0xd9, 0x3c, 0xa3, 0x63, 0x5a, 0x38, 0x79,
+ 0xab, 0x77, 0x98, 0xde, 0x8f, 0x4e, 0x9e, 0x26, 0xbc, 0x4e, 0x80, 0x9e,
+ 0x8f, 0xbe, 0xf1, 0x00, 0xb3, 0x78, 0xb9, 0x4b, 0x1d, 0xc7, 0xa4, 0x83,
+ 0x59, 0x56, 0x11, 0xd1, 0x11, 0x1e, 0x50, 0x39, 0xd5, 0x78, 0x14, 0xf3,
+ 0xb9, 0x1d, 0xda, 0xe4, 0xc4, 0x63, 0x74, 0x26, 0xab, 0xa3, 0xfd, 0x9d,
+ 0x58, 0xa2, 0xee, 0x7b, 0x28, 0x34, 0xa3, 0xbe, 0x85, 0x7e, 0xaa, 0x97,
+ 0xb7, 0x5b, 0x9d, 0xa9, 0x4d, 0x96, 0xdb, 0x6b, 0x21, 0xe1, 0x96, 0x5d,
+ 0xc7, 0xad, 0x23, 0x03, 0x9a, 0x16, 0xdb, 0xa4, 0x1f, 0x63, 0xef, 0xaf,
+ 0x1e, 0x4f, 0xf8, 0x27, 0xdc, 0x4b, 0xfc, 0x2b, 0x68, 0x2e, 0xa0, 0xd3,
+ 0xae, 0xf2, 0xce, 0xf5, 0xfc, 0x97, 0x92, 0xd2, 0x29, 0x0f, 0x4f, 0x4b,
+ 0x29, 0xeb, 0x06, 0xcb, 0xf8, 0x21, 0x6e, 0xbc, 0x8b, 0x5c, 0xc5, 0xc9,
+ 0xf7, 0xe2, 0x7c, 0x47, 0xcd, 0x43, 0x98, 0xc4, 0xa3, 0x9a, 0xd7, 0x3e,
+ 0xdc, 0x01, 0x13, 0x28, 0x96, 0xc4, 0x60, 0x83, 0xe2, 0x79, 0xa1, 0x46,
+ 0xef, 0xf5, 0xa4, 0x7b, 0x00, 0xe3, 0x3d, 0x7d, 0xbc, 0xa8, 0x98, 0x49,
+ 0xa8, 0xcf, 0x3b, 0x41, 0xb6, 0x09, 0x97, 0x07
+};
+unsigned int certificate_der_len = 908;
+
+unsigned char hi_signed[] = {
+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82,
+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01,
+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49,
+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47,
+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64,
+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64,
+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d,
+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30,
+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66,
+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0,
+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16,
+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69,
+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b,
+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb,
+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94,
+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41,
+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86,
+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c,
+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86,
+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7,
+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14,
+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14,
+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0,
+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8,
+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e,
+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70,
+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25,
+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad,
+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95,
+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61,
+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65,
+ 0x64, 0x7e, 0x0a
+};
+unsigned int hi_signed_len = 495;
+
+unsigned char hj_signed[] = {
+ 0x68, 0x6a, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82,
+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01,
+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49,
+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47,
+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64,
+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64,
+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d,
+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30,
+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66,
+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0,
+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16,
+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69,
+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b,
+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb,
+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94,
+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41,
+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86,
+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c,
+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86,
+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7,
+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14,
+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14,
+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0,
+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8,
+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e,
+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70,
+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25,
+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad,
+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95,
+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61,
+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65,
+ 0x64, 0x7e, 0x0a
+};
+unsigned int hj_signed_len = 495;
+
+unsigned char hi_signed_sha256[] = {
+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82,
+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01,
+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49,
+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47,
+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64,
+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54,
+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64,
+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d,
+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30,
+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x7b, 0x5e, 0x82, 0x1d, 0x21,
+ 0xb6, 0x40, 0xd3, 0x33, 0x79, 0xa7, 0x52, 0x2b, 0xfc, 0x46, 0x51, 0x26,
+ 0xfe, 0x0f, 0x81, 0x90, 0x81, 0xab, 0x57, 0x5e, 0xf6, 0x45, 0x41, 0xa3,
+ 0x7b, 0x48, 0xdd, 0xd6, 0x59, 0x60, 0x51, 0x31, 0x14, 0x14, 0x7b, 0xb4,
+ 0x55, 0x7b, 0x4d, 0xfe, 0x09, 0x7a, 0x5d, 0xae, 0xc4, 0x58, 0x50, 0x80,
+ 0x75, 0xf2, 0x23, 0x20, 0x62, 0xe3, 0x7c, 0x26, 0x1d, 0x2a, 0x4d, 0x9f,
+ 0x89, 0xf0, 0x4f, 0x95, 0x8a, 0x80, 0x6e, 0x1a, 0xea, 0x87, 0xdb, 0x1f,
+ 0xf3, 0xda, 0x04, 0x91, 0x37, 0xea, 0x0a, 0xfb, 0x6c, 0xc9, 0x3d, 0x73,
+ 0xf9, 0x58, 0x7c, 0x15, 0x6b, 0xa2, 0x52, 0x5a, 0x97, 0xff, 0xd6, 0xb0,
+ 0xf1, 0xbf, 0xa5, 0x04, 0x6d, 0x91, 0xc1, 0x54, 0x05, 0xdc, 0x7f, 0x5d,
+ 0x19, 0xaf, 0x55, 0xec, 0x51, 0xfb, 0x66, 0x0a, 0xa4, 0x4e, 0x96, 0x47,
+ 0x43, 0x54, 0x7c, 0x64, 0xa8, 0xaa, 0xb4, 0x90, 0x02, 0xf3, 0xa7, 0x0b,
+ 0xb7, 0xbf, 0x06, 0xdb, 0x5e, 0x9c, 0x32, 0x6d, 0x45, 0x14, 0x1c, 0xaf,
+ 0x46, 0x30, 0x08, 0x55, 0x49, 0x78, 0xfa, 0x57, 0xda, 0x3d, 0xf5, 0xa0,
+ 0xef, 0x11, 0x0a, 0x81, 0x0d, 0x82, 0xcd, 0xaf, 0xdb, 0xda, 0x0e, 0x1a,
+ 0x44, 0xd1, 0xee, 0xc4, 0xb8, 0xde, 0x97, 0xb4, 0xda, 0xb4, 0x8b, 0x4f,
+ 0x58, 0x24, 0x59, 0xc0, 0xe0, 0x08, 0x97, 0x14, 0x68, 0xbe, 0x31, 0x09,
+ 0x5e, 0x67, 0x45, 0xf0, 0xcb, 0x81, 0x4f, 0x17, 0x44, 0x61, 0xe0, 0xe2,
+ 0xf0, 0xfc, 0x1e, 0xb9, 0x73, 0xaf, 0x42, 0xff, 0x33, 0xde, 0x61, 0x6b,
+ 0x7f, 0xc2, 0x69, 0x0d, 0x66, 0x54, 0xae, 0xf6, 0xde, 0x20, 0x47, 0x44,
+ 0x9b, 0x73, 0xd1, 0x07, 0x6e, 0x77, 0x37, 0x0a, 0xbb, 0x7f, 0xa0, 0x93,
+ 0x2d, 0x8d, 0x44, 0xba, 0xe2, 0xdd, 0x34, 0x32, 0xd7, 0x56, 0x71, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e,
+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61,
+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65,
+ 0x64, 0x7e, 0x0a
+};
+unsigned int hi_signed_sha256_len = 495;
+
+unsigned char short_msg[] = {
+ 0x68, 0x69, 0x0a
+};
+unsigned int short_msg_len = 3;
+
+unsigned char unsigned_msg[] = {
+ 0x53, 0x65, 0x64, 0x20, 0x75, 0x74, 0x20, 0x70, 0x65, 0x72, 0x73, 0x70,
+ 0x69, 0x63, 0x69, 0x61, 0x74, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x64, 0x65,
+ 0x20, 0x6f, 0x6d, 0x6e, 0x69, 0x73, 0x20, 0x69, 0x73, 0x74, 0x65, 0x20,
+ 0x6e, 0x61, 0x74, 0x75, 0x73, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20,
+ 0x73, 0x69, 0x74, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x20, 0x61, 0x63, 0x63, 0x75, 0x73, 0x61, 0x6e, 0x74, 0x69,
+ 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x71, 0x75,
+ 0x65, 0x20, 0x6c, 0x61, 0x75, 0x64, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d,
+ 0x2c, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6d, 0x20, 0x72, 0x65, 0x6d, 0x20,
+ 0x61, 0x70, 0x65, 0x72, 0x69, 0x61, 0x6d, 0x2c, 0x20, 0x65, 0x61, 0x71,
+ 0x75, 0x65, 0x20, 0x69, 0x70, 0x73, 0x61, 0x20, 0x71, 0x75, 0x61, 0x65,
+ 0x20, 0x61, 0x62, 0x20, 0x69, 0x6c, 0x6c, 0x6f, 0x20, 0x69, 0x6e, 0x76,
+ 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x76, 0x65, 0x72, 0x69, 0x74,
+ 0x61, 0x74, 0x69, 0x73, 0x20, 0x65, 0x74, 0x20, 0x71, 0x75, 0x61, 0x73,
+ 0x69, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x6f,
+ 0x20, 0x62, 0x65, 0x61, 0x74, 0x61, 0x65, 0x20, 0x76, 0x69, 0x74, 0x61,
+ 0x65, 0x20, 0x64, 0x69, 0x63, 0x74, 0x61, 0x20, 0x73, 0x75, 0x6e, 0x74,
+ 0x20, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6f, 0x2e, 0x20,
+ 0x4e, 0x65, 0x6d, 0x6f, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, 0x69, 0x70,
+ 0x73, 0x61, 0x6d, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75,
+ 0x70, 0x74, 0x61, 0x73, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x73, 0x70,
+ 0x65, 0x72, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x20, 0x61, 0x75, 0x74, 0x20,
+ 0x6f, 0x64, 0x69, 0x74, 0x20, 0x61, 0x75, 0x74, 0x20, 0x66, 0x75, 0x67,
+ 0x69, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x64, 0x20, 0x71, 0x75, 0x69, 0x61,
+ 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x75, 0x6e, 0x74, 0x75,
+ 0x72, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f,
+ 0x72, 0x65, 0x73, 0x20, 0x65, 0x6f, 0x73, 0x20, 0x71, 0x75, 0x69, 0x20,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x20, 0x76, 0x6f, 0x6c, 0x75,
+ 0x70, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x20, 0x73, 0x65, 0x71, 0x75, 0x69,
+ 0x20, 0x6e, 0x65, 0x73, 0x63, 0x69, 0x75, 0x6e, 0x74, 0x2e, 0x20, 0x4e,
+ 0x65, 0x71, 0x75, 0x65, 0x20, 0x70, 0x6f, 0x72, 0x72, 0x6f, 0x20, 0x71,
+ 0x75, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x65, 0x73, 0x74, 0x2c,
+ 0x20, 0x71, 0x75, 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d,
+ 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x61, 0x20,
+ 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d,
+ 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65,
+ 0x74, 0x75, 0x72, 0x2c, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63,
+ 0x69, 0x20, 0x76, 0x65, 0x6c, 0x69, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x64,
+ 0x20, 0x71, 0x75, 0x69, 0x61, 0x20, 0x6e, 0x6f, 0x6e, 0x20, 0x6e, 0x75,
+ 0x6d, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x65, 0x69, 0x75, 0x73, 0x20, 0x6d,
+ 0x6f, 0x64, 0x69, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x20,
+ 0x69, 0x6e, 0x63, 0x69, 0x64, 0x75, 0x6e, 0x74, 0x20, 0x75, 0x74, 0x20,
+ 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x74, 0x20, 0x64, 0x6f,
+ 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x61, 0x6d, 0x20,
+ 0x61, 0x6c, 0x69, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x71, 0x75, 0x61, 0x65,
+ 0x72, 0x61, 0x74, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74,
+ 0x65, 0x6d, 0x2e, 0x20, 0x55, 0x74, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20,
+ 0x61, 0x64, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x20, 0x76, 0x65,
+ 0x6e, 0x69, 0x61, 0x6d, 0x2c, 0x20, 0x71, 0x75, 0x69, 0x73, 0x20, 0x6e,
+ 0x6f, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x20, 0x65, 0x78, 0x65, 0x72, 0x63,
+ 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x20, 0x75, 0x6c,
+ 0x6c, 0x61, 0x6d, 0x20, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x69, 0x73,
+ 0x20, 0x73, 0x75, 0x73, 0x63, 0x69, 0x70, 0x69, 0x74, 0x20, 0x6c, 0x61,
+ 0x62, 0x6f, 0x72, 0x69, 0x6f, 0x73, 0x61, 0x6d, 0x2c, 0x20, 0x6e, 0x69,
+ 0x73, 0x69, 0x20, 0x75, 0x74, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x69,
+ 0x64, 0x20, 0x65, 0x78, 0x20, 0x65, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x6f, 0x64, 0x69, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61,
+ 0x74, 0x75, 0x72, 0x3f, 0x20, 0x51, 0x75, 0x69, 0x73, 0x20, 0x61, 0x75,
+ 0x74, 0x65, 0x6d, 0x20, 0x76, 0x65, 0x6c, 0x20, 0x65, 0x75, 0x6d, 0x20,
+ 0x69, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x68, 0x65,
+ 0x6e, 0x64, 0x65, 0x72, 0x69, 0x74, 0x20, 0x71, 0x75, 0x69, 0x20, 0x69,
+ 0x6e, 0x20, 0x65, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61,
+ 0x74, 0x65, 0x20, 0x76, 0x65, 0x6c, 0x69, 0x74, 0x20, 0x65, 0x73, 0x73,
+ 0x65, 0x20, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x6e, 0x69, 0x68, 0x69, 0x6c,
+ 0x20, 0x6d, 0x6f, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x65, 0x20, 0x63,
+ 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, 0x74, 0x75, 0x72, 0x2c, 0x20,
+ 0x76, 0x65, 0x6c, 0x20, 0x69, 0x6c, 0x6c, 0x75, 0x6d, 0x20, 0x71, 0x75,
+ 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x65, 0x75,
+ 0x6d, 0x20, 0x66, 0x75, 0x67, 0x69, 0x61, 0x74, 0x20, 0x71, 0x75, 0x6f,
+ 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x73, 0x20, 0x6e, 0x75,
+ 0x6c, 0x6c, 0x61, 0x20, 0x70, 0x61, 0x72, 0x69, 0x61, 0x74, 0x75, 0x72,
+ 0x3f, 0x0a
+};
+unsigned int unsigned_msg_len = 866;
+
+unsigned char certificate2_der[] = {
+ 0x30, 0x82, 0x05, 0x52, 0x30, 0x82, 0x03, 0x3a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5,
+ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x3a, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04,
+ 0x03, 0x0c, 0x2f, 0x47, 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20,
+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20,
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x74, 0x79, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x37, 0x32, 0x38,
+ 0x31, 0x33, 0x32, 0x34, 0x32, 0x39, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x32,
+ 0x30, 0x30, 0x37, 0x30, 0x34, 0x31, 0x33, 0x32, 0x34, 0x32, 0x39, 0x5a,
+ 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+ 0x20, 0x47, 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69,
+ 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x82, 0x02,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02,
+ 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xb0, 0x2f, 0x50, 0x01, 0x9c, 0x0e,
+ 0xd6, 0x8c, 0x07, 0xca, 0xc1, 0xcf, 0xbc, 0x03, 0xdd, 0xd3, 0xfa, 0xe3,
+ 0x4f, 0x71, 0xc1, 0x30, 0xaa, 0x09, 0x96, 0xe4, 0xd0, 0x6c, 0x42, 0x93,
+ 0xdb, 0x35, 0xf6, 0x7e, 0x1b, 0x67, 0xc0, 0xc2, 0x2d, 0x5b, 0xec, 0xca,
+ 0x35, 0x06, 0x32, 0x6c, 0x7b, 0x2c, 0xd3, 0x71, 0x2b, 0xe9, 0x7a, 0x19,
+ 0xd1, 0xf2, 0xa0, 0x7f, 0xd7, 0x4d, 0x6e, 0x28, 0xbb, 0xae, 0x49, 0x4a,
+ 0xbc, 0xea, 0x47, 0x67, 0xb8, 0x36, 0xa6, 0xf5, 0x0d, 0x0e, 0x20, 0x14,
+ 0x0c, 0x66, 0x67, 0x28, 0xb5, 0x97, 0x8b, 0x1f, 0x5e, 0x32, 0x06, 0x29,
+ 0x9c, 0x99, 0x92, 0x0f, 0x73, 0xac, 0xfd, 0xd2, 0x1d, 0xf2, 0xa8, 0x55,
+ 0x9d, 0x1b, 0xd8, 0x3d, 0xb0, 0x76, 0x9a, 0xb6, 0x6c, 0x9f, 0x62, 0x37,
+ 0x2f, 0xc0, 0xef, 0x44, 0xb3, 0x0d, 0x4a, 0x3e, 0x4f, 0x7d, 0xbd, 0xdb,
+ 0xd8, 0x75, 0x5f, 0x68, 0xe3, 0xf0, 0xec, 0x82, 0x66, 0x7c, 0x31, 0x70,
+ 0xa9, 0xa1, 0x6f, 0x38, 0x9f, 0xdf, 0xf5, 0xf0, 0x7d, 0x23, 0x9d, 0x34,
+ 0xa5, 0x85, 0xd3, 0xdf, 0x68, 0x41, 0xfc, 0x4f, 0x89, 0x45, 0x3c, 0x24,
+ 0x81, 0xa6, 0xf2, 0x3c, 0x02, 0x26, 0x09, 0x48, 0xdd, 0xfe, 0x4b, 0xb6,
+ 0x66, 0xbf, 0x8f, 0xe5, 0x5f, 0xf0, 0x5d, 0x8a, 0x61, 0x2e, 0x5f, 0x9f,
+ 0x80, 0xd9, 0xd5, 0xe6, 0x41, 0xd8, 0x10, 0x5e, 0x7a, 0xc6, 0xdb, 0x89,
+ 0xc7, 0xca, 0x6c, 0x5b, 0xb1, 0x4e, 0x7d, 0x0c, 0x03, 0xfd, 0x50, 0xca,
+ 0xbf, 0xbb, 0xe2, 0x69, 0x4b, 0x4e, 0xc2, 0x3d, 0x75, 0xfa, 0xd1, 0xcc,
+ 0xd6, 0xf9, 0x39, 0xb9, 0xdc, 0x53, 0xad, 0x62, 0xfb, 0x1b, 0x94, 0x26,
+ 0x7f, 0x21, 0x54, 0x5c, 0xb7, 0xdc, 0xe7, 0x96, 0x8c, 0xce, 0x75, 0xe0,
+ 0x17, 0x01, 0x3a, 0x3c, 0x77, 0x6e, 0xa4, 0x8b, 0x7a, 0x83, 0x28, 0x7a,
+ 0xf7, 0xb0, 0x5f, 0xfc, 0x7f, 0x2d, 0x2e, 0xec, 0xf5, 0xeb, 0x9c, 0x63,
+ 0x74, 0xd0, 0xe5, 0xdc, 0x19, 0xe4, 0x71, 0xc5, 0x4a, 0x8a, 0x54, 0xa4,
+ 0xe0, 0x7d, 0x4e, 0xbf, 0x53, 0x30, 0xaf, 0xd0, 0xeb, 0x96, 0xc3, 0xbb,
+ 0x65, 0xf7, 0x67, 0xf5, 0xae, 0xd3, 0x96, 0xf2, 0x63, 0xc8, 0x69, 0xf7,
+ 0x47, 0xcb, 0x27, 0x79, 0xe1, 0xff, 0x2f, 0x68, 0xdf, 0x1e, 0xb3, 0xb8,
+ 0x0c, 0xc5, 0x58, 0x73, 0xcc, 0xfe, 0x8c, 0xda, 0x4e, 0x3b, 0x01, 0x04,
+ 0xcd, 0xcb, 0xb8, 0x3e, 0x06, 0xfd, 0x4c, 0x0a, 0x9f, 0x5e, 0x76, 0x8c,
+ 0x0c, 0x83, 0x75, 0x09, 0x08, 0xb2, 0xdb, 0xf4, 0x49, 0x4e, 0xa0, 0xf2,
+ 0x0c, 0x7b, 0x87, 0x38, 0x9e, 0x22, 0x67, 0xbd, 0xd1, 0x97, 0x57, 0x24,
+ 0xf1, 0x46, 0x07, 0xf9, 0xd2, 0x1b, 0xec, 0x25, 0x5e, 0x67, 0xd9, 0x66,
+ 0x23, 0x1b, 0xd3, 0xe4, 0xaa, 0xec, 0x88, 0xf0, 0x7e, 0x15, 0x83, 0x51,
+ 0x31, 0x67, 0x51, 0x76, 0x5f, 0x55, 0xd7, 0x36, 0xdf, 0x4a, 0x84, 0x0b,
+ 0x6f, 0x5c, 0xbb, 0x5b, 0x8f, 0x37, 0x23, 0x7f, 0xf8, 0x17, 0x84, 0xa2,
+ 0x70, 0x20, 0x07, 0x0c, 0x90, 0x3a, 0x04, 0xfd, 0xf0, 0x08, 0x4a, 0xb1,
+ 0x16, 0x0f, 0xe6, 0xf6, 0x40, 0x51, 0x83, 0xd2, 0x87, 0x40, 0x9c, 0x1c,
+ 0x9f, 0x13, 0x38, 0x17, 0xd3, 0x34, 0x58, 0xad, 0x05, 0x71, 0xa0, 0x73,
+ 0xca, 0x40, 0xa6, 0xa4, 0x81, 0x02, 0xee, 0xa8, 0x72, 0x41, 0xa1, 0x41,
+ 0x18, 0x64, 0x8a, 0x86, 0x8a, 0x5d, 0xe6, 0x4f, 0x0a, 0xc5, 0x95, 0x98,
+ 0xf9, 0x78, 0xfe, 0x19, 0x0d, 0xc9, 0xb3, 0x89, 0xc1, 0x2b, 0x09, 0xbe,
+ 0xf1, 0xd2, 0x04, 0x5d, 0xcc, 0x28, 0xf5, 0x4b, 0xd2, 0x20, 0x4f, 0xc5,
+ 0x41, 0x9d, 0x8c, 0x85, 0xd8, 0xb0, 0x68, 0x5e, 0xc1, 0x0c, 0xb7, 0x24,
+ 0x4d, 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30, 0x5b, 0x30,
+ 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+ 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
+ 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
+ 0x14, 0xac, 0xf5, 0x47, 0x17, 0xd9, 0x7d, 0xc1, 0xb1, 0xc4, 0x41, 0xe1,
+ 0x41, 0x60, 0xcb, 0x37, 0x11, 0x60, 0x28, 0x78, 0x5f, 0x30, 0x1f, 0x06,
+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x21, 0x94,
+ 0xfb, 0xf9, 0xb2, 0x43, 0xe9, 0x33, 0xd7, 0x50, 0x7d, 0xc7, 0x37, 0xdb,
+ 0xd5, 0x82, 0x5a, 0x4e, 0xbe, 0x1b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02,
+ 0x01, 0x00, 0x96, 0x70, 0x65, 0x26, 0x42, 0xf8, 0xdc, 0x69, 0xde, 0xcf,
+ 0x41, 0x3a, 0x2e, 0x7f, 0x5b, 0xf1, 0xf9, 0x3b, 0x9b, 0xd2, 0x4e, 0x64,
+ 0x48, 0x81, 0xe4, 0x5d, 0x1e, 0x22, 0xce, 0x68, 0x63, 0x62, 0xe5, 0x1b,
+ 0x9b, 0xf2, 0xc7, 0x12, 0xda, 0x1e, 0x9b, 0x90, 0x84, 0x79, 0x48, 0x12,
+ 0xe6, 0x21, 0x6f, 0x2f, 0x7e, 0x18, 0x77, 0xdb, 0x8c, 0xc4, 0xd1, 0x0d,
+ 0x91, 0xbf, 0x39, 0x22, 0x0f, 0x64, 0xcf, 0x25, 0x2e, 0x8c, 0x1f, 0x91,
+ 0x81, 0xb5, 0xe9, 0x6c, 0x02, 0x3a, 0xf8, 0x07, 0xa2, 0x6f, 0x46, 0x5d,
+ 0x7b, 0xfd, 0x43, 0xff, 0x41, 0x0f, 0xe2, 0x57, 0x1c, 0xbd, 0x48, 0x60,
+ 0x53, 0x11, 0x48, 0x87, 0x88, 0x9d, 0x13, 0x82, 0x40, 0x68, 0x44, 0x2c,
+ 0xc6, 0xc8, 0x95, 0x27, 0x4f, 0xb6, 0xb9, 0x4a, 0x22, 0x0a, 0xfd, 0xe4,
+ 0x46, 0x8f, 0x35, 0x12, 0x98, 0x5a, 0x34, 0x6f, 0x2b, 0x57, 0x62, 0xa1,
+ 0x4d, 0x8d, 0x79, 0x37, 0xe4, 0x6b, 0x8a, 0x32, 0x5b, 0xcb, 0xef, 0x79,
+ 0x11, 0xed, 0xa7, 0xf8, 0x7a, 0x1c, 0xbd, 0x86, 0xdc, 0x0e, 0x2e, 0xfd,
+ 0xd3, 0x51, 0xbb, 0x73, 0xad, 0x00, 0xa0, 0x1b, 0xf9, 0x1d, 0xd1, 0x4a,
+ 0xe4, 0xd4, 0x02, 0x63, 0x2b, 0x39, 0x5f, 0x18, 0x08, 0x2f, 0x42, 0xb7,
+ 0x23, 0x4b, 0x48, 0x46, 0x1f, 0x63, 0x87, 0xae, 0x6d, 0xd5, 0xdb, 0x60,
+ 0xf8, 0x5f, 0xd3, 0x13, 0xec, 0xca, 0xdd, 0x60, 0x60, 0x79, 0x52, 0x70,
+ 0x47, 0xae, 0x1d, 0x38, 0x78, 0x71, 0xcf, 0xb3, 0x04, 0x03, 0xbe, 0xba,
+ 0x81, 0xba, 0x74, 0xb1, 0x30, 0x35, 0xdc, 0xea, 0x21, 0x4a, 0x9b, 0x70,
+ 0xfb, 0xd6, 0x60, 0x59, 0x78, 0x0c, 0x4d, 0x39, 0x19, 0x1d, 0xe5, 0x75,
+ 0xba, 0x07, 0xf4, 0x22, 0x37, 0x64, 0xb7, 0xf2, 0x9a, 0xc9, 0x11, 0x2d,
+ 0x8e, 0x58, 0xa6, 0xcf, 0x83, 0xf1, 0xcb, 0x6c, 0x7f, 0x02, 0xbd, 0xda,
+ 0x03, 0x92, 0xa9, 0x45, 0x24, 0x56, 0xc5, 0xbd, 0x41, 0xd1, 0x20, 0x86,
+ 0xc0, 0xb6, 0xb7, 0xe8, 0xa7, 0xb2, 0x46, 0xf7, 0x8e, 0xa9, 0x38, 0x0e,
+ 0x23, 0x77, 0x3c, 0x0d, 0x66, 0x83, 0x6a, 0x1a, 0x6b, 0x7f, 0x54, 0x11,
+ 0x58, 0x0d, 0x4a, 0xb5, 0x74, 0x60, 0xca, 0xed, 0xff, 0x91, 0x47, 0xd9,
+ 0x29, 0xe0, 0xaa, 0x8c, 0xa8, 0x8f, 0x10, 0x4c, 0x15, 0x7d, 0xce, 0x95,
+ 0xf9, 0x87, 0x1e, 0x18, 0x38, 0x18, 0xfc, 0xcc, 0xaf, 0x91, 0x17, 0x3f,
+ 0xfa, 0xf0, 0x8a, 0x09, 0x6f, 0xba, 0x4e, 0x53, 0xf7, 0xfa, 0x4f, 0x20,
+ 0xa3, 0xf4, 0x4a, 0x5a, 0xde, 0x17, 0x1c, 0x29, 0x6a, 0x6f, 0x03, 0x48,
+ 0xdf, 0xad, 0x4f, 0xe4, 0xbc, 0x71, 0xc4, 0x72, 0x32, 0x11, 0x84, 0xac,
+ 0x09, 0xd2, 0x18, 0x44, 0x35, 0xf1, 0xcd, 0xaf, 0xa8, 0x98, 0xe0, 0x8b,
+ 0xec, 0xa0, 0x83, 0x37, 0xc3, 0x35, 0x85, 0xd6, 0xd8, 0x1b, 0xe0, 0x75,
+ 0xdc, 0xfd, 0xde, 0xc9, 0xeb, 0xd5, 0x18, 0x0f, 0xd3, 0x4c, 0x2f, 0x71,
+ 0xdc, 0x48, 0xe3, 0x14, 0xeb, 0xda, 0x00, 0x24, 0x24, 0x9e, 0xa3, 0x8e,
+ 0x3e, 0x08, 0x6f, 0x22, 0x24, 0xd6, 0xc4, 0x85, 0x8f, 0x68, 0x00, 0x4a,
+ 0x82, 0x4c, 0x33, 0x6e, 0xa5, 0x35, 0x7b, 0xeb, 0x4b, 0xdc, 0xa0, 0xa6,
+ 0x65, 0x6f, 0x5a, 0x7a, 0xdf, 0x8a, 0x01, 0x52, 0xa1, 0x6c, 0xff, 0x59,
+ 0x22, 0x7f, 0xe1, 0x96, 0x1b, 0x19, 0xb8, 0xf9, 0x5d, 0x44, 0x9f, 0x91,
+ 0x03, 0x3c, 0x3d, 0xa1, 0x2a, 0xb6, 0x5a, 0x51, 0xa0, 0xce, 0x4a, 0x88,
+ 0x22, 0x72, 0x9c, 0xdc, 0xc0, 0x47, 0x76, 0x35, 0x84, 0x75, 0x9b, 0x87,
+ 0x5c, 0xd3, 0xcf, 0xe7, 0xdd, 0xa3, 0x57, 0x14, 0xdf, 0x00, 0xfd, 0x19,
+ 0x2a, 0x7d, 0x89, 0x27, 0x1c, 0x78, 0x97, 0x04, 0x58, 0x48
+};
+unsigned int certificate2_der_len = 1366;
+
+unsigned char hi_signed_2nd[] = {
+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x02, 0xb1, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0xa2, 0x30, 0x82,
+ 0x02, 0x9e, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x02,
+ 0x7b, 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x01, 0x30, 0x52, 0x30, 0x3a,
+ 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x47,
+ 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74,
+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x14,
+ 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, 0x91, 0x07,
+ 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30, 0x0b, 0x06, 0x09,
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0d, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x04, 0x82, 0x02, 0x00, 0x0e, 0xc2, 0x30, 0x38, 0x81, 0x23, 0x68, 0x90,
+ 0xae, 0x5f, 0xce, 0xf7, 0x27, 0xb1, 0x8c, 0x2e, 0x12, 0x10, 0xc6, 0x99,
+ 0xdc, 0x4d, 0x4b, 0x79, 0xda, 0xe4, 0x32, 0x10, 0x46, 0x1c, 0x16, 0x07,
+ 0x87, 0x66, 0x55, 0xff, 0x64, 0x1c, 0x61, 0x25, 0xd5, 0xb9, 0xe1, 0xfe,
+ 0xea, 0x5a, 0xcd, 0x56, 0xa5, 0xc3, 0xbe, 0xb1, 0x61, 0xc7, 0x6f, 0x5f,
+ 0x69, 0x20, 0x64, 0x50, 0x6f, 0x12, 0x78, 0xb6, 0x0c, 0x72, 0x44, 0x4f,
+ 0x60, 0x0f, 0x9f, 0xa2, 0x83, 0x3b, 0xc2, 0x83, 0xd5, 0x14, 0x1f, 0x6f,
+ 0x3e, 0xb2, 0x47, 0xb5, 0x58, 0xc5, 0xa7, 0xb4, 0x82, 0x53, 0x2e, 0x53,
+ 0x95, 0x4e, 0x3d, 0xe4, 0x62, 0xe8, 0xa1, 0xaf, 0xae, 0xbf, 0xa9, 0xd2,
+ 0x22, 0x07, 0xbe, 0x71, 0x37, 0x2c, 0x5a, 0xa7, 0x6c, 0xaf, 0x14, 0xc0,
+ 0x6c, 0x2f, 0xbf, 0x4f, 0x15, 0xc2, 0x0f, 0x8b, 0xdc, 0x68, 0x45, 0xdf,
+ 0xf3, 0xa5, 0x7f, 0x11, 0x6a, 0x54, 0xcd, 0x67, 0xb9, 0x2e, 0x7d, 0x05,
+ 0xe3, 0x1c, 0x1d, 0xcc, 0x77, 0x8e, 0x97, 0xb1, 0xa0, 0x11, 0x09, 0x3d,
+ 0x90, 0x54, 0xfc, 0x7e, 0xbb, 0xbb, 0x21, 0x23, 0x03, 0x44, 0xbf, 0x7d,
+ 0x2c, 0xc9, 0x15, 0x42, 0xe5, 0xa0, 0x3b, 0xa2, 0xd1, 0x5b, 0x73, 0x81,
+ 0xff, 0xfa, 0x90, 0xfc, 0x27, 0x7b, 0x2f, 0x86, 0x9c, 0x1d, 0x14, 0x36,
+ 0x94, 0xa2, 0x6e, 0xe8, 0x9d, 0xa0, 0x5f, 0xfc, 0x5a, 0x0d, 0xa4, 0xd5,
+ 0x2f, 0x8d, 0xd6, 0x00, 0xfa, 0x93, 0x5b, 0x09, 0x7f, 0x42, 0x78, 0xcc,
+ 0x8c, 0x49, 0xda, 0xd9, 0xf6, 0x43, 0xe7, 0xe1, 0x3c, 0xa2, 0xe2, 0x70,
+ 0xe2, 0x6a, 0x99, 0xc5, 0xd6, 0xa2, 0xe3, 0x0b, 0xd4, 0x09, 0xac, 0x94,
+ 0xaf, 0xb7, 0xf0, 0xb3, 0x0c, 0x1e, 0xf5, 0x16, 0x4f, 0x53, 0x9a, 0xe3,
+ 0xcc, 0xe2, 0x0c, 0x4a, 0xb9, 0xe6, 0x06, 0xbb, 0xf7, 0x41, 0x43, 0x20,
+ 0x04, 0xee, 0x99, 0x2f, 0xd8, 0x9f, 0xda, 0x3f, 0xfd, 0x49, 0xb8, 0xc2,
+ 0xbd, 0xd9, 0xc5, 0x72, 0xfd, 0xe3, 0xce, 0x1c, 0xbc, 0xe4, 0x39, 0xac,
+ 0x2a, 0x99, 0xe9, 0xb4, 0x3e, 0x74, 0x10, 0xeb, 0xd5, 0x14, 0xcc, 0xdb,
+ 0xf1, 0x04, 0x63, 0x36, 0xfb, 0x1f, 0x2b, 0xe2, 0x73, 0xd4, 0xd8, 0x49,
+ 0x31, 0xa8, 0x55, 0xcc, 0xa7, 0x76, 0x36, 0x6e, 0x18, 0xdc, 0xb9, 0xb0,
+ 0x29, 0x99, 0xcf, 0x49, 0xbf, 0xf9, 0xdb, 0x7f, 0x24, 0x42, 0x02, 0xcb,
+ 0xc1, 0xaa, 0xcb, 0xba, 0x18, 0x85, 0x86, 0xc7, 0xf4, 0x1c, 0x62, 0x76,
+ 0xbc, 0x73, 0xfb, 0xe4, 0x15, 0xb8, 0xdd, 0x5d, 0xa6, 0x68, 0x39, 0xa5,
+ 0x3d, 0x33, 0xaf, 0xd5, 0x92, 0x4d, 0x48, 0xdb, 0x22, 0xc0, 0xdc, 0x49,
+ 0x5f, 0x7b, 0xa8, 0xd2, 0x62, 0x2d, 0xa7, 0x39, 0x93, 0x48, 0xe7, 0x6b,
+ 0x23, 0xba, 0xd4, 0xe0, 0xc1, 0x29, 0x55, 0xc4, 0x34, 0xe3, 0xac, 0x25,
+ 0xa7, 0x15, 0xad, 0xab, 0xb3, 0xb7, 0x25, 0xca, 0x37, 0x88, 0x40, 0x2e,
+ 0x47, 0x6e, 0x92, 0x20, 0x09, 0x2e, 0x5a, 0xec, 0xf2, 0xfb, 0xb3, 0xa0,
+ 0x16, 0xb6, 0x93, 0xf2, 0xf5, 0x8b, 0xfe, 0xaf, 0x25, 0xee, 0x2e, 0x98,
+ 0x6c, 0x0a, 0xfe, 0xae, 0x0b, 0x57, 0xf5, 0x9f, 0x3c, 0x80, 0xe9, 0x8b,
+ 0xaf, 0x92, 0x8a, 0xad, 0xe7, 0xa0, 0xe4, 0xe6, 0x0a, 0xa0, 0xc7, 0x83,
+ 0xb5, 0x48, 0x58, 0x5f, 0x55, 0x9e, 0x9b, 0x27, 0xcd, 0x31, 0x1f, 0x3e,
+ 0x50, 0x5a, 0x91, 0xad, 0x21, 0x1b, 0x97, 0x5b, 0xe8, 0xfa, 0x29, 0x8a,
+ 0xa4, 0x17, 0xe8, 0xab, 0x87, 0x02, 0xd6, 0x18, 0x8c, 0x9f, 0x65, 0xb7,
+ 0x2a, 0xfa, 0xde, 0x5f, 0x77, 0x30, 0x6c, 0x04, 0x22, 0xe6, 0x58, 0x26,
+ 0x14, 0x0d, 0x9c, 0x41, 0x0a, 0x82, 0x77, 0xdb, 0x40, 0xa1, 0x58, 0xac,
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb5,
+ 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e,
+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64,
+ 0x65, 0x64, 0x7e, 0x0a
+};
+unsigned int hi_signed_2nd_len = 736;
+
+unsigned char certificate_printable_der[] = {
+ 0x30, 0x82, 0x03, 0x39, 0x30, 0x82, 0x02, 0x21, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x09, 0x00, 0xde, 0xf6, 0x22, 0xc4, 0xf2, 0xf1, 0x86, 0x02,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x30, 0x2a, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x1f, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20,
+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20,
+ 0x43, 0x41, 0x20, 0x32, 0x20, 0x28, 0x62, 0x65, 0x74, 0x61, 0x29, 0x30,
+ 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x33, 0x31, 0x31, 0x34, 0x31,
+ 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x33, 0x37, 0x31, 0x30, 0x32, 0x35,
+ 0x31, 0x34, 0x31, 0x39, 0x32, 0x33, 0x5a, 0x30, 0x2f, 0x31, 0x2d, 0x30,
+ 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x52, 0x65, 0x64, 0x20,
+ 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42,
+ 0x6f, 0x6f, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20,
+ 0x33, 0x20, 0x28, 0x62, 0x65, 0x74, 0x61, 0x29, 0x30, 0x82, 0x01, 0x22,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xda, 0xa1, 0xed, 0x8d, 0x8e, 0x15,
+ 0x5c, 0xf8, 0x01, 0x77, 0x48, 0x4a, 0x60, 0x96, 0xf9, 0x27, 0xfa, 0xe2,
+ 0xb1, 0x69, 0x0f, 0x51, 0x19, 0x52, 0x7e, 0xc4, 0x34, 0x8e, 0xe1, 0x9b,
+ 0x9c, 0xa4, 0xb1, 0x5c, 0xd6, 0x81, 0x98, 0x78, 0xfe, 0xa9, 0xe5, 0x0b,
+ 0x00, 0xba, 0x9c, 0x64, 0x7e, 0xc7, 0xcc, 0x72, 0xb1, 0x73, 0x4b, 0x11,
+ 0x07, 0x52, 0xf0, 0x20, 0x96, 0x8b, 0x99, 0x39, 0xde, 0xdb, 0xfa, 0x3d,
+ 0x45, 0xe2, 0x98, 0x7b, 0x0c, 0x41, 0xe4, 0x0c, 0xb5, 0x5d, 0x92, 0x74,
+ 0x39, 0x96, 0xe1, 0x97, 0x97, 0xa1, 0xad, 0x2e, 0xcc, 0xd0, 0x1b, 0x4d,
+ 0x9d, 0xbd, 0x3e, 0xa9, 0x36, 0x8e, 0xcc, 0xc7, 0x5f, 0x6a, 0x7d, 0x39,
+ 0x5e, 0x0b, 0x8d, 0xca, 0xe4, 0x83, 0xe9, 0x3b, 0x5c, 0x86, 0x47, 0xd4,
+ 0xba, 0x7d, 0x98, 0x26, 0xa1, 0xf4, 0xe8, 0x90, 0x6b, 0x0f, 0xf1, 0x6b,
+ 0x8c, 0xe3, 0xa2, 0x80, 0x3c, 0x96, 0xf1, 0x0a, 0xb6, 0x66, 0xc0, 0x4b,
+ 0x61, 0xf7, 0x74, 0xcd, 0xd3, 0x7b, 0x8e, 0x5e, 0x39, 0xda, 0x99, 0x20,
+ 0x33, 0x93, 0xd3, 0xf0, 0x7f, 0xad, 0x35, 0xe9, 0x88, 0x8d, 0x9c, 0xbf,
+ 0x65, 0xf1, 0x47, 0x02, 0xf9, 0x7c, 0xed, 0x27, 0x5f, 0x4a, 0x65, 0x3c,
+ 0xcf, 0x5f, 0x0e, 0x88, 0x95, 0x74, 0xde, 0xfb, 0x9e, 0x2e, 0x91, 0x9b,
+ 0x45, 0x37, 0xc8, 0x85, 0xff, 0xe3, 0x41, 0x70, 0xfe, 0xd5, 0xef, 0x0e,
+ 0x82, 0x22, 0x08, 0xb7, 0x3b, 0x44, 0x3e, 0xdc, 0x5b, 0x7f, 0xba, 0xbf,
+ 0xe6, 0x58, 0x9d, 0x02, 0x6e, 0x75, 0xbf, 0x50, 0xec, 0xcf, 0x3f, 0xa5,
+ 0x91, 0x0a, 0xe2, 0x59, 0x2c, 0xc3, 0xe7, 0x05, 0x03, 0xe8, 0xf2, 0x6f,
+ 0x2a, 0x04, 0x68, 0x9a, 0x31, 0x32, 0x8f, 0x04, 0x35, 0xcd, 0x1f, 0x34,
+ 0xcc, 0x4f, 0x79, 0x5a, 0x99, 0x8d, 0x9d, 0x5c, 0xf5, 0x02, 0x03, 0x01,
+ 0x00, 0x01, 0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03,
+ 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, 0x06,
+ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x65, 0xc5, 0xbe, 0xca,
+ 0xe6, 0x59, 0x6a, 0xfd, 0x6c, 0x71, 0xc4, 0xa7, 0x98, 0xc6, 0x25, 0x8d,
+ 0x7b, 0x67, 0x05, 0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x81, 0xf8, 0xee, 0x47, 0x5c, 0x3e, 0xed,
+ 0xfb, 0xce, 0xa5, 0x84, 0xbe, 0xd7, 0xae, 0xdb, 0xd3, 0x7d, 0x64, 0xb3,
+ 0x2a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x66, 0x1e, 0x3d,
+ 0x1d, 0x53, 0x33, 0xde, 0x4e, 0xc7, 0xc4, 0xf4, 0xdf, 0xda, 0x18, 0x19,
+ 0x8a, 0xa9, 0xff, 0xe2, 0x63, 0x2b, 0xbe, 0xf2, 0x61, 0x63, 0xe2, 0xf6,
+ 0xed, 0x47, 0x1a, 0x71, 0x02, 0xec, 0x2a, 0xef, 0x89, 0x77, 0xe3, 0xfd,
+ 0x86, 0x69, 0xf1, 0x3f, 0x0d, 0xf9, 0x6e, 0xf9, 0x3b, 0xad, 0x26, 0x47,
+ 0xb7, 0xf2, 0x0d, 0xad, 0x23, 0xa3, 0x67, 0x3b, 0xcb, 0x6d, 0x9e, 0x03,
+ 0x0f, 0xbc, 0x69, 0x73, 0x9f, 0xd4, 0xa5, 0x0f, 0x6f, 0xf8, 0xab, 0x4d,
+ 0x36, 0xd1, 0xe0, 0xe0, 0x5d, 0x20, 0x43, 0x90, 0xc4, 0x65, 0x61, 0x93,
+ 0xe2, 0x0f, 0x51, 0x59, 0x0a, 0xf7, 0x88, 0x70, 0x57, 0xb9, 0x04, 0xa9,
+ 0x32, 0x57, 0x9c, 0xb3, 0x57, 0x38, 0x8b, 0x8e, 0x46, 0xc8, 0x32, 0x6c,
+ 0xb4, 0xf3, 0x96, 0x7f, 0x4b, 0xf0, 0x88, 0xf9, 0x7f, 0xe2, 0x71, 0xe1,
+ 0x8b, 0xe2, 0x14, 0xf1, 0x4b, 0x25, 0x00, 0x48, 0x1c, 0x7e, 0xe5, 0x8d,
+ 0x65, 0x2d, 0xeb, 0x72, 0x4f, 0x92, 0x44, 0xf3, 0xe6, 0xe0, 0xd0, 0xdf,
+ 0x85, 0xa8, 0x13, 0x4a, 0xfb, 0x99, 0xca, 0x14, 0x2c, 0x97, 0x80, 0x93,
+ 0x27, 0xd3, 0x20, 0xf8, 0x6d, 0x29, 0x28, 0x2c, 0xb9, 0x77, 0xea, 0xb1,
+ 0x63, 0xbd, 0x7d, 0x53, 0xfd, 0x4a, 0x62, 0x64, 0x0b, 0x98, 0xa8, 0xae,
+ 0x11, 0xfc, 0x6e, 0x8d, 0x63, 0xd4, 0x15, 0x55, 0xc6, 0x4c, 0x74, 0xf5,
+ 0x5f, 0xa0, 0xb9, 0x2c, 0x2d, 0x9a, 0x7a, 0x87, 0x6e, 0xf0, 0x5e, 0x25,
+ 0xed, 0xfc, 0xd8, 0xc4, 0x34, 0x33, 0x32, 0xad, 0x01, 0xd4, 0x4b, 0x49,
+ 0x51, 0xc2, 0x07, 0x7f, 0x90, 0x6d, 0xea, 0xf5, 0x4c, 0x41, 0x71, 0x64,
+ 0xeb, 0x1f, 0x29, 0xa3, 0x1f, 0x64, 0xa2, 0x1e, 0x0e, 0x6f, 0xa1, 0x67,
+ 0x99, 0x8d, 0x98, 0x1c, 0xb8, 0x53, 0x9d, 0x30, 0x1d, 0xae, 0x32, 0x56,
+ 0xd2
+};
+unsigned int certificate_printable_der_len = 829;

View File

@ -0,0 +1,329 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 1 Oct 2020 13:02:09 +1000
Subject: [PATCH] appended signatures: documentation
This explains how appended signatures can be used to form part of
a secure boot chain, and documents the commands and variables
introduced.
(docs: s/grub/grub2/)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 172 insertions(+), 13 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index a833364d5ff..97f0f47e082 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3160,6 +3160,7 @@ These variables have special meaning to GRUB.
@menu
* biosnum::
+* check_appended_signatures::
* check_signatures::
* chosen::
* cmdpath::
@@ -3219,11 +3220,18 @@ For an alternative approach which also changes BIOS drive mappings for the
chain-loaded system, @pxref{drivemap}.
+@node check_appended_signatures
+@subsection check_appended_signatures
+
+This variable controls whether GRUB enforces appended signature validation on
+certain loaded files. @xref{Using appended signatures}.
+
+
@node check_signatures
@subsection check_signatures
-This variable controls whether GRUB enforces digital signature
-validation on loaded files. @xref{Using digital signatures}.
+This variable controls whether GRUB enforces GPG-style digital signature
+validation on loaded files. @xref{Using GPG-style digital signatures}.
@node chosen
@subsection chosen
@@ -3937,6 +3945,7 @@ you forget a command, you can run the command @command{help}
* date:: Display or set current date and time
* devicetree:: Load a device tree blob
* distrust:: Remove a pubkey from trusted keys
+* distrust_certificate:: Remove a certificate from the list of trusted certificates
* drivemap:: Map a drive to another
* echo:: Display a line of text
* eval:: Evaluate agruments as GRUB commands
@@ -3953,6 +3962,7 @@ you forget a command, you can run the command @command{help}
* keystatus:: Check key modifier status
* linux:: Load a Linux kernel
* linux16:: Load a Linux kernel (16-bit mode)
+* list_certificates:: List trusted certificates
* list_env:: List variables in environment block
* list_trusted:: List trusted public keys
* load_env:: Load variables from environment block
@@ -3989,9 +3999,11 @@ you forget a command, you can run the command @command{help}
* test:: Check file types and compare values
* true:: Do nothing, successfully
* trust:: Add public key to list of trusted keys
+* trust_certificate:: Add an x509 certificate to the list of trusted certificates
* unset:: Unset an environment variable
* uppermem:: Set the upper memory size
@comment * vbeinfo:: List available video modes
+* verify_appended:: Verify appended digital signature
* verify_detached:: Verify detached digital signature
* videoinfo:: List available video modes
@comment * xen_*:: Xen boot commands for AArch64
@@ -4282,9 +4294,28 @@ These keys are used to validate signatures when environment variable
@code{check_signatures} is set to @code{enforce}
(@pxref{check_signatures}), and by some invocations of
@command{verify_detached} (@pxref{verify_detached}). @xref{Using
-digital signatures}, for more information.
+GPG-style digital signatures}, for more information.
@end deffn
+
+@node distrust_certificate
+@subsection distrust_certificate
+
+@deffn Command distrust_certificate cert_number
+Remove the x509 certificate numbered @var{cert_number} from GRUB's keyring of
+trusted x509 certificates for verifying appended signatures.
+
+@var{cert_number} is the certificate number as listed by
+@command{list_certificates} (@pxref{list_certificates}).
+
+These certificates are used to validate appended signatures when environment
+variable @code{check_appended_signatures} is set to @code{enforce}
+(@pxref{check_appended_signatures}), and by @command{verify_appended}
+(@pxref{verify_appended}). See @xref{Using appended signatures} for more
+information.
+@end deffn
+
+
@node drivemap
@subsection drivemap
@@ -4542,6 +4573,21 @@ This command is only available on x86 systems.
@end deffn
+@node list_certificates
+@subsection list_certificates
+
+@deffn Command list_certificates
+List all x509 certificates trusted by GRUB for validating appended signatures.
+The output is a numbered list of certificates, showing the certificate's serial
+number and Common Name.
+
+The certificate number can be used as an argument to
+@command{distrust_certificate} (@pxref{distrust_certificate}).
+
+See @xref{Using appended signatures} for more information.
+@end deffn
+
+
@node list_env
@subsection list_env
@@ -4561,7 +4607,7 @@ The output is in GPG's v4 key fingerprint format (i.e., the output of
@code{gpg --fingerprint}). The least significant four bytes (last
eight hexadecimal digits) can be used as an argument to
@command{distrust} (@pxref{distrust}).
-@xref{Using digital signatures}, for more information about uses for
+@xref{Using GPG-style digital signatures}, for more information about uses for
these keys.
@end deffn
@@ -4596,8 +4642,12 @@ When used with care, @option{--skip-sig} and the whitelist enable an
administrator to configure a system to boot only signed
configurations, but to allow the user to select from among multiple
configurations, and to enable ``one-shot'' boot attempts and
-``savedefault'' behavior. @xref{Using digital signatures}, for more
+``savedefault'' behavior. @xref{Using GPG-style digital signatures}, for more
information.
+
+Extra care should be taken when combining this command with appended signatures
+(@pxref{Using appended signatures}), as this file is not validated by an
+appended signature and could set @code{check_appended_signatures=no}.
@end deffn
@@ -4883,7 +4933,7 @@ read. It is possible to modify a digitally signed environment block
file from within GRUB using this command, such that its signature will
no longer be valid on subsequent boots. Care should be taken in such
advanced configurations to avoid rendering the system
-unbootable. @xref{Using digital signatures}, for more information.
+unbootable. @xref{Using GPG-style digital signatures}, for more information.
@end deffn
@@ -5208,11 +5258,31 @@ signatures when environment variable @code{check_signatures} is set to
must itself be properly signed. The @option{--skip-sig} option can be
used to disable signature-checking when reading @var{pubkey_file}
itself. It is expected that @option{--skip-sig} is useful for testing
-and manual booting. @xref{Using digital signatures}, for more
+and manual booting. @xref{Using GPG-style digital signatures}, for more
information.
@end deffn
+@node trust_certificate
+@subsection trust_certificate
+
+@deffn Command trust_certificate x509_certificate
+Read an DER-formatted x509 certificate from the file @var{x509_certificate}
+and add it to GRUB's internal list of trusted x509 certificates. These
+certificates are used to validate appended signatures when the environment
+variable @code{check_appended_signatures} is set to @code{enforce}.
+
+Note that if @code{check_appended_signatures} is set to @code{enforce}
+when @command{trust_certificate} is executed, then @var{x509_certificate}
+must itself bear an appended signature. (It is not sufficient that
+@var{x509_certificate} be signed by a trusted certificate according to the
+x509 rules: grub does not include support for validating signatures within x509
+certificates themselves.)
+
+See @xref{Using appended signatures} for more information.
+@end deffn
+
+
@node unset
@subsection unset
@@ -5237,6 +5307,18 @@ only on PC BIOS platforms.
@end deffn
@end ignore
+@node verify_appended
+@subsection verify_appended
+
+@deffn Command verify_appended file
+Verifies an appended signature on @var{file} against the trusted certificates
+known to GRUB (See @pxref{list_certificates}, @pxref{trust_certificate}, and
+@pxref{distrust_certificate}).
+
+Exit code @code{$?} is set to 0 if the signature validates
+successfully. If validation fails, it is set to a non-zero value.
+See @xref{Using appended signatures}, for more information.
+@end deffn
@node verify_detached
@subsection verify_detached
@@ -5255,7 +5337,7 @@ tried.
Exit code @code{$?} is set to 0 if the signature validates
successfully. If validation fails, it is set to a non-zero value.
-@xref{Using digital signatures}, for more information.
+@xref{Using GPG-style digital signatures}, for more information.
@end deffn
@node videoinfo
@@ -5601,9 +5683,10 @@ environment variables and commands are listed in the same order.
@chapter Security
@menu
-* Authentication and authorisation:: Users and access control
-* Using digital signatures:: Booting digitally signed code
-* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
+* Authentication and authorisation:: Users and access control
+* Using GPG-style digital signatures:: Booting digitally signed code
+* Using appended signatures:: An alternative approach to booting digitally signed code
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
@end menu
@node Authentication and authorisation
@@ -5676,8 +5759,8 @@ generating configuration files with authentication. You can use
adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2}
commands.
-@node Using digital signatures
-@section Using digital signatures in GRUB
+@node Using GPG-style digital signatures
+@section Using GPG-style digital signatures in GRUB
GRUB's @file{core.img} can optionally provide enforcement that all files
subsequently read from disk are covered by a valid digital signature.
@@ -5760,6 +5843,82 @@ or BIOS) configuration to cause the machine to boot from a different
(attacker-controlled) device. GRUB is at best only one link in a
secure boot chain.
+@node Using appended signatures
+@section Using appended signatures in GRUB
+
+GRUB supports verifying Linux-style 'appended signatures' for secure boot.
+Appended signatures are PKCS#7 messages containing a signature over the
+contents of a file, plus some metadata, appended to the end of a file. A file
+with an appended signature ends with the magic string:
+
+@example
+~Module signature appended~\n
+@end example
+
+where @code{\n} represents the carriage-return character, @code{0x0a}.
+
+To enable appended signature verification, load the appendedsig module and an
+x509 certificate for verification. Building the appendedsig module into the
+core grub image is recommended.
+
+Certificates can be managed at boot time using the @pxref{trust_certificate},
+@pxref{distrust_certificate} and @pxref{list_certificates} commands.
+Certificates can also be built in to the core image using the @code{--x509}
+parameter to @command{grub-install} or @command{grub-mkimage}.
+
+A file can be explictly verified using the @pxref{verify_appended} command.
+
+Only signatures made with the SHA-256 or SHA-512 hash algorithm are supported,
+and only RSA signatures are supported.
+
+A file can be signed with the @command{sign-file} utility supplied with the
+Linux kernel source. For example, if you have @code{signing.key} as the private
+key and @code{certificate.der} as the x509 certificate containing the public key:
+
+@example
+sign-file SHA256 signing.key certificate.der vmlinux vmlinux.signed
+@end example
+
+Enforcement of signature verification is controlled by the
+@code{check_appended_signatures} variable. Verification will only take place
+when files are loaded if the variable is set to @code{enforce}. If a
+certificate is built into the grub core image with the @code{--x509} parameter,
+the variable will be automatically set to @code{enforce} when the appendedsig
+module is loaded.
+
+Unlike GPG-style signatures, not all files loaded by GRUB are required to be
+signed. Once verification is turned on, the following file types must carry
+appended signatures:
+
+@enumerate
+@item Linux, Multiboot, BSD, XNU and Plan9 kernels
+@item Grub modules, except those built in to the core image
+@item Any new certificate files to be trusted
+@end enumerate
+
+ACPI tables and Device Tree images will not be checked for appended signatures
+but must be verified by another mechanism such as GPG-style signatures before
+they will be loaded.
+
+No attempt is made to validate any other file type. In particular,
+chain-loaded binaries are not verified - if your platform supports
+chain-loading and this cannot be disabled, consider an alternative secure
+boot mechanism.
+
+As with GPG-style appended signatures, signature checking does @strong{not}
+stop an attacker with console access from dropping manually to the GRUB
+console and executing:
+
+@example
+set check_appended_signatures=no
+@end example
+
+Refer to the section on password-protecting GRUB (@pxref{Authentication
+and authorisation}) for more information on preventing this.
+
+Additionally, special care must be taken around the @command{loadenv} command,
+which can be used to turn off @code{check_appended_signature}.
+
@node Signing GRUB itself
@section Signing GRUB itself

View File

@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 28 Sep 2020 11:11:17 +1000
Subject: [PATCH] ieee1275: link appended-signature enforcement to
/ibm,secure-boot
If the 'ibm,secure-boot' property of the root node is 2 or greater,
require that the kernel pass appended-signature verification.
Do not consider the presence of a certificate to enforce verification.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/appendedsig/appendedsig.c | 44 +++++++++++++++++++++-------
grub-core/kern/ieee1275/init.c | 26 ++++++++++++++++
2 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
index 5d8897be5c8..4ef2ec2893c 100644
--- a/grub-core/commands/appendedsig/appendedsig.c
+++ b/grub-core/commands/appendedsig/appendedsig.c
@@ -95,10 +95,24 @@ static char *
grub_env_write_sec (struct grub_env_var *var __attribute__((unused)),
const char *val)
{
+ if (check_sigs == 2)
+ return grub_strdup ("forced");
check_sigs = (*val == '1') || (*val == 'e');
return grub_strdup (check_sigs ? "enforce" : "no");
}
+static const char *
+grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val __attribute__ ((unused)))
+{
+ if (check_sigs == 2)
+ return "forced";
+ else if (check_sigs == 1)
+ return "enforce";
+ else
+ return "no";
+}
+
static grub_err_t
read_cert_from_file (grub_file_t f, struct x509_certificate *certificate)
{
@@ -552,14 +566,20 @@ GRUB_MOD_INIT (appendedsig)
val = grub_env_get ("check_appended_signatures");
grub_dprintf ("appendedsig", "check_appended_signatures='%s'\n", val);
- if (val && (val[0] == '1' || val[0] == 'e'))
- check_sigs = 1;
- else
- check_sigs = 0;
+ if (val)
+ {
+ if (val[0] == '2' || val[0] == 'f')
+ check_sigs = 2;
+ else if (val[0] == '1' || val[0] == 'e')
+ check_sigs = 1;
+ else
+ check_sigs = 0;
+ }
grub_trusted_key = NULL;
- grub_register_variable_hook ("check_appended_signatures", 0,
+ grub_register_variable_hook ("check_appended_signatures",
+ grub_env_read_sec,
grub_env_write_sec);
grub_env_export ("check_appended_signatures");
@@ -603,11 +623,15 @@ GRUB_MOD_INIT (appendedsig)
grub_trusted_key = pk;
}
- if (!val || val[0] == '\0')
- {
- grub_env_set ("check_appended_signatures",
- grub_trusted_key ? "enforce" : "no");
- }
+ /*
+ * When controlled by ibm,secure-boot, we don't want the presence of
+ * a certificate to enforce secure boot.
+ * if (!val || val[0] == '\0')
+ * {
+ * grub_env_set ("check_appended_signatures",
+ * grub_trusted_key ? "enforce" : "no");
+ * }
+ */
cmd_trust =
grub_register_command ("trust_certificate", grub_cmd_trust,
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index e731a57a47b..22dc3013d86 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -268,6 +268,30 @@ grub_parse_cmdline (void)
}
}
+static void
+grub_get_ieee1275_secure_boot (void)
+{
+ grub_ieee1275_phandle_t root;
+ int rc;
+ grub_uint32_t is_sb;
+
+ grub_ieee1275_finddevice ("/", &root);
+
+ rc = grub_ieee1275_get_integer_property (root, "ibm,secure-boot", &is_sb,
+ sizeof (is_sb), 0);
+
+ /* ibm,secure-boot:
+ * 0 - disabled
+ * 1 - audit
+ * 2 - enforce
+ * 3 - enforce + OS-specific behaviour
+ *
+ * We only support enforce.
+ */
+ if (rc >= 0 && is_sb >= 2)
+ grub_env_set("check_appended_signatures", "forced");
+}
+
grub_addr_t grub_modbase;
void
@@ -290,6 +314,8 @@ grub_machine_init (void)
#else
grub_install_get_time_ms (grub_rtc_get_time_ms);
#endif
+
+ grub_get_ieee1275_secure_boot ();
}
void

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <leif.lindholm@linaro.org>
Date: Wed, 14 Nov 2018 19:29:15 +0000
Subject: [PATCH] include/grub/verify.h: Add include guard
verify.h was added without include guards. This means compiling anything
including both include/grub/verify.h and include/grub/lib/cmdline.h fails
(at least grub-core/loader/arm64/linux.c.
Add the necessary include guard.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
include/grub/verify.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 60c13e7ea8e..ace72d74663 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -16,6 +16,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef GRUB_VERIFY_HEADER
+#define GRUB_VERIFY_HEADER 1
+
#include <grub/file.h>
#include <grub/list.h>
@@ -89,3 +92,5 @@ char grub_is_dangerous_module (grub_file_t io);
* Returns the name if one is loaded, otherwise NULL.
*/
const char *grub_dangerous_module_loaded (void);
+
+#endif /* ! GRUB_VERIFY_HEADER */

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lee Jones <lee.jones@linaro.org>
Date: Tue, 20 Nov 2018 10:45:04 +0000
Subject: [PATCH] arm64/xen: Fix too few arguments to function
grub_create_loader_cmdline()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Without this fix, building xen_boot.c omits:
loader/arm64/xen_boot.c: In function xen_boot_binary_load:
loader/arm64/xen_boot.c:370:7: error: too few arguments to function grub_create_loader_cmdline
grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from loader/arm64/xen_boot.c:36:0:
../include/grub/lib/cmdline.h:29:12: note: declared here
grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf,
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/arm64/xen_boot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
index 318c833de57..1a337866f08 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -367,7 +367,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
return;
}
grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
- binary->cmdline_size);
+ binary->cmdline_size,
+ GRUB_VERIFY_KERNEL_CMDLINE);
grub_dprintf ("xen_loader",
"Xen_boot cmdline @ %p %s, size: %d\n",
binary->cmdline, binary->cmdline, binary->cmdline_size);

View File

@ -0,0 +1,440 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Fri, 19 Feb 2021 10:33:54 +0100
Subject: [PATCH] kern: Add lockdown support
When the GRUB starts on a secure boot platform, some commands can be
used to subvert the protections provided by the verification mechanism and
could lead to booting untrusted system.
To prevent that situation, allow GRUB to be locked down. That way the code
may check if GRUB has been locked down and further restrict the commands
that are registered or what subset of their functionality could be used.
The lockdown support adds the following components:
* The grub_lockdown() function which can be used to lockdown GRUB if,
e.g., UEFI Secure Boot is enabled.
* The grub_is_lockdown() function which can be used to check if the GRUB
was locked down.
* A verifier that flags OS kernels, the GRUB modules, Device Trees and ACPI
tables as GRUB_VERIFY_FLAGS_DEFER_AUTH to defer verification to other
verifiers. These files are only successfully verified if another registered
verifier returns success. Otherwise, the whole verification process fails.
For example, PE/COFF binaries verification can be done by the shim_lock
verifier which validates the signatures using the shim_lock protocol.
However, the verification is not deferred directly to the shim_lock verifier.
The shim_lock verifier is hooked into the verification process instead.
* A set of grub_{command,extcmd}_lockdown functions that can be used by
code registering command handlers, to only register unsafe commands if
the GRUB has not been locked down.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/Makefile.core.def | 1 +
grub-core/commands/extcmd.c | 23 +++++++++++
grub-core/kern/command.c | 24 ++++++++++++
grub-core/kern/lockdown.c | 93 +++++++++++++++++++++++++++++++++++++++++++++
include/grub/command.h | 5 +++
include/grub/extcmd.h | 7 ++++
include/grub/lockdown.h | 44 +++++++++++++++++++++
conf/Makefile.common | 2 +
docs/grub-dev.texi | 27 +++++++++++++
docs/grub.texi | 8 ++++
grub-core/Makefile.am | 5 ++-
11 files changed, 238 insertions(+), 1 deletion(-)
create mode 100644 grub-core/kern/lockdown.c
create mode 100644 include/grub/lockdown.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8914083d13f..02fbecd4b81 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -197,6 +197,7 @@ kernel = {
efi = term/efi/console.c;
efi = kern/acpi.c;
efi = kern/efi/acpi.c;
+ efi = kern/lockdown.c;
efi = lib/envblk.c;
efi = kern/efi/tpm.c;
i386_coreboot = kern/i386/pc/acpi.c;
diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
index 69574e2b05b..90a5ca24a64 100644
--- a/grub-core/commands/extcmd.c
+++ b/grub-core/commands/extcmd.c
@@ -19,6 +19,7 @@
#include <grub/mm.h>
#include <grub/list.h>
+#include <grub/lockdown.h>
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/script_sh.h>
@@ -110,6 +111,28 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func,
summary, description, parser, 1);
}
+static grub_err_t
+grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **argv __attribute__ ((unused)))
+{
+ return grub_error (GRUB_ERR_ACCESS_DENIED,
+ N_("%s: the command is not allowed when lockdown is enforced"),
+ ctxt->extcmd->cmd->name);
+}
+
+grub_extcmd_t
+grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func,
+ grub_command_flags_t flags, const char *summary,
+ const char *description,
+ const struct grub_arg_option *parser)
+{
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
+ func = grub_extcmd_lockdown;
+
+ return grub_register_extcmd (name, func, flags, summary, description, parser);
+}
+
void
grub_unregister_extcmd (grub_extcmd_t ext)
{
diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c
index acd72187992..4aabcd4b5f9 100644
--- a/grub-core/kern/command.c
+++ b/grub-core/kern/command.c
@@ -17,6 +17,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <grub/lockdown.h>
#include <grub/mm.h>
#include <grub/command.h>
@@ -77,6 +78,29 @@ grub_register_command_prio (const char *name,
return cmd;
}
+static grub_err_t
+grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **argv __attribute__ ((unused)))
+
+{
+ return grub_error (GRUB_ERR_ACCESS_DENIED,
+ N_("%s: the command is not allowed when lockdown is enforced"),
+ cmd->name);
+}
+
+grub_command_t
+grub_register_command_lockdown (const char *name,
+ grub_command_func_t func,
+ const char *summary,
+ const char *description)
+{
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
+ func = grub_cmd_lockdown;
+
+ return grub_register_command_prio (name, func, summary, description, 0);
+}
+
void
grub_unregister_command (grub_command_t cmd)
{
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
new file mode 100644
index 00000000000..f87ddaeb1ee
--- /dev/null
+++ b/grub-core/kern/lockdown.c
@@ -0,0 +1,93 @@
+/*
+ * 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/>.
+ *
+ */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/lockdown.h>
+
+/* There is no verifier framework in grub 2.02 */
+#if 0
+#include <grub/verify.h>
+#endif
+
+static int lockdown = GRUB_LOCKDOWN_DISABLED;
+
+/* There is no verifier framework in grub 2.02 */
+#if 0
+static grub_err_t
+lockdown_verifier_init (grub_file_t io __attribute__ ((unused)),
+ enum grub_file_type type,
+ void **context __attribute__ ((unused)),
+ enum grub_verify_flags *flags)
+{
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+
+ switch (type & GRUB_FILE_TYPE_MASK)
+ {
+ case GRUB_FILE_TYPE_GRUB_MODULE:
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
+ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
+ case GRUB_FILE_TYPE_XEN_HYPERVISOR:
+ case GRUB_FILE_TYPE_BSD_KERNEL:
+ case GRUB_FILE_TYPE_XNU_KERNEL:
+ case GRUB_FILE_TYPE_PLAN9_KERNEL:
+ case GRUB_FILE_TYPE_NTLDR:
+ case GRUB_FILE_TYPE_TRUECRYPT:
+ case GRUB_FILE_TYPE_FREEDOS:
+ case GRUB_FILE_TYPE_PXECHAINLOADER:
+ case GRUB_FILE_TYPE_PCCHAINLOADER:
+ case GRUB_FILE_TYPE_COREBOOT_CHAINLOADER:
+ case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
+ case GRUB_FILE_TYPE_ACPI_TABLE:
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
+
+ /* Fall through. */
+
+ default:
+ return GRUB_ERR_NONE;
+ }
+}
+
+struct grub_file_verifier lockdown_verifier =
+ {
+ .name = "lockdown_verifier",
+ .init = lockdown_verifier_init,
+ };
+#endif
+
+void
+grub_lockdown (void)
+{
+ lockdown = GRUB_LOCKDOWN_ENABLED;
+
+ /*
+ * XXX: The lockdown verifier doesn't make sense until
+ * GRUB has moved to the shim_lock verifier.
+ */
+#if 0
+ grub_verifier_register (&lockdown_verifier);
+#endif
+}
+
+int
+grub_is_lockdown (void)
+{
+ return lockdown;
+}
diff --git a/include/grub/command.h b/include/grub/command.h
index eee4e847ee4..2a6f7f84697 100644
--- a/include/grub/command.h
+++ b/include/grub/command.h
@@ -86,6 +86,11 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name,
const char *summary,
const char *description,
int prio);
+grub_command_t
+EXPORT_FUNC(grub_register_command_lockdown) (const char *name,
+ grub_command_func_t func,
+ const char *summary,
+ const char *description);
void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd);
static inline grub_command_t
diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h
index 19fe592669e..fe9248b8bb6 100644
--- a/include/grub/extcmd.h
+++ b/include/grub/extcmd.h
@@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name,
const char *description,
const struct grub_arg_option *parser);
+grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name,
+ grub_extcmd_func_t func,
+ grub_command_flags_t flags,
+ const char *summary,
+ const char *description,
+ const struct grub_arg_option *parser);
+
grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name,
grub_extcmd_func_t func,
grub_command_flags_t flags,
diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h
new file mode 100644
index 00000000000..40531fa823b
--- /dev/null
+++ b/include/grub/lockdown.h
@@ -0,0 +1,44 @@
+/*
+ * 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/>.
+ */
+
+#ifndef GRUB_LOCKDOWN_H
+#define GRUB_LOCKDOWN_H 1
+
+#include <grub/symbol.h>
+
+#define GRUB_LOCKDOWN_DISABLED 0
+#define GRUB_LOCKDOWN_ENABLED 1
+
+#ifdef GRUB_MACHINE_EFI
+extern void
+EXPORT_FUNC (grub_lockdown) (void);
+extern int
+EXPORT_FUNC (grub_is_lockdown) (void);
+#else
+static inline void
+grub_lockdown (void)
+{
+}
+
+static inline int
+grub_is_lockdown (void)
+{
+ return GRUB_LOCKDOWN_DISABLED;
+}
+#endif
+#endif /* ! GRUB_LOCKDOWN_H */
diff --git a/conf/Makefile.common b/conf/Makefile.common
index b93879804c0..521cdda1f5a 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -85,7 +85,9 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER
CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)'
+CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)'
+CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)'
CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \
diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
index 3ce827ab726..421dd410e50 100644
--- a/docs/grub-dev.texi
+++ b/docs/grub-dev.texi
@@ -84,6 +84,7 @@ This edition documents version @value{VERSION}.
* Video Subsystem::
* PFF2 Font File Format::
* Graphical Menu Software Design::
+* Lockdown framework::
* Copying This Manual:: Copying This Manual
* Index::
@end menu
@@ -1949,6 +1950,32 @@ the graphics mode that was in use before @code{grub_video_setup()} was called
might fix some of the problems.
+@node Lockdown framework
+@chapter Lockdown framework
+
+The GRUB can be locked down, which is a restricted mode where some operations
+are not allowed. For instance, some commands cannot be used when the GRUB is
+locked down.
+
+The function
+@code{grub_lockdown()} is used to lockdown GRUB and the function
+@code{grub_is_lockdown()} function can be used to check whether lockdown is
+enabled or not. When enabled, the function returns @samp{GRUB_LOCKDOWN_ENABLED}
+and @samp{GRUB_LOCKDOWN_DISABLED} when is not enabled.
+
+The following functions can be used to register the commands that can only be
+used when lockdown is disabled:
+
+@itemize
+
+@item @code{grub_cmd_lockdown()} registers command which should not run when the
+GRUB is in lockdown mode.
+
+@item @code{grub_cmd_lockdown()} registers extended command which should not run
+when the GRUB is in lockdown mode.
+
+@end itemize
+
@node Copying This Manual
@appendix Copying This Manual
diff --git a/docs/grub.texi b/docs/grub.texi
index 97f0f47e082..f957535dbea 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5687,6 +5687,7 @@ environment variables and commands are listed in the same order.
* Using GPG-style digital signatures:: Booting digitally signed code
* Using appended signatures:: An alternative approach to booting digitally signed code
* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
+* Lockdown:: Lockdown when booting on a secure setup
@end menu
@node Authentication and authorisation
@@ -5977,6 +5978,13 @@ As with UEFI secure boot, it is necessary to build in the required modules,
or sign them separately.
+@node Lockdown
+@section Lockdown when booting on a secure setup
+
+The GRUB can be locked down when booted on a secure boot environment, for example
+if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will
+be restricted and some operations/commands cannot be executed.
+
@node Platform limitations
@chapter Platform limitations
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index 4062652506d..a6f1b0dcd06 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -82,6 +82,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
@@ -350,8 +351,10 @@ command.lst: $(MARKER_FILES)
b=`basename $$pp .marker`; \
sed -n \
-e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
+ -e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
-e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
- -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
+ -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \
+ -e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
done) | sort -u > $@
platform_DATA += command.lst
CLEANFILES += command.lst

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Tue, 2 Feb 2021 19:59:48 +0100
Subject: [PATCH] kern/lockdown: Set a variable if the GRUB is locked down
It may be useful for scripts to determine whether the GRUB is locked
down or not. Add the lockdown variable which is set to "y" when the GRUB
is locked down.
Suggested-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/lockdown.c | 4 ++++
docs/grub.texi | 3 +++
2 files changed, 7 insertions(+)
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
index f87ddaeb1ee..30cba7f5ea2 100644
--- a/grub-core/kern/lockdown.c
+++ b/grub-core/kern/lockdown.c
@@ -18,6 +18,7 @@
*/
#include <grub/dl.h>
+#include <grub/env.h>
#include <grub/file.h>
#include <grub/lockdown.h>
@@ -84,6 +85,9 @@ grub_lockdown (void)
#if 0
grub_verifier_register (&lockdown_verifier);
#endif
+
+ grub_env_set ("lockdown", "y");
+ grub_env_export ("lockdown");
}
int
diff --git a/docs/grub.texi b/docs/grub.texi
index f957535dbea..755de88d7d8 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5985,6 +5985,9 @@ The GRUB can be locked down when booted on a secure boot environment, for exampl
if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will
be restricted and some operations/commands cannot be executed.
+The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
+Otherwise it does not exit.
+
@node Platform limitations
@chapter Platform limitations

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Mon, 28 Sep 2020 20:08:29 +0200
Subject: [PATCH] efi: Lockdown the GRUB when the UEFI Secure Boot is enabled
If the UEFI Secure Boot is enabled then the GRUB must be locked down
to prevent executing code that can potentially be used to subvert its
verification mechanisms.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/init.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 79243b364a1..97bf36906a4 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -20,6 +20,8 @@
#include <grub/efi/efi.h>
#include <grub/efi/console.h>
#include <grub/efi/disk.h>
+#include <grub/efi/sb.h>
+#include <grub/lockdown.h>
#include <grub/term.h>
#include <grub/misc.h>
#include <grub/env.h>
@@ -93,6 +95,23 @@ grub_efi_init (void)
/* Initialize the memory management system. */
grub_efi_mm_init ();
+ /*
+ * Lockdown the GRUB and register the shim_lock verifier
+ * if the UEFI Secure Boot is enabled.
+ */
+ if (grub_efi_secure_boot ())
+ {
+ grub_lockdown ();
+
+ /*
+ * TODO: Move GRUB to using the shim_lock verifier and
+ * enable the lockdown verifier.
+ */
+#if 0
+ grub_shim_lock_verifier_setup ();
+#endif
+ }
+
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
0, 0, 0, NULL);

View File

@ -0,0 +1,137 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Mon, 28 Sep 2020 20:08:33 +0200
Subject: [PATCH] efi: Use grub_is_lockdown() instead of hardcoding a disabled
modules list
Now the GRUB can check if it has been locked down and this can be used to
prevent executing commands that can be utilized to circumvent the UEFI
Secure Boot mechanisms. So, instead of hardcoding a list of modules that
have to be disabled, prevent the usage of commands that can be dangerous.
This not only allows the commands to be disabled on other platforms, but
also properly separate the concerns. Since the shim_lock verifier logic
should be only about preventing to run untrusted binaries and not about
defining these kind of policies.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/iorw.c | 26 ++++++++++----------------
grub-core/commands/memrw.c | 26 ++++++++++----------------
2 files changed, 20 insertions(+), 32 deletions(-)
diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c
index 41a7f3f0466..584baec8f91 100644
--- a/grub-core/commands/iorw.c
+++ b/grub-core/commands/iorw.c
@@ -23,7 +23,7 @@
#include <grub/env.h>
#include <grub/cpu/io.h>
#include <grub/i18n.h>
-#include <grub/efi/sb.h>
+#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -119,9 +119,6 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
GRUB_MOD_INIT(memrw)
{
- if (grub_efi_secure_boot())
- return;
-
cmd_read_byte =
grub_register_extcmd ("inb", grub_cmd_read, 0,
N_("PORT"), N_("Read 8-bit value from PORT."),
@@ -135,24 +132,21 @@ GRUB_MOD_INIT(memrw)
N_("PORT"), N_("Read 32-bit value from PORT."),
options);
cmd_write_byte =
- grub_register_command ("outb", grub_cmd_write,
- N_("PORT VALUE [MASK]"),
- N_("Write 8-bit VALUE to PORT."));
+ grub_register_command_lockdown ("outb", grub_cmd_write,
+ N_("PORT VALUE [MASK]"),
+ N_("Write 8-bit VALUE to PORT."));
cmd_write_word =
- grub_register_command ("outw", grub_cmd_write,
- N_("PORT VALUE [MASK]"),
- N_("Write 16-bit VALUE to PORT."));
+ grub_register_command_lockdown ("outw", grub_cmd_write,
+ N_("PORT VALUE [MASK]"),
+ N_("Write 16-bit VALUE to PORT."));
cmd_write_dword =
- grub_register_command ("outl", grub_cmd_write,
- N_("ADDR VALUE [MASK]"),
- N_("Write 32-bit VALUE to PORT."));
+ grub_register_command_lockdown ("outl", grub_cmd_write,
+ N_("ADDR VALUE [MASK]"),
+ N_("Write 32-bit VALUE to PORT."));
}
GRUB_MOD_FINI(memrw)
{
- if (grub_efi_secure_boot())
- return;
-
grub_unregister_extcmd (cmd_read_byte);
grub_unregister_extcmd (cmd_read_word);
grub_unregister_extcmd (cmd_read_dword);
diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
index 088cbe9e2bc..d401a6db0ef 100644
--- a/grub-core/commands/memrw.c
+++ b/grub-core/commands/memrw.c
@@ -22,7 +22,7 @@
#include <grub/extcmd.h>
#include <grub/env.h>
#include <grub/i18n.h>
-#include <grub/efi/sb.h>
+#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -121,9 +121,6 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
GRUB_MOD_INIT(memrw)
{
- if (grub_efi_secure_boot())
- return;
-
cmd_read_byte =
grub_register_extcmd ("read_byte", grub_cmd_read, 0,
N_("ADDR"), N_("Read 8-bit value from ADDR."),
@@ -137,24 +134,21 @@ GRUB_MOD_INIT(memrw)
N_("ADDR"), N_("Read 32-bit value from ADDR."),
options);
cmd_write_byte =
- grub_register_command ("write_byte", grub_cmd_write,
- N_("ADDR VALUE [MASK]"),
- N_("Write 8-bit VALUE to ADDR."));
+ grub_register_command_lockdown ("write_byte", grub_cmd_write,
+ N_("ADDR VALUE [MASK]"),
+ N_("Write 8-bit VALUE to ADDR."));
cmd_write_word =
- grub_register_command ("write_word", grub_cmd_write,
- N_("ADDR VALUE [MASK]"),
- N_("Write 16-bit VALUE to ADDR."));
+ grub_register_command_lockdown ("write_word", grub_cmd_write,
+ N_("ADDR VALUE [MASK]"),
+ N_("Write 16-bit VALUE to ADDR."));
cmd_write_dword =
- grub_register_command ("write_dword", grub_cmd_write,
- N_("ADDR VALUE [MASK]"),
- N_("Write 32-bit VALUE to ADDR."));
+ grub_register_command_lockdown ("write_dword", grub_cmd_write,
+ N_("ADDR VALUE [MASK]"),
+ N_("Write 32-bit VALUE to ADDR."));
}
GRUB_MOD_FINI(memrw)
{
- if (grub_efi_secure_boot())
- return;
-
grub_unregister_extcmd (cmd_read_byte);
grub_unregister_extcmd (cmd_read_word);
grub_unregister_extcmd (cmd_read_dword);

View File

@ -0,0 +1,72 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Mon, 28 Sep 2020 20:08:41 +0200
Subject: [PATCH] acpi: Don't register the acpi command when locked down
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The command is not allowed when lockdown is enforced. Otherwise an
attacker can instruct the GRUB to load an SSDT table to overwrite
the kernel lockdown configuration and later load and execute
unsigned code.
Fixes: CVE-2020-14372
Reported-by: Máté Kukri <km@mkukri.xyz>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/acpi.c | 15 ++++++++-------
docs/grub.texi | 5 +++++
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index 5a1499aa0e3..1215f2a62ef 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -27,6 +27,7 @@
#include <grub/mm.h>
#include <grub/memory.h>
#include <grub/i18n.h>
+#include <grub/lockdown.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
@@ -775,13 +776,13 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(acpi)
{
- cmd = grub_register_extcmd ("acpi", grub_cmd_acpi, 0,
- N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
- "--load-only=TABLE1,TABLE2] FILE1"
- " [FILE2] [...]"),
- N_("Load host ACPI tables and tables "
- "specified by arguments."),
- options);
+ cmd = grub_register_extcmd_lockdown ("acpi", grub_cmd_acpi, 0,
+ N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
+ "--load-only=TABLE1,TABLE2] FILE1"
+ " [FILE2] [...]"),
+ N_("Load host ACPI tables and tables "
+ "specified by arguments."),
+ options);
}
GRUB_MOD_FINI(acpi)
diff --git a/docs/grub.texi b/docs/grub.texi
index 755de88d7d8..01acf672b80 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4038,6 +4038,11 @@ Normally, this command will replace the Root System Description Pointer
(RSDP) in the Extended BIOS Data Area to point to the new tables. If the
@option{--no-ebda} option is used, the new tables will be known only to
GRUB, but may be used by GRUB's EFI emulation.
+
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
+ Otherwise an attacker can instruct the GRUB to load an SSDT table to
+ overwrite the kernel lockdown configuration and later load and execute
+ unsigned code.
@end deffn

View File

@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Wed, 14 Oct 2020 16:33:42 +0200
Subject: [PATCH] mmap: Don't register cutmem and badram commands when lockdown
is enforced
The cutmem and badram commands can be used to remove EFI memory regions
and potentially disable the UEFI Secure Boot. Prevent the commands to be
registered if the GRUB is locked down.
Fixes: CVE-2020-27779
Reported-by: Teddy Reed <teddy.reed@gmail.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/mmap/mmap.c | 13 +++++++------
docs/grub.texi | 4 ++++
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
index 57b4e9a72a9..7ebf32e1e5e 100644
--- a/grub-core/mmap/mmap.c
+++ b/grub-core/mmap/mmap.c
@@ -20,6 +20,7 @@
#include <grub/memory.h>
#include <grub/machine/memory.h>
#include <grub/err.h>
+#include <grub/lockdown.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/command.h>
@@ -534,12 +535,12 @@ static grub_command_t cmd, cmd_cut;
GRUB_MOD_INIT(mmap)
{
- cmd = grub_register_command ("badram", grub_cmd_badram,
- N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"),
- N_("Declare memory regions as faulty (badram)."));
- cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem,
- N_("FROM[K|M|G] TO[K|M|G]"),
- N_("Remove any memory regions in specified range."));
+ cmd = grub_register_command_lockdown ("badram", grub_cmd_badram,
+ N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"),
+ N_("Declare memory regions as faulty (badram)."));
+ cmd_cut = grub_register_command_lockdown ("cutmem", grub_cmd_cutmem,
+ N_("FROM[K|M|G] TO[K|M|G]"),
+ N_("Remove any memory regions in specified range."));
}
diff --git a/docs/grub.texi b/docs/grub.texi
index 01acf672b80..f1675b6140c 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4103,6 +4103,10 @@ this page is to be filtered. This syntax makes it easy to represent patterns
that are often result of memory damage, due to physical distribution of memory
cells.
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
+ This prevents removing EFI memory regions to potentially subvert the
+ security mechanisms provided by the UEFI secure boot.
+
@node blocklist
@subsection blocklist

View File

@ -0,0 +1,108 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Wed, 24 Feb 2021 09:00:05 +0100
Subject: [PATCH] commands: Restrict commands that can load BIOS or DT blobs
when locked down
There are some more commands that should be restricted when the GRUB is
locked down. Following is the list of commands and reasons to restrict:
* fakebios: creates BIOS-like structures for backward compatibility with
existing OSes. This should not be allowed when locked down.
* loadbios: reads a BIOS dump from storage and loads it. This action
should not be allowed when locked down.
* devicetree: loads a Device Tree blob and passes it to the OS. It replaces
any Device Tree provided by the firmware. This also should
not be allowed when locked down.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/efi/loadbios.c | 14 +++++++-------
grub-core/loader/arm/linux.c | 6 +++---
grub-core/loader/efi/fdt.c | 4 ++--
docs/grub.texi | 6 ++++--
4 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c
index d41d521a4ae..5c7725f8bd8 100644
--- a/grub-core/commands/efi/loadbios.c
+++ b/grub-core/commands/efi/loadbios.c
@@ -205,14 +205,14 @@ static grub_command_t cmd_fakebios, cmd_loadbios;
GRUB_MOD_INIT(loadbios)
{
- cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios,
- 0, N_("Create BIOS-like structures for"
- " backward compatibility with"
- " existing OS."));
+ cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios,
+ 0, N_("Create BIOS-like structures for"
+ " backward compatibility with"
+ " existing OS."));
- cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
- N_("BIOS_DUMP [INT10_DUMP]"),
- N_("Load BIOS dump."));
+ cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios,
+ N_("BIOS_DUMP [INT10_DUMP]"),
+ N_("Load BIOS dump."));
}
GRUB_MOD_FINI(loadbios)
diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
index 1e944a2b671..653f2e07692 100644
--- a/grub-core/loader/arm/linux.c
+++ b/grub-core/loader/arm/linux.c
@@ -493,9 +493,9 @@ GRUB_MOD_INIT (linux)
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, N_("Load initrd."));
- cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree,
- /* TRANSLATORS: DTB stands for device tree blob. */
- 0, N_("Load DTB file."));
+ cmd_devicetree = grub_register_command_lockdown ("devicetree", grub_cmd_devicetree,
+ /* TRANSLATORS: DTB stands for device tree blob. */
+ 0, N_("Load DTB file."));
my_mod = mod;
current_fdt = (const void *) grub_arm_firmware_get_boot_data ();
machine_type = grub_arm_firmware_get_machine_type ();
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index e3ee3ad79d6..64c560f5610 100644
--- a/grub-core/loader/efi/fdt.c
+++ b/grub-core/loader/efi/fdt.c
@@ -167,8 +167,8 @@ static grub_command_t cmd_devicetree;
GRUB_MOD_INIT (fdt)
{
cmd_devicetree =
- grub_register_command ("devicetree", grub_cmd_devicetree, 0,
- N_("Load DTB file."));
+ grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, 0,
+ N_("Load DTB file."));
}
GRUB_MOD_FINI (fdt)
diff --git a/docs/grub.texi b/docs/grub.texi
index f1675b6140c..c55452307dc 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4281,13 +4281,15 @@ hour, minute, and second unchanged.
@node devicetree
-@subsection linux
+@subsection devicetree
@deffn Command devicetree file
Load a device tree blob (.dtb) from a filesystem, for later use by a Linux
kernel. Does not perform merging with any device tree supplied by firmware,
but rather replaces it completely.
-@ref{GNU/Linux}.
+
+Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}).
+ This is done to prevent subverting various security mechanisms.
@end deffn
@node distrust

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Wed, 24 Feb 2021 22:59:59 +0100
Subject: [PATCH] commands/setpci: Restrict setpci command when locked down
This command can set PCI devices register values, which makes it dangerous
in a locked down configuration. Restrict it so can't be used on this setup.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/setpci.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c
index d5bc97d60b2..fa2ba7d8919 100644
--- a/grub-core/commands/setpci.c
+++ b/grub-core/commands/setpci.c
@@ -329,10 +329,10 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(setpci)
{
- cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0,
- N_("[-s POSITION] [-d DEVICE] [-v VAR] "
- "REGISTER[=VALUE[:MASK]]"),
- N_("Manipulate PCI devices."), options);
+ cmd = grub_register_extcmd_lockdown ("setpci", grub_cmd_setpci, 0,
+ N_("[-s POSITION] [-d DEVICE] [-v VAR] "
+ "REGISTER[=VALUE[:MASK]]"),
+ N_("Manipulate PCI devices."), options);
}
GRUB_MOD_FINI(setpci)

Some files were not shown because too many files have changed in this diff Show More