Blame SOURCES/0001-Make-SBAT-variable-payload-introspectable.patch

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