From 2dd2f7600d41253fe621b8d040ab57f0c202d71b Mon Sep 17 00:00:00 2001 From: Steve McIntyre Date: Sun, 22 Jan 2023 13:05:10 +0000 Subject: [PATCH] New upstream version 15.7 --- Cryptlib/Pk/CryptAuthenticode.c | 4 +- Make.defaults | 2 +- Makefile | 9 ++-- README.md | 2 + commit | 2 +- data/sbat.csv | 2 +- elf_aarch64_efi.lds | 4 ++ elf_ia32_efi.lds | 4 ++ elf_ia64_efi.lds | 4 ++ elf_x86_64_efi.lds | 4 ++ include/cc.h | 85 +++++++++++++++++++++++++++++++++ include/compiler.h | 6 +++ include/guid.h | 1 + include/sbat.h | 32 ------------- include/sbat_var_defs.h | 45 +++++++++++++++++ include/test.mk | 2 +- include/ucs2.h | 18 ------- lib/guid.c | 1 + load-options.c | 7 ++- make-archive | 4 +- model.c | 23 ++++++++- mok.c | 1 - pe.c | 5 +- sbat.c | 21 ++++++-- sbat_var.S | 20 ++++++++ shim.c | 18 +++---- shim.h | 2 + tpm.c | 48 +++++++++++++++++++ 28 files changed, 294 insertions(+), 82 deletions(-) create mode 100644 include/cc.h create mode 100644 include/sbat_var_defs.h create mode 100644 sbat_var.S diff --git a/Cryptlib/Pk/CryptAuthenticode.c b/Cryptlib/Pk/CryptAuthenticode.c index 74e50a2..f6f988b 100644 --- a/Cryptlib/Pk/CryptAuthenticode.c +++ b/Cryptlib/Pk/CryptAuthenticode.c @@ -9,7 +9,7 @@ AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for data structure. -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -106,7 +106,7 @@ AuthenticodeVerify ( // // Check if it's PKCS#7 Signed Data (for Authenticode Scenario) // - if (!PKCS7_type_is_signed (Pkcs7)) { + if (!PKCS7_type_is_signed (Pkcs7) || PKCS7_get_detached (Pkcs7)) { goto _Exit; } diff --git a/Make.defaults b/Make.defaults index dfed9c4..c46164a 100644 --- a/Make.defaults +++ b/Make.defaults @@ -71,7 +71,7 @@ ifeq ($(ARCH),x86_64) endif ifeq ($(ARCH),ia32) ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \ - $(CLANG_BUGS) -m32 \ + $(CLANG_BUGS) -m32 -malign-double \ -DMDE_CPU_IA32 -DPAGE_SIZE=4096 ARCH_GNUEFI ?= ia32 ARCH_SUFFIX ?= ia32 diff --git a/Makefile b/Makefile index 24ac314..a9202f4 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ default : all NAME = shim -VERSION = 15.6 +VERSION = 15.7 ifneq ($(origin RELEASE),undefined) DASHRELEASE ?= -$(RELEASE) else @@ -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 \ diff --git a/README.md b/README.md index ce6bad7..60d51b6 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,5 @@ pub.cer and build with `make VENDOR_CERT_FILE=pub.cer`. There are a couple of build options, and a couple of ways to customize the build, described in [BUILDING](BUILDING). + +See the [test plan](testplan.txt), and file a ticket if anything fails! diff --git a/commit b/commit index 4605976..ba705c6 100644 --- a/commit +++ b/commit @@ -1 +1 @@ -505cdb678b319fcf9a7fdee77c0f091b4147cbe5 \ No newline at end of file +11491619f4336fef41c3519877ba242161763580 \ No newline at end of file diff --git a/data/sbat.csv b/data/sbat.csv index 7a5169f..2beec75 100755 --- a/data/sbat.csv +++ b/data/sbat.csv @@ -1,2 +1,2 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -shim,2,UEFI shim,shim,1,https://github.com/rhboot/shim +shim,3,UEFI shim,shim,1,https://github.com/rhboot/shim diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds index 60c55ba..0861f5e 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 497a3a1..e8da91b 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 2669b85..a219560 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 bcc6527..39aff6b 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/cc.h b/include/cc.h new file mode 100644 index 0000000..8b12720 --- /dev/null +++ b/include/cc.h @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef SHIM_CC_H +#define SHIM_CC_H + +typedef struct { + uint8_t Major; + uint8_t Minor; +} EFI_CC_VERSION; + +#define EFI_CC_TYPE_NONE 0 +#define EFI_CC_TYPE_SEV 1 +#define EFI_CC_TYPE_TDX 2 + +typedef struct { + uint8_t Type; + uint8_t SubType; +} EFI_CC_TYPE; + +typedef uint32_t EFI_CC_EVENT_LOG_BITMAP; +typedef uint32_t EFI_CC_EVENT_LOG_FORMAT; +typedef uint32_t EFI_CC_EVENT_ALGORITHM_BITMAP; +typedef uint32_t EFI_CC_MR_INDEX; + +#define TDX_MR_INDEX_MRTD 0 +#define TDX_MR_INDEX_RTMR0 1 +#define TDX_MR_INDEX_RTMR1 2 +#define TDX_MR_INDEX_RTMR2 3 +#define TDX_MR_INDEX_RTMR3 4 + +#define EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 +#define EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 +#define EFI_CC_EVENT_HEADER_VERSION 1 + +typedef struct tdEFI_CC_EVENT_HEADER { + uint32_t HeaderSize; + uint16_t HeaderVersion; + EFI_CC_MR_INDEX MrIndex; + uint32_t EventType; +} __attribute__((packed)) EFI_CC_EVENT_HEADER; + +typedef struct tdEFI_CC_EVENT { + uint32_t Size; + EFI_CC_EVENT_HEADER Header; + uint8_t Event[1]; +} __attribute__((packed)) EFI_CC_EVENT; + +typedef struct tdEFI_CC_BOOT_SERVICE_CAPABILITY { + uint8_t Size; + EFI_CC_VERSION StructureVersion; + EFI_CC_VERSION ProtocolVersion; + EFI_CC_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; + EFI_CC_EVENT_LOG_BITMAP SupportedEventLogs; + EFI_CC_TYPE CcType; +} EFI_CC_BOOT_SERVICE_CAPABILITY; + +struct efi_cc_protocol +{ + EFI_STATUS (EFIAPI *get_capability) ( + struct efi_cc_protocol *this, + EFI_CC_BOOT_SERVICE_CAPABILITY *ProtocolCapability); + EFI_STATUS (EFIAPI *get_event_log) ( + struct efi_cc_protocol *this, + EFI_CC_EVENT_LOG_FORMAT EventLogFormat, + EFI_PHYSICAL_ADDRESS *EventLogLocation, + EFI_PHYSICAL_ADDRESS *EventLogLastEntry, + BOOLEAN *EventLogTruncated); + EFI_STATUS (EFIAPI *hash_log_extend_event) ( + struct efi_cc_protocol *this, + uint64_t Flags, + EFI_PHYSICAL_ADDRESS DataToHash, + uint64_t DataToHashLen, + EFI_CC_EVENT *EfiCcEvent); + EFI_STATUS (EFIAPI *map_pcr_to_mr_index) ( + struct efi_cc_protocol *this, + uint32_t PcrIndex, + EFI_CC_MR_INDEX *MrIndex); +}; + +typedef struct efi_cc_protocol efi_cc_protocol_t; + +#define EFI_CC_FLAG_PE_COFF_IMAGE 0x0000000000000010 + +#endif /* SHIM_CC_H */ +// vim:fenc=utf-8:tw=75 diff --git a/include/compiler.h b/include/compiler.h index b4bf103..b0d595f 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -192,5 +192,11 @@ */ #define unreachable() __builtin_unreachable() +#if defined(__GNUC__) +#define cache_invalidate(begin, end) __builtin___clear_cache(begin, end) +#else /* __GNUC__ */ +#error shim has no cache_invalidate() implementation for this compiler +#endif /* __GNUC__ */ + #endif /* !COMPILER_H_ */ // vim:fenc=utf-8:tw=75:et diff --git a/include/guid.h b/include/guid.h index d9910ff..dad63f0 100644 --- a/include/guid.h +++ b/include/guid.h @@ -29,6 +29,7 @@ extern EFI_GUID EFI_IP6_CONFIG_GUID; extern EFI_GUID EFI_LOADED_IMAGE_GUID; extern EFI_GUID EFI_TPM_GUID; extern EFI_GUID EFI_TPM2_GUID; +extern EFI_GUID EFI_CC_MEASUREMENT_PROTOCOL_GUID; extern EFI_GUID EFI_SECURE_BOOT_DB_GUID; extern EFI_GUID EFI_SIMPLE_FILE_SYSTEM_GUID; extern EFI_GUID SECURITY_PROTOCOL_GUID; diff --git a/include/sbat.h b/include/sbat.h index aca4359..c94c4fb 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 0000000..6b01573 --- /dev/null +++ b/include/sbat_var_defs.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifndef SBAT_VAR_DEFS_H_ +#define SBAT_VAR_DEFS_H_ + +/* + * This is the entry for the sbat data format + */ +#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 */ +/* + * As of 2022-11-16, most folks (including Ubuntu, SUSE, openSUSE) don't have + * a "shim,2" yet, so adding that here would end up unbootable. + */ +#define SBAT_VAR_PREVIOUS_DATE "2022052400" +#define SBAT_VAR_PREVIOUS_REVOCATIONS "grub,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 "2022111500" +#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,3\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/include/test.mk b/include/test.mk index e965c60..c0e2409 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/include/ucs2.h b/include/ucs2.h index ee038ce..87eab32 100644 --- a/include/ucs2.h +++ b/include/ucs2.h @@ -63,22 +63,4 @@ StrCSpn(const CHAR16 *s, const CHAR16 *reject) return ret; } -/* - * Test if an entire buffer is nothing but NUL characters. This - * implementation "gracefully" ignores the difference between the - * UTF-8/ASCII 1-byte NUL and the UCS-2 2-byte NUL. - */ -static inline bool -__attribute__((__unused__)) -is_all_nuls(UINT8 *data, UINTN data_size) -{ - UINTN i; - - for (i = 0; i < data_size; i++) { - if (data[i] != 0) - return false; - } - return true; -} - #endif /* SHIM_UCS2_H */ diff --git a/lib/guid.c b/lib/guid.c index e100c92..904629e 100644 --- a/lib/guid.c +++ b/lib/guid.c @@ -28,6 +28,7 @@ EFI_GUID EFI_IP6_CONFIG_GUID = { 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, EFI_GUID EFI_LOADED_IMAGE_GUID = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID EFI_TPM_GUID = { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }; EFI_GUID EFI_TPM2_GUID = { 0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }; +EFI_GUID EFI_CC_MEASUREMENT_PROTOCOL_GUID = { 0x96751a3d, 0x72f4, 0x41a6, {0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } }; EFI_GUID EFI_SECURE_BOOT_DB_GUID = { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f } }; EFI_GUID EFI_SIMPLE_FILE_SYSTEM_GUID = SIMPLE_FILE_SYSTEM_PROTOCOL; EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } }; diff --git a/load-options.c b/load-options.c index c6bb742..a8c6e1a 100644 --- a/load-options.c +++ b/load-options.c @@ -404,8 +404,13 @@ parse_load_options(EFI_LOADED_IMAGE *li) /* * Apparently sometimes we get L"\0\0"? Which isn't useful at all. + * + * Possibly related, but some boards have additional data before the + * size which is garbage (it's a weird path to the directory + * containing the loaders). Known boards that do this: Kontron VX3040 + * (AMI), ASUS B85M-E, and at least one "older Dell laptop". */ - if (is_all_nuls(li->LoadOptions, li->LoadOptionsSize)) + if (((CHAR16 *)li->LoadOptions)[0] == 0) return EFI_SUCCESS; /* diff --git a/make-archive b/make-archive index d4f095f..9ae9eef 100755 --- a/make-archive +++ b/make-archive @@ -86,14 +86,16 @@ main() { cd .. if [ "x" = "x${SHIM_GIT_TAG}" ] ; then git archive --format=tar "$(git log -1 --pretty=format:%h)" | ( cd "${ARCHIVE_DIR}/shim-${VERSION}" ; tar x ) + TIMESTAMP=0 else # ORIGIN doesn't yet have this tag git archive --format=tar "${SHIM_GIT_TAG}" | ( cd "${ARCHIVE_DIR}/shim-${VERSION}" ; tar x ) + TIMESTAMP=$(git log -1 --pretty=%ct "${SHIM_GIT_TAG}") fi git log -1 --pretty=format:%H > "${ARCHIVE_DIR}/shim-${VERSION}/commit" DIR="$PWD" cd "${ARCHIVE_DIR}" - tar -c --bzip2 -f "${DIR}/shim-${VERSION}.tar.bz2" "shim-${VERSION}" + tar -c --sort=name --mtime="@${TIMESTAMP}" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --bzip2 -f "${DIR}/shim-${VERSION}.tar.bz2" "shim-${VERSION}" rm -rf "${ARCHIVE_DIR}" echo "The archive is in shim-${VERSION}.tar.bz2" exit 0 diff --git a/model.c b/model.c index 50e3f0d..e122ba9 100644 --- a/model.c +++ b/model.c @@ -8,16 +8,18 @@ /* This is so vim's Syntastic checker won't yell about all these. */ extern void __coverity_string_size_sanitize__(int); extern void __coverity_negative_sink__(int); -extern void __coverity_alloc_nosize__(void); +extern void *__coverity_alloc_nosize__(void); +extern void __coverity_writeall0__(void *); extern void *__coverity_alloc__(int); extern void __coverity_sleep__(); extern void __coverity_tainted_data_sanitize__(void *); +extern void __coverity_free__(void *); #endif void * OBJ_dup(void *o) { - __coverity_alloc_nosize__(); + return __coverity_alloc_nosize__(); } int @@ -133,4 +135,21 @@ AllocatePages(EFI_ALLOCATE_TYPE Type, return EFI_OUT_OF_RESOURCES; } +void * +AllocateZeroPool(int sz) +{ + void *ptr; + + __coverity_negative_sink__(sz); + ptr = __coverity_alloc__(sz); + __coverity_writeall0__(ptr); + return ptr; +} + +void +FreePool(void *ptr) +{ + __coverity_free__(ptr); +} + // vim:fenc=utf-8:tw=75 diff --git a/mok.c b/mok.c index 63ddfca..9811b35 100644 --- a/mok.c +++ b/mok.c @@ -178,7 +178,6 @@ struct mok_state_variable mok_state_variable_data[] = { EFI_VARIABLE_NON_VOLATILE, .no_attr = EFI_VARIABLE_RUNTIME_ACCESS, .flags = MOK_MIRROR_DELETE_FIRST | - MOK_VARIABLE_MEASURE | MOK_VARIABLE_INVERSE | MOK_VARIABLE_LOG, .pcr = 14, diff --git a/pe.c b/pe.c index ba3e2bb..9a3679e 100644 --- a/pe.c +++ b/pe.c @@ -1196,6 +1196,9 @@ handle_image (void *data, unsigned int datasize, CopyMem(buffer, data, context.SizeOfHeaders); + /* Flush the instruction cache for the region holding the image */ + cache_invalidate(buffer, buffer + context.ImageSize); + *entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint); if (!*entry_point) { perror(L"Entry point is invalid\n"); @@ -1256,7 +1259,7 @@ handle_image (void *data, unsigned int datasize, } if (Section->VirtualAddress <= context.EntryPoint && - (Section->VirtualAddress + Section->SizeOfRawData - 1) + (Section->VirtualAddress + Section->Misc.VirtualSize - 1) > context.EntryPoint) found_entry_point++; diff --git a/sbat.c b/sbat.c index f1d6e98..a08c5b2 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/sbat_var.S b/sbat_var.S new file mode 100644 index 0000000..a115077 --- /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/shim.c b/shim.c index fdd205e..4437898 100644 --- a/shim.c +++ b/shim.c @@ -397,22 +397,22 @@ static EFI_STATUS check_allowlist (WIN_CERTIFICATE_EFI_PKCS *cert, } #endif - if (check_db_hash(L"MokList", SHIM_LOCK_GUID, sha256hash, + if (check_db_hash(L"MokListRT", SHIM_LOCK_GUID, sha256hash, SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) == DATA_FOUND) { verification_method = VERIFIED_BY_HASH; update_verification_method(VERIFIED_BY_HASH); return EFI_SUCCESS; } else { - LogError(L"check_db_hash(MokList, sha256hash) != DATA_FOUND\n"); + LogError(L"check_db_hash(MokListRT, sha256hash) != DATA_FOUND\n"); } - if (cert && check_db_cert(L"MokList", SHIM_LOCK_GUID, cert, sha256hash) + if (cert && check_db_cert(L"MokListRT", SHIM_LOCK_GUID, cert, sha256hash) == DATA_FOUND) { verification_method = VERIFIED_BY_CERT; update_verification_method(VERIFIED_BY_CERT); return EFI_SUCCESS; } else if (cert) { - LogError(L"check_db_cert(MokList, sha256hash) != DATA_FOUND\n"); + LogError(L"check_db_cert(MokListRT, sha256hash) != DATA_FOUND\n"); } update_verification_method(VERIFIED_BY_NOTHING); @@ -1395,7 +1395,6 @@ EFI_STATUS load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) { EFI_STATUS efi_status; - EFI_LOADED_IMAGE li; PE_COFF_LOADER_IMAGE_CONTEXT context; EFI_IMAGE_SECTION_HEADER *Section; EFI_SIGNATURE_LIST *certlist; @@ -1410,10 +1409,7 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) if (EFI_ERROR(efi_status)) return efi_status; - memset(&li, 0, sizeof(li)); - memcpy(&li.FilePath[0], filename, MIN(StrSize(filename), sizeof(li.FilePath))); - - efi_status = verify_image(data, datasize, &li, &context); + efi_status = verify_image(data, datasize, shim_li, &context); if (EFI_ERROR(efi_status)) return efi_status; @@ -1433,8 +1429,8 @@ load_cert_file(EFI_HANDLE image_handle, CHAR16 *filename, CHAR16 *PathName) user_cert_size += certlist->SignatureListSize;; user_cert = ReallocatePool(user_cert, original, user_cert_size); - memcpy(user_cert + original, pointer, - certlist->SignatureListSize); + CopyMem(user_cert + original, pointer, + certlist->SignatureListSize); } } FreePool(data); diff --git a/shim.h b/shim.h index b5272b9..14824c6 100644 --- a/shim.h +++ b/shim.h @@ -179,12 +179,14 @@ #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 #include "include/simple_file.h" #include "include/str.h" #include "include/tpm.h" +#include "include/cc.h" #include "include/ucs2.h" #include "include/variables.h" #include "include/hexdump.h" diff --git a/tpm.c b/tpm.c index 41f3665..388f8d1 100644 --- a/tpm.c +++ b/tpm.c @@ -108,6 +108,45 @@ static EFI_STATUS tpm_locate_protocol(efi_tpm_protocol_t **tpm, return EFI_NOT_FOUND; } +static EFI_STATUS cc_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, + UINT8 pcr, const CHAR8 *log, UINTN logsize, + UINT32 type, BOOLEAN is_pe_image) +{ + EFI_STATUS efi_status; + EFI_CC_EVENT *event; + efi_cc_protocol_t *cc; + EFI_CC_MR_INDEX mr; + uint64_t flags = is_pe_image ? EFI_CC_FLAG_PE_COFF_IMAGE : 0; + + efi_status = LibLocateProtocol(&EFI_CC_MEASUREMENT_PROTOCOL_GUID, + (VOID **)&cc); + if (EFI_ERROR(efi_status) || !cc) + return EFI_SUCCESS; + + efi_status = cc->map_pcr_to_mr_index(cc, pcr, &mr); + if (EFI_ERROR(efi_status)) + return EFI_NOT_FOUND; + + UINTN event_size = sizeof(*event) - sizeof(event->Event) + logsize; + + event = AllocatePool(event_size); + if (!event) { + perror(L"Unable to allocate event structure\n"); + return EFI_OUT_OF_RESOURCES; + } + + event->Header.HeaderSize = sizeof(EFI_CC_EVENT_HEADER); + event->Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION; + event->Header.MrIndex = mr; + event->Header.EventType = type; + event->Size = event_size; + CopyMem(event->Event, (VOID *)log, logsize); + efi_status = cc->hash_log_extend_event(cc, flags, buf, (UINT64)size, + event); + FreePool(event); + return efi_status; +} + static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *log, UINTN logsize, UINT32 type, CHAR8 *hash) @@ -118,6 +157,15 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, BOOLEAN old_caps; EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; + /* CC guest like TDX or SEV will measure the buffer and log the event, + extend the result into a specific CC MR like TCG's PCR. It could + coexists with TCG's TPM 1.2 and TPM 2. + */ + efi_status = cc_log_event_raw(buf, size, pcr, log, logsize, type, + (hash != NULL)); + if (EFI_ERROR(efi_status)) + return efi_status; + efi_status = tpm_locate_protocol(&tpm, &tpm2, &old_caps, &caps); if (EFI_ERROR(efi_status)) { #ifdef REQUIRE_TPM