Skip to content

Commit

Permalink
Make SBAT variable payload introspectable
Browse files Browse the repository at this point in the history
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 <chris.coulson@canonical.com>
  • Loading branch information
chrisccoulson authored and vathpela committed Aug 3, 2022
1 parent 505cdb6 commit 0eb07e1
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 41 deletions.
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 $@

Expand All @@ -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 \
Expand Down
4 changes: 4 additions & 0 deletions elf_aarch64_efi.lds
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ SECTIONS
.data.ident : {
*(.data.ident)
}
. = ALIGN(4096);
.sbatlevel : {
*(.sbatlevel)
}

. = ALIGN(4096);
.data :
Expand Down
4 changes: 4 additions & 0 deletions elf_ia32_efi.lds
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ SECTIONS
.data.ident : {
*(.data.ident)
}
. = ALIGN(4096);
.sbatlevel : {
*(.sbatlevel)
}

. = ALIGN(4096);
.data :
Expand Down
4 changes: 4 additions & 0 deletions elf_ia64_efi.lds
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ SECTIONS
.data.ident : {
*(.data.ident)
}
. = ALIGN(4096);
.sbatlevel : {
*(.sbatlevel)
}

. = ALIGN(4096);
.data :
Expand Down
4 changes: 4 additions & 0 deletions elf_x86_64_efi.lds
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ SECTIONS
.data.ident : {
*(.data.ident)
}
. = ALIGN(4096);
.sbatlevel : {
*(.sbatlevel)
}

. = ALIGN(4096);
.data :
Expand Down
32 changes: 0 additions & 32 deletions include/sbat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
38 changes: 38 additions & 0 deletions include/sbat_var_defs.h
Original file line number Diff line number Diff line change
@@ -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_ */
2 changes: 1 addition & 1 deletion include/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 16 additions & 5 deletions sbat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions sbat_var.S
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 0eb07e1

Please sign in to comment.