[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SECURITY PATCH 109/117] util/mkimage: Add an option to import SBAT meta
From: |
Daniel Kiper |
Subject: |
[SECURITY PATCH 109/117] util/mkimage: Add an option to import SBAT metadata into a .sbat section |
Date: |
Tue, 2 Mar 2021 19:01:56 +0100 |
From: Peter Jones <pjones@redhat.com>
Add a --sbat option to the grub-mkimage tool which allows us to import
an SBAT metadata formatted as a CSV file into a .sbat section of the
EFI binary.
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 19 +++++++++++++++++++
include/grub/util/install.h | 3 ++-
include/grub/util/mkimage.h | 1 +
util/grub-install-common.c | 2 +-
util/grub-mkimage.c | 15 ++++++++++++++-
util/mkimage.c | 43 ++++++++++++++++++++++++++++++++++++-------
6 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index c5fc3904f..81b90947a 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5784,6 +5784,7 @@ environment variables and commands are listed in the same
order.
* Authentication and authorisation:: Users and access control
* Using digital signatures:: Booting digitally signed code
* UEFI secure boot and shim:: Booting digitally signed PE files
+* Secure Boot Advanced Targeting:: Embedded information for generation
number based revocation
* Measured Boot:: Measuring boot components
* Lockdown:: Lockdown when booting on a secure setup
@end menu
@@ -5958,6 +5959,24 @@ and @command{memrw} will not be available when the UEFI
secure boot is enabled.
This is done for security reasons and are enforced by the GRUB Lockdown
mechanism
(@pxref{Lockdown}).
+@node Secure Boot Advanced Targeting
+@section Embedded information for generation number based revocation
+
+The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the
revocation
+of components in the boot path by using generation numbers embedded into the
EFI
+binaries. The SBAT metadata is located in an .sbat data section that has set of
+UTF-8 strings as comma-separated values (CSV). See
+@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details.
+
+To add a data section containing the SBAT information into the binary, the
+@option{--sbat} option of @command{grub-mkimage} command should be used. The
content
+of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section
into
+the generated EFI binary. The CSV file can be stored anywhere on the file
system.
+
+@example
+grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv
efinet tftp
+@end example
+
@node Measured Boot
@section Measuring boot components
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 8cbbc4139..3736a16aa 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -183,7 +183,8 @@ grub_install_generate_image (const char *dir, const char
*prefix,
char *config_path,
const struct grub_install_image_target_desc
*image_target,
int note,
- grub_compression_t comp, const char *dtb_file);
+ grub_compression_t comp, const char *dtb_file,
+ const char *sbat_path);
const struct grub_install_image_target_desc *
grub_install_get_image_target (const char *arg);
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
index ba9f568f6..3819a6744 100644
--- a/include/grub/util/mkimage.h
+++ b/include/grub/util/mkimage.h
@@ -24,6 +24,7 @@ struct grub_mkimage_layout
size_t exec_size;
size_t kernel_size;
size_t bss_size;
+ size_t sbat_size;
grub_uint64_t start_address;
void *reloc_section;
size_t reloc_size;
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 08d3eb668..56dcb52bf 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -536,7 +536,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, compression, dtb, NULL);
while (dc--)
grub_install_pop_module ();
}
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index 912564e36..75b884710 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -81,6 +81,7 @@ static struct argp_option options[] = {
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE
[default=stdout]"), 0},
{"format", 'O', N_("FORMAT"), 0, 0, 0},
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use
for core image"), 0},
+ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
{ 0, 0, 0, 0, 0, 0 }
};
@@ -123,6 +124,7 @@ struct arguments
size_t npubkeys;
char *font;
char *config;
+ char *sbat;
int note;
const struct grub_install_image_target_desc *image_target;
grub_compression_t comp;
@@ -224,6 +226,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->prefix = xstrdup (arg);
break;
+ case 's':
+ if (arguments->sbat)
+ free (arguments->sbat);
+
+ arguments->sbat = xstrdup (arg);
+ break;
+
case 'v':
verbosity++;
break;
@@ -309,7 +318,8 @@ main (int argc, char *argv[])
arguments.memdisk, arguments.pubkeys,
arguments.npubkeys, arguments.config,
arguments.image_target, arguments.note,
- arguments.comp, arguments.dtb);
+ arguments.comp, arguments.dtb,
+ arguments.sbat);
if (grub_util_file_sync (fp) < 0)
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
@@ -328,5 +338,8 @@ main (int argc, char *argv[])
if (arguments.output)
free (arguments.output);
+ if (arguments.sbat)
+ free (arguments.sbat);
+
return 0;
}
diff --git a/util/mkimage.c b/util/mkimage.c
index 8b475a691..b354ec1d9 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -869,12 +869,13 @@ 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, grub_compression_t comp, const char
*dtb_path,
+ const char *sbat_path)
{
char *kernel_img, *core_img;
size_t total_module_size, core_size;
size_t memdisk_size = 0, config_size = 0;
- size_t prefix_size = 0, dtb_size = 0;
+ size_t prefix_size = 0, dtb_size = 0, sbat_size = 0;
char *kernel_path;
size_t offset;
struct grub_util_path_list *path_list, *p;
@@ -925,6 +926,9 @@ grub_install_generate_image (const char *dir, const char
*prefix,
total_module_size += dtb_size + sizeof (struct grub_module_header);
}
+ if (sbat_path != NULL && image_target->id != IMAGE_EFI)
+ grub_util_error (_(".sbat section can be embedded into EFI images only"));
+
if (config_path)
{
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
@@ -1289,8 +1293,9 @@ grub_install_generate_image (const char *dir, const char
*prefix,
break;
case IMAGE_EFI:
{
- char *pe_img, *header;
+ char *pe_img, *pe_sbat, *header;
struct grub_pe32_section_table *section;
+ size_t n_sections = 4;
size_t scn_size;
grub_uint32_t vma, raw_data;
size_t pe_size, header_size;
@@ -1305,8 +1310,15 @@ grub_install_generate_image (const char *dir, const char
*prefix,
header_size = EFI64_HEADER_SIZE;
vma = raw_data = header_size;
+
+ if (sbat_path != NULL)
+ {
+ sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path));
+ sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT);
+ }
+
pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
- ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
+ ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size;
header = pe_img = xcalloc (1, pe_size);
memcpy (pe_img + raw_data, core_img, core_size);
@@ -1321,7 +1333,10 @@ grub_install_generate_image (const char *dir, const char
*prefix,
+ GRUB_PE32_SIGNATURE_SIZE);
c->machine = grub_host_to_target16 (image_target->pe_target);
- c->num_sections = grub_host_to_target16 (4);
+ if (sbat_path != NULL)
+ n_sections++;
+
+ c->num_sections = grub_host_to_target16 (n_sections);
c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
|
GRUB_PE32_LINE_NUMS_STRIPPED
@@ -1383,7 +1398,8 @@ grub_install_generate_image (const char *dir, const char
*prefix,
GRUB_PE32_SCN_MEM_READ);
scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size,
GRUB_PE32_FILE_ALIGNMENT);
- PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
+ /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */
+ PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
sbat_size +
ALIGN_UP
(total_module_size,
GRUB_PE32_FILE_ALIGNMENT));
@@ -1394,7 +1410,7 @@ grub_install_generate_image (const char *dir, const char
*prefix,
GRUB_PE32_SCN_MEM_READ |
GRUB_PE32_SCN_MEM_WRITE);
- scn_size = pe_size - layout.reloc_size - raw_data;
+ scn_size = pe_size - layout.reloc_size - sbat_size - raw_data;
section = init_pe_section (image_target, section, "mods",
&vma, scn_size, image_target->section_align,
&raw_data, scn_size,
@@ -1402,6 +1418,19 @@ grub_install_generate_image (const char *dir, const char
*prefix,
GRUB_PE32_SCN_MEM_READ |
GRUB_PE32_SCN_MEM_WRITE);
+ if (sbat_path != NULL)
+ {
+ pe_sbat = pe_img + raw_data;
+ grub_util_load_image (sbat_path, pe_sbat);
+
+ section = init_pe_section (image_target, section, ".sbat",
+ &vma, sbat_size,
+ image_target->section_align,
+ &raw_data, sbat_size,
+ GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
+ GRUB_PE32_SCN_MEM_READ);
+ }
+
scn_size = layout.reloc_size;
PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32
(vma);
PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32
(scn_size);
--
2.11.0
[SECURITY PATCH 107/117] util/mkimage: Improve data_size value calculation, Daniel Kiper, 2021/03/02
[SECURITY PATCH 100/117] kern/parser: Fix a stack buffer overflow, Daniel Kiper, 2021/03/02
[SECURITY PATCH 103/117] util/mkimage: Use grub_host_to_target32() instead of grub_cpu_to_le32(), Daniel Kiper, 2021/03/02
[SECURITY PATCH 105/117] util/mkimage: Unify more of the PE32 and PE32+ header set-up, Daniel Kiper, 2021/03/02
[SECURITY PATCH 101/117] kern/efi: Add initial stack protector implementation, Daniel Kiper, 2021/03/02
[SECURITY PATCH 109/117] util/mkimage: Add an option to import SBAT metadata into a .sbat section,
Daniel Kiper <=
[SECURITY PATCH 115/117] gfxmenu/gui: Check printf() format in the gui_progress_bar and gui_label, Daniel Kiper, 2021/03/02
[SECURITY PATCH 104/117] util/mkimage: Always use grub_host_to_target32() to initialize PE stack and heap stuff, Daniel Kiper, 2021/03/02
[SECURITY PATCH 112/117] kern/misc: Split parse_printf_args() into format parsing and va_list handling, Daniel Kiper, 2021/03/02
[SECURITY PATCH 106/117] util/mkimage: Reorder PE optional header fields set-up, Daniel Kiper, 2021/03/02
[SECURITY PATCH 114/117] kern/misc: Add function to check printf() format against expected format, Daniel Kiper, 2021/03/02
[SECURITY PATCH 116/117] templates: Disable the os-prober by default, Daniel Kiper, 2021/03/02