|
|
9723a8 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
9723a8 |
From: Peter Jones <pjones@redhat.com>
|
|
|
9723a8 |
Date: Mon, 15 Feb 2021 17:07:00 +0100
|
|
|
9723a8 |
Subject: [PATCH] util/mkimage: Add an option to import SBAT metadata into a
|
|
|
9723a8 |
.sbat section
|
|
|
9723a8 |
|
|
|
9723a8 |
Add a --sbat option to the grub-mkimage tool which allows us to import
|
|
|
9723a8 |
an SBAT metadata formatted as a CSV file into a .sbat section of the
|
|
|
9723a8 |
EFI binary.
|
|
|
9723a8 |
|
|
|
9723a8 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
9723a8 |
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
9723a8 |
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
|
9723a8 |
---
|
|
|
9723a8 |
util/grub-install-common.c | 3 ++-
|
|
|
9723a8 |
util/grub-mkimage.c | 15 ++++++++++++++-
|
|
|
9723a8 |
util/mkimage.c | 43 ++++++++++++++++++++++++++++++++++++-------
|
|
|
9723a8 |
include/grub/util/install.h | 3 ++-
|
|
|
9723a8 |
include/grub/util/mkimage.h | 1 +
|
|
|
9723a8 |
docs/grub.texi | 21 +++++++++++++++++++++
|
|
|
9723a8 |
6 files changed, 76 insertions(+), 10 deletions(-)
|
|
|
9723a8 |
|
|
|
9723a8 |
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
|
|
9723a8 |
index cf993c059ad..909db42e7d6 100644
|
|
|
9723a8 |
--- a/util/grub-install-common.c
|
|
|
9723a8 |
+++ b/util/grub-install-common.c
|
|
|
9723a8 |
@@ -506,7 +506,8 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
|
|
9723a8 |
grub_install_generate_image (dir, prefix, fp, outname,
|
|
|
9723a8 |
modules.entries, memdisk_path,
|
|
|
9723a8 |
pubkeys, npubkeys, config_path, tgt,
|
|
|
9723a8 |
- note, compression, dtb);
|
|
|
9723a8 |
+ note, compression, dtb, NULL);
|
|
|
9723a8 |
+
|
|
|
9723a8 |
while (dc--)
|
|
|
9723a8 |
grub_install_pop_module ();
|
|
|
9723a8 |
}
|
|
|
9723a8 |
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
|
|
9723a8 |
index 98d24cc06ea..bce7f7a5f02 100644
|
|
|
9723a8 |
--- a/util/grub-mkimage.c
|
|
|
9723a8 |
+++ b/util/grub-mkimage.c
|
|
|
9723a8 |
@@ -81,6 +81,7 @@ static struct argp_option options[] = {
|
|
|
9723a8 |
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
|
|
|
9723a8 |
{"format", 'O', N_("FORMAT"), 0, 0, 0},
|
|
|
9723a8 |
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
|
|
9723a8 |
+ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
|
|
9723a8 |
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
|
|
9723a8 |
{ 0, 0, 0, 0, 0, 0 }
|
|
|
9723a8 |
};
|
|
|
9723a8 |
@@ -123,6 +124,7 @@ struct arguments
|
|
|
9723a8 |
size_t npubkeys;
|
|
|
9723a8 |
char *font;
|
|
|
9723a8 |
char *config;
|
|
|
9723a8 |
+ char *sbat;
|
|
|
9723a8 |
int note;
|
|
|
9723a8 |
const struct grub_install_image_target_desc *image_target;
|
|
|
9723a8 |
grub_compression_t comp;
|
|
|
9723a8 |
@@ -224,6 +226,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
|
|
9723a8 |
arguments->prefix = xstrdup (arg);
|
|
|
9723a8 |
break;
|
|
|
9723a8 |
|
|
|
9723a8 |
+ case 's':
|
|
|
9723a8 |
+ if (arguments->sbat)
|
|
|
9723a8 |
+ free (arguments->sbat);
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+ arguments->sbat = xstrdup (arg);
|
|
|
9723a8 |
+ break;
|
|
|
9723a8 |
+
|
|
|
9723a8 |
case 'v':
|
|
|
9723a8 |
verbosity++;
|
|
|
9723a8 |
break;
|
|
|
9723a8 |
@@ -309,7 +318,8 @@ main (int argc, char *argv[])
|
|
|
9723a8 |
arguments.memdisk, arguments.pubkeys,
|
|
|
9723a8 |
arguments.npubkeys, arguments.config,
|
|
|
9723a8 |
arguments.image_target, arguments.note,
|
|
|
9723a8 |
- arguments.comp, arguments.dtb);
|
|
|
9723a8 |
+ arguments.comp, arguments.dtb,
|
|
|
9723a8 |
+ arguments.sbat);
|
|
|
9723a8 |
|
|
|
9723a8 |
grub_util_file_sync (fp);
|
|
|
9723a8 |
fclose (fp);
|
|
|
9723a8 |
@@ -324,5 +334,8 @@ main (int argc, char *argv[])
|
|
|
9723a8 |
if (arguments.output)
|
|
|
9723a8 |
free (arguments.output);
|
|
|
9723a8 |
|
|
|
9723a8 |
+ if (arguments.sbat)
|
|
|
9723a8 |
+ free (arguments.sbat);
|
|
|
9723a8 |
+
|
|
|
9723a8 |
return 0;
|
|
|
9723a8 |
}
|
|
|
9723a8 |
diff --git a/util/mkimage.c b/util/mkimage.c
|
|
|
9723a8 |
index e8e579304aa..8c7d9164396 100644
|
|
|
9723a8 |
--- a/util/mkimage.c
|
|
|
9723a8 |
+++ b/util/mkimage.c
|
|
|
9723a8 |
@@ -824,12 +824,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
char *memdisk_path, char **pubkey_paths,
|
|
|
9723a8 |
size_t npubkeys, char *config_path,
|
|
|
9723a8 |
const struct grub_install_image_target_desc *image_target,
|
|
|
9723a8 |
- int note, grub_compression_t comp, const char *dtb_path)
|
|
|
9723a8 |
+ int note, grub_compression_t comp, const char *dtb_path,
|
|
|
9723a8 |
+ const char *sbat_path)
|
|
|
9723a8 |
{
|
|
|
9723a8 |
char *kernel_img, *core_img;
|
|
|
9723a8 |
size_t total_module_size, core_size;
|
|
|
9723a8 |
size_t memdisk_size = 0, config_size = 0;
|
|
|
9723a8 |
- size_t prefix_size = 0, dtb_size = 0;
|
|
|
9723a8 |
+ size_t prefix_size = 0, dtb_size = 0, sbat_size = 0;
|
|
|
9723a8 |
char *kernel_path;
|
|
|
9723a8 |
size_t offset;
|
|
|
9723a8 |
struct grub_util_path_list *path_list, *p;
|
|
|
9723a8 |
@@ -880,6 +881,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
total_module_size += dtb_size + sizeof (struct grub_module_header);
|
|
|
9723a8 |
}
|
|
|
9723a8 |
|
|
|
9723a8 |
+ if (sbat_path != NULL && image_target->id != IMAGE_EFI)
|
|
|
9723a8 |
+ grub_util_error (_(".sbat section can be embedded into EFI images only"));
|
|
|
9723a8 |
+
|
|
|
9723a8 |
if (config_path)
|
|
|
9723a8 |
{
|
|
|
9723a8 |
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
|
|
9723a8 |
@@ -1242,8 +1246,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
break;
|
|
|
9723a8 |
case IMAGE_EFI:
|
|
|
9723a8 |
{
|
|
|
9723a8 |
- char *pe_img, *header;
|
|
|
9723a8 |
+ char *pe_img, *pe_sbat, *header;
|
|
|
9723a8 |
struct grub_pe32_section_table *section;
|
|
|
9723a8 |
+ size_t n_sections = 4;
|
|
|
9723a8 |
size_t scn_size;
|
|
|
9723a8 |
grub_uint32_t vma, raw_data;
|
|
|
9723a8 |
size_t pe_size, header_size;
|
|
|
9723a8 |
@@ -1258,8 +1263,15 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
header_size = EFI64_HEADER_SIZE;
|
|
|
9723a8 |
|
|
|
9723a8 |
vma = raw_data = header_size;
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+ if (sbat_path != NULL)
|
|
|
9723a8 |
+ {
|
|
|
9723a8 |
+ sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path));
|
|
|
9723a8 |
+ sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT);
|
|
|
9723a8 |
+ }
|
|
|
9723a8 |
+
|
|
|
9723a8 |
pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
|
|
|
9723a8 |
- ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
|
|
|
9723a8 |
+ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size;
|
|
|
9723a8 |
header = pe_img = xcalloc (1, pe_size);
|
|
|
9723a8 |
|
|
|
9723a8 |
memcpy (pe_img + raw_data, core_img, core_size);
|
|
|
9723a8 |
@@ -1274,7 +1286,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
+ GRUB_PE32_SIGNATURE_SIZE);
|
|
|
9723a8 |
c->machine = grub_host_to_target16 (image_target->pe_target);
|
|
|
9723a8 |
|
|
|
9723a8 |
- c->num_sections = grub_host_to_target16 (4);
|
|
|
9723a8 |
+ if (sbat_path != NULL)
|
|
|
9723a8 |
+ n_sections++;
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+ c->num_sections = grub_host_to_target16 (n_sections);
|
|
|
9723a8 |
c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
|
|
|
9723a8 |
c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
|
|
|
9723a8 |
| GRUB_PE32_LINE_NUMS_STRIPPED
|
|
|
9723a8 |
@@ -1336,7 +1351,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
GRUB_PE32_SCN_MEM_READ);
|
|
|
9723a8 |
|
|
|
9723a8 |
scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
|
|
|
9723a8 |
- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
|
|
|
9723a8 |
+ /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */
|
|
|
9723a8 |
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size +
|
|
|
9723a8 |
ALIGN_UP (total_module_size,
|
|
|
9723a8 |
GRUB_PE32_FILE_ALIGNMENT));
|
|
|
9723a8 |
|
|
|
9723a8 |
@@ -1347,7 +1363,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
GRUB_PE32_SCN_MEM_READ |
|
|
|
9723a8 |
GRUB_PE32_SCN_MEM_WRITE);
|
|
|
9723a8 |
|
|
|
9723a8 |
- scn_size = pe_size - layout.reloc_size - raw_data;
|
|
|
9723a8 |
+ scn_size = pe_size - layout.reloc_size - sbat_size - raw_data;
|
|
|
9723a8 |
section = init_pe_section (image_target, section, "mods",
|
|
|
9723a8 |
&vma, scn_size, image_target->section_align,
|
|
|
9723a8 |
&raw_data, scn_size,
|
|
|
9723a8 |
@@ -1355,6 +1371,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
GRUB_PE32_SCN_MEM_READ |
|
|
|
9723a8 |
GRUB_PE32_SCN_MEM_WRITE);
|
|
|
9723a8 |
|
|
|
9723a8 |
+ if (sbat_path != NULL)
|
|
|
9723a8 |
+ {
|
|
|
9723a8 |
+ pe_sbat = pe_img + raw_data;
|
|
|
9723a8 |
+ grub_util_load_image (sbat_path, pe_sbat);
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+ section = init_pe_section (image_target, section, ".sbat",
|
|
|
9723a8 |
+ &vma, sbat_size,
|
|
|
9723a8 |
+ image_target->section_align,
|
|
|
9723a8 |
+ &raw_data, sbat_size,
|
|
|
9723a8 |
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
|
|
|
9723a8 |
+ GRUB_PE32_SCN_MEM_READ);
|
|
|
9723a8 |
+ }
|
|
|
9723a8 |
+
|
|
|
9723a8 |
scn_size = layout.reloc_size;
|
|
|
9723a8 |
PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
|
|
|
9723a8 |
PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
|
|
|
9723a8 |
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
|
|
9723a8 |
index 0dba8b67f93..a08f0b5325f 100644
|
|
|
9723a8 |
--- a/include/grub/util/install.h
|
|
|
9723a8 |
+++ b/include/grub/util/install.h
|
|
|
9723a8 |
@@ -180,7 +180,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
|
|
9723a8 |
char *config_path,
|
|
|
9723a8 |
const struct grub_install_image_target_desc *image_target,
|
|
|
9723a8 |
int note,
|
|
|
9723a8 |
- grub_compression_t comp, const char *dtb_file);
|
|
|
9723a8 |
+ grub_compression_t comp, const char *dtb_file,
|
|
|
9723a8 |
+ const char *sbat_path);
|
|
|
9723a8 |
|
|
|
9723a8 |
const struct grub_install_image_target_desc *
|
|
|
9723a8 |
grub_install_get_image_target (const char *arg);
|
|
|
9723a8 |
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
|
|
|
9723a8 |
index b3a5ca132bc..151c178e6ee 100644
|
|
|
9723a8 |
--- a/include/grub/util/mkimage.h
|
|
|
9723a8 |
+++ b/include/grub/util/mkimage.h
|
|
|
9723a8 |
@@ -24,6 +24,7 @@ struct grub_mkimage_layout
|
|
|
9723a8 |
size_t exec_size;
|
|
|
9723a8 |
size_t kernel_size;
|
|
|
9723a8 |
size_t bss_size;
|
|
|
9723a8 |
+ size_t sbat_size;
|
|
|
9723a8 |
grub_uint64_t start_address;
|
|
|
9723a8 |
void *reloc_section;
|
|
|
9723a8 |
size_t reloc_size;
|
|
|
9723a8 |
diff --git a/docs/grub.texi b/docs/grub.texi
|
|
|
9723a8 |
index 067aa294162..fc7b56b8f47 100644
|
|
|
9723a8 |
--- a/docs/grub.texi
|
|
|
9723a8 |
+++ b/docs/grub.texi
|
|
|
9723a8 |
@@ -5642,6 +5642,7 @@ environment variables and commands are listed in the same order.
|
|
|
9723a8 |
@menu
|
|
|
9723a8 |
* Authentication and authorisation:: Users and access control
|
|
|
9723a8 |
* Using digital signatures:: Booting digitally signed code
|
|
|
9723a8 |
+* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
|
|
|
9723a8 |
* Lockdown:: Lockdown when booting on a secure setup
|
|
|
9723a8 |
|
|
|
9723a8 |
@end menu
|
|
|
9723a8 |
@@ -5806,6 +5807,26 @@ or BIOS) configuration to cause the machine to boot from a different
|
|
|
9723a8 |
(attacker-controlled) device. GRUB is at best only one link in a
|
|
|
9723a8 |
secure boot chain.
|
|
|
9723a8 |
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+@node Secure Boot Advanced Targeting
|
|
|
9723a8 |
+@section Embedded information for generation number based revocation
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation
|
|
|
9723a8 |
+of components in the boot path by using generation numbers embedded into the EFI
|
|
|
9723a8 |
+binaries. The SBAT metadata is located in an .sbat data section that has set of
|
|
|
9723a8 |
+UTF-8 strings as comma-separated values (CSV). See
|
|
|
9723a8 |
+@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details.
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+To add a data section containing the SBAT information into the binary, the
|
|
|
9723a8 |
+@option{--sbat} option of @command{grub-mkimage} command should be used. The content
|
|
|
9723a8 |
+of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into
|
|
|
9723a8 |
+the generated EFI binary. The CSV file can be stored anywhere on the file system.
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+@example
|
|
|
9723a8 |
+grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp
|
|
|
9723a8 |
+@end example
|
|
|
9723a8 |
+
|
|
|
9723a8 |
+
|
|
|
9723a8 |
@node Lockdown
|
|
|
9723a8 |
@section Lockdown when booting on a secure setup
|
|
|
9723a8 |
|