From 0eb07e11b20680200d3ce9c5bc59299121a75388 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Tue, 31 May 2022 22:21:26 +0100 Subject: [PATCH 01/13] Make SBAT variable payload introspectable Given a set of EFI variables and boot assets, it should be possible to compute what the value of PCR 7 will be on the next boot. As shim manages the contents of the SbatLevel variable and this is measured to PCR 7, export the payloads that shim contains in a new COFF section (.sbatlevel) so that it can be introspected by code outside of shim. The new section works a bit like .vendor_cert - it contains a header and then the payload. In this case, the header contains no size fields because the strings are NULL terminated. Shim uses this new section internally in set_sbat_uefi_variable. The .sbatlevel section starts with a 4 byte version field which is not used by shim but may be useful for external auditors if the format of the section contents change in the future. Signed-off-by: Chris Coulson --- sbat.c | 21 ++++++++++++++++----- include/sbat.h | 32 -------------------------------- include/sbat_var_defs.h | 38 ++++++++++++++++++++++++++++++++++++++ shim.h | 1 + sbat_var.S | 20 ++++++++++++++++++++ elf_aarch64_efi.lds | 4 ++++ elf_ia32_efi.lds | 4 ++++ elf_ia64_efi.lds | 4 ++++ elf_x86_64_efi.lds | 4 ++++ include/test.mk | 2 +- Makefile | 7 ++++--- 11 files changed, 96 insertions(+), 41 deletions(-) create mode 100644 include/sbat_var_defs.h create mode 100644 sbat_var.S diff --git a/sbat.c b/sbat.c index f1d6e98dcde..a08c5b2a972 100644 --- a/sbat.c +++ b/sbat.c @@ -5,6 +5,11 @@ #include "shim.h" +extern struct { + UINT32 previous_offset; + UINT32 latest_offset; +} sbat_var_payload_header; + EFI_STATUS parse_sbat_section(char *section_base, size_t section_size, size_t *n_entries, @@ -399,6 +404,9 @@ set_sbat_uefi_variable(void) EFI_STATUS efi_status = EFI_SUCCESS; UINT32 attributes = 0; + char *sbat_var_previous; + char *sbat_var_latest; + UINT8 *sbat = NULL; UINT8 *sbat_policy = NULL; UINTN sbatsize = 0; @@ -407,27 +415,30 @@ set_sbat_uefi_variable(void) char *sbat_var = NULL; bool reset_sbat = false; + sbat_var_previous = (char *)&sbat_var_payload_header + sbat_var_payload_header.previous_offset; + sbat_var_latest = (char *)&sbat_var_payload_header + sbat_var_payload_header.latest_offset; + efi_status = get_variable_attr(SBAT_POLICY, &sbat_policy, &sbat_policysize, SHIM_LOCK_GUID, &attributes); if (EFI_ERROR(efi_status)) { dprint("Default sbat policy: previous\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; } else { switch (*sbat_policy) { case SBAT_POLICY_LATEST: dprint("Custom sbat policy: latest\n"); - sbat_var = SBAT_VAR_LATEST; + sbat_var = sbat_var_latest; clear_sbat_policy(); break; case SBAT_POLICY_PREVIOUS: dprint("Custom sbat policy: previous\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; break; case SBAT_POLICY_RESET: if (secure_mode()) { console_print(L"Cannot reset SBAT policy: Secure Boot is enabled.\n"); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; } else { dprint(L"Custom SBAT policy: reset OK\n"); reset_sbat = true; @@ -438,7 +449,7 @@ set_sbat_uefi_variable(void) default: console_error(L"SBAT policy state %llu is invalid", EFI_INVALID_PARAMETER); - sbat_var = SBAT_VAR_PREVIOUS; + sbat_var = sbat_var_previous; clear_sbat_policy(); break; } diff --git a/include/sbat.h b/include/sbat.h index aca4359870f..c94c4fba8cd 100644 --- a/include/sbat.h +++ b/include/sbat.h @@ -6,38 +6,6 @@ #ifndef SBAT_H_ #define SBAT_H_ -#define SBAT_VAR_SIG "sbat," -#define SBAT_VAR_VERSION "1," -#define SBAT_VAR_ORIGINAL_DATE "2021030218" -#define SBAT_VAR_ORIGINAL \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_ORIGINAL_DATE "\n" - -#if defined(ENABLE_SHIM_DEVEL) -#define SBAT_VAR_PREVIOUS_DATE "2022020101" -#define SBAT_VAR_PREVIOUS_REVOCATIONS "component,2\n" -#define SBAT_VAR_PREVIOUS \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ - SBAT_VAR_PREVIOUS_REVOCATIONS - -#define SBAT_VAR_LATEST_DATE "2022050100" -#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n" -#define SBAT_VAR_LATEST \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ - SBAT_VAR_LATEST_REVOCATIONS -#else /* !ENABLE_SHIM_DEVEL */ -#define SBAT_VAR_PREVIOUS_DATE SBAT_VAR_ORIGINAL_DATE -#define SBAT_VAR_PREVIOUS_REVOCATIONS -#define SBAT_VAR_PREVIOUS \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ - SBAT_VAR_PREVIOUS_REVOCATIONS - -#define SBAT_VAR_LATEST_DATE "2022052400" -#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,2\n" -#define SBAT_VAR_LATEST \ - SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ - SBAT_VAR_LATEST_REVOCATIONS -#endif /* ENABLE_SHIM_DEVEL */ - #define UEFI_VAR_NV_BS \ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) #define UEFI_VAR_NV_BS_RT \ diff --git a/include/sbat_var_defs.h b/include/sbat_var_defs.h new file mode 100644 index 00000000000..c656b56d4c3 --- /dev/null +++ b/include/sbat_var_defs.h @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef SBAT_VAR_DEFS_H_ +#define SBAT_VAR_DEFS_H_ + +#define SBAT_VAR_SIG "sbat," +#define SBAT_VAR_VERSION "1," +#define SBAT_VAR_ORIGINAL_DATE "2021030218" +#define SBAT_VAR_ORIGINAL \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_ORIGINAL_DATE "\n" + +#if defined(ENABLE_SHIM_DEVEL) +#define SBAT_VAR_PREVIOUS_DATE "2022020101" +#define SBAT_VAR_PREVIOUS_REVOCATIONS "component,2\n" +#define SBAT_VAR_PREVIOUS \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ + SBAT_VAR_PREVIOUS_REVOCATIONS + +#define SBAT_VAR_LATEST_DATE "2022050100" +#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n" +#define SBAT_VAR_LATEST \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ + SBAT_VAR_LATEST_REVOCATIONS +#else /* !ENABLE_SHIM_DEVEL */ +#define SBAT_VAR_PREVIOUS_DATE SBAT_VAR_ORIGINAL_DATE +#define SBAT_VAR_PREVIOUS_REVOCATIONS +#define SBAT_VAR_PREVIOUS \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ + SBAT_VAR_PREVIOUS_REVOCATIONS + +#define SBAT_VAR_LATEST_DATE "2022052400" +#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,2\n" +#define SBAT_VAR_LATEST \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ + SBAT_VAR_LATEST_REVOCATIONS +#endif /* ENABLE_SHIM_DEVEL */ + +#endif /* !SBAT_VAR_DEFS_H_ */ diff --git a/shim.h b/shim.h index b5272b9c9e9..7e9d10eb2df 100644 --- a/shim.h +++ b/shim.h @@ -179,6 +179,7 @@ #include "include/pe.h" #include "include/replacements.h" #include "include/sbat.h" +#include "include/sbat_var_defs.h" #if defined(OVERRIDE_SECURITY_POLICY) #include "include/security_policy.h" #endif diff --git a/sbat_var.S b/sbat_var.S new file mode 100644 index 00000000000..a115077ae4d --- /dev/null +++ b/sbat_var.S @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#include "include/sbat_var_defs.h" + + .section .sbatlevel, "a", %progbits + .balignl 4, 0 + .4byte 0 /* format version for external parsers */ + .globl sbat_var_payload_header + .type sbat_var_payload_header, %object + .size sbat_var_payload_header, .Lsbat_var_payload_header_end - sbat_var_payload_header +sbat_var_payload_header: + .4byte .Lsbat_var_previous - sbat_var_payload_header + .4byte .Lsbat_var_latest - sbat_var_payload_header +.Lsbat_var_payload_header_end: + .balign 1, 0 +.Lsbat_var_previous: + .asciz SBAT_VAR_PREVIOUS + .balign 1, 0 +.Lsbat_var_latest: + .asciz SBAT_VAR_LATEST diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds index 60c55ba5fe1..0861f5e8a16 100644 --- a/elf_aarch64_efi.lds +++ b/elf_aarch64_efi.lds @@ -34,6 +34,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds index 497a3a15265..e8da91bdfb2 100644 --- a/elf_ia32_efi.lds +++ b/elf_ia32_efi.lds @@ -28,6 +28,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_ia64_efi.lds b/elf_ia64_efi.lds index 2669b856b15..a2195609ca0 100644 --- a/elf_ia64_efi.lds +++ b/elf_ia64_efi.lds @@ -34,6 +34,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/elf_x86_64_efi.lds b/elf_x86_64_efi.lds index bcc65270911..39aff6b07b6 100644 --- a/elf_x86_64_efi.lds +++ b/elf_x86_64_efi.lds @@ -35,6 +35,10 @@ SECTIONS .data.ident : { *(.data.ident) } + . = ALIGN(4096); + .sbatlevel : { + *(.sbatlevel) + } . = ALIGN(4096); .data : diff --git a/include/test.mk b/include/test.mk index e965c6000a5..c0e2409517a 100644 --- a/include/test.mk +++ b/include/test.mk @@ -92,7 +92,7 @@ test-mock-variables: CFLAGS+=-DHAVE_SHIM_LOCK_GUID test-mok-mirror_FILES = mok.c globals.c tpm.c lib/guid.c lib/variables.c mock-variables.c test-mok-mirror: CFLAGS+=-DHAVE_START_IMAGE -DHAVE_SHIM_LOCK_GUID -test-sbat_FILES = csv.c lib/variables.c lib/guid.c +test-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S test-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID test-str_FILES = lib/string.c diff --git a/Makefile b/Makefile index 24ac314e04f..866611c75d5 100644 --- a/Makefile +++ b/Makefile @@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT else TARGETS += $(MMNAME) $(FBNAME) endif -OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o pe.o httpboot.o csv.o load-options.o +OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer -ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S +ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h) FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o @@ -253,7 +253,7 @@ endif $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \ -j .dynamic -j .rodata -j .rel* \ -j .rela* -j .dyn -j .reloc -j .eh_frame \ - -j .vendor_cert -j .sbat \ + -j .vendor_cert -j .sbat -j .sbatlevel \ $(FORMAT) $< $@ ./post-process-pe -vv $@ @@ -269,6 +269,7 @@ endif $(OBJCOPY) -D -j .text -j .sdata -j .data \ -j .dynamic -j .rodata -j .rel* \ -j .rela* -j .dyn -j .reloc -j .eh_frame -j .sbat \ + -j .sbatlevel \ -j .debug_info -j .debug_abbrev -j .debug_aranges \ -j .debug_line -j .debug_str -j .debug_ranges \ -j .note.gnu.build-id \ -- 2.37.1