summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm.h4
-rw-r--r--include/compiler.h50
-rw-r--r--include/console.h8
-rw-r--r--include/fanalyzer.mk1
-rw-r--r--include/fuzz.mk97
-rw-r--r--include/guid.h1
-rw-r--r--include/httpboot.h2
-rw-r--r--include/netboot.h2
-rw-r--r--include/pe.h14
-rw-r--r--include/peimage.h3
-rw-r--r--include/sbat.h16
-rw-r--r--include/sbat_var_defs.h52
-rw-r--r--include/scan-build.mk1
-rw-r--r--include/ssp.h14
-rw-r--r--include/ssp_var_defs.h19
-rw-r--r--include/test.mk5
16 files changed, 261 insertions, 28 deletions
diff --git a/include/asm.h b/include/asm.h
index 03b06557..f5118b23 100644
--- a/include/asm.h
+++ b/include/asm.h
@@ -40,11 +40,11 @@ static inline void wait_for_debug(void)
{
uint64_t a, b;
int x;
- extern void msleep(unsigned long msecs);
+ extern void usleep(unsigned long usecs);
a = read_counter();
for (x = 0; x < 1000; x++) {
- msleep(1000);
+ usleep(1000);
b = read_counter();
if (a != b)
break;
diff --git a/include/compiler.h b/include/compiler.h
index b0d595f3..8e8a658d 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,5 +198,55 @@
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define GNUC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define CLANG_PREREQ(maj, min) \
+ ((__clang_major__ > (maj)) || \
+ (__clang_major__ == (maj) && __clang_minor__ >= (min)))
+#else
+#define CLANG_PREREQ(maj, min) 0
+#endif
+
+#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
+#define checked_add(addend0, addend1, sum) \
+ __builtin_add_overflow(addend0, addend1, sum)
+#define checked_sub(minuend, subtrahend, difference) \
+ __builtin_sub_overflow(minuend, subtrahend, difference)
+#define checked_mul(factor0, factor1, product) \
+ __builtin_mul_overflow(factor0, factor1, product)
+#else
+#define checked_add(a0, a1, s) \
+ ({ \
+ (*s) = ((a0) + (a1)); \
+ 0; \
+ })
+#define checked_sub(s0, s1, d) \
+ ({ \
+ (*d) = ((s0) - (s1)); \
+ 0; \
+ })
+#define checked_mul(f0, f1, p) \
+ ({ \
+ (*p) = ((f0) * (f1)); \
+ 0; \
+ })
+#endif
+
+#define checked_div(dividend, divisor, quotient) \
+ ({ \
+ bool _ret = True; \
+ if ((divisor) != 0) { \
+ _ret = False; \
+ (quotient) = (dividend) / (divisor); \
+ } \
+ _ret; \
+ })
+
#endif /* !COMPILER_H_ */
// vim:fenc=utf-8:tw=75:et
diff --git a/include/console.h b/include/console.h
index 0c4a5137..7ac4e113 100644
--- a/include/console.h
+++ b/include/console.h
@@ -106,8 +106,8 @@ extern UINT32 verbose;
dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__ - 1, __func__, \
##__VA_ARGS__)
#else
-#define dprint_(...)
-#define dprint(fmt, ...)
+#define dprint_(...) ({ ; })
+#define dprint(fmt, ...) ({ ; })
#endif
extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line,
@@ -122,7 +122,9 @@ extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line,
extern EFI_STATUS print_crypto_errors(EFI_STATUS rc, char *file, const char *func, int line);
#define crypterr(rc) print_crypto_errors((rc), __FILE__, __func__, __LINE__)
-extern VOID msleep(unsigned long msecs);
+#ifndef SHIM_UNIT_TEST
+extern VOID usleep(unsigned long usecs);
+#endif
/* This is used in various things to determine if we should print to the
* console */
diff --git a/include/fanalyzer.mk b/include/fanalyzer.mk
index e0bf4d75..a0679e3e 100644
--- a/include/fanalyzer.mk
+++ b/include/fanalyzer.mk
@@ -21,6 +21,7 @@ fanalyzer-build-all : COMPILER=gcc
fanalyzer-build-all : CCACHE_DISABLE=1
fanalyzer-build-all : FEATUREFLAGS+=-fanalyzer
fanalyzer-build-all : WERRFLAGS=-Werror=analyzer-null-dereference
+fanalyzer-build-all : IGNORE_COMPILER_ERRORS=" || :"
fanalyzer-build-all : all
fanalyzer-no-openssl : | fanalyzer-test
diff --git a/include/fuzz.mk b/include/fuzz.mk
new file mode 100644
index 00000000..f35df415
--- /dev/null
+++ b/include/fuzz.mk
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# fuzz.mk - makefile to fuzz local test programs
+#
+
+.SUFFIXES:
+
+include Make.defaults
+
+CC = clang
+VALGRIND ?=
+DEBUG_PRINTS ?= 0
+OPTIMIZATIONS ?= -Og -ggdb
+FUZZ_ARGS ?=
+CFLAGS = $(OPTIMIZATIONS) -std=gnu11 \
+ -isystem $(TOPDIR)/include/system \
+ $(EFI_INCLUDES) \
+ -Iinclude -iquote . \
+ -isystem /usr/include \
+ -isystem $(shell $(CC) $(ARCH_CFLAGS) -print-file-name=include) \
+ $(ARCH_CFLAGS) \
+ -fsanitize=fuzzer,address \
+ -fshort-wchar \
+ -fno-builtin \
+ -rdynamic \
+ -fno-inline \
+ -fno-eliminate-unused-debug-types \
+ -fno-eliminate-unused-debug-symbols \
+ -gpubnames \
+ -grecord-gcc-switches \
+ $(if $(findstring clang,$(CC)),-Wno-unknown-warning-option) \
+ $(DEFAULT_WARNFLAGS) \
+ -Wsign-compare \
+ -Wno-deprecated-declarations \
+ $(if $(findstring gcc,$(CC)),-Wno-unused-but-set-variable) \
+ -Wno-unused-but-set-variable \
+ -Wno-unused-variable \
+ -Wno-pointer-sign \
+ $(DEFAULT_WERRFLAGS) \
+ -Werror=nonnull \
+ $(shell $(CC) -Werror=nonnull-compare -E -x c /dev/null >/dev/null 2>&1 && echo -Werror=nonnull-compare) \
+ $(ARCH_DEFINES) \
+ -DEFI_FUNCTION_WRAPPER \
+ -DGNU_EFI_USE_MS_ABI -DPAGE_SIZE=4096 \
+ -DSHIM_UNIT_TEST \
+ -DSHIM_ENABLE_LIBFUZZER \
+ "-DDEFAULT_DEBUG_PRINT_STATE=$(DEBUG_PRINTS)"
+
+# On some systems (e.g. Arch Linux), limits.h is in the "include-fixed" instead
+# of the "include" directory
+CFLAGS += -isystem $(shell $(CC) $(ARCH_CFLAGS) -print-file-name=include-fixed)
+
+# And on Debian also check the multi-arch include path
+CFLAGS += -isystem /usr/include/$(shell $(CC) $(ARCH_CFLAGS) -print-multiarch)
+
+libefi-test.a :
+ $(MAKE) -C gnu-efi \
+ COMPILER="$(COMPILER)" \
+ CC="$(CC)" \
+ ARCH=$(ARCH_GNUEFI) \
+ TOPDIR=$(TOPDIR)/gnu-efi \
+ -f $(TOPDIR)/gnu-efi/Makefile \
+ clean lib
+ mv gnu-efi/$(ARCH)/lib/libefi.a $@
+ $(MAKE) -C gnu-efi \
+ COMPILER="$(COMPILER)" \
+ ARCH=$(ARCH_GNUEFI) \
+ TOPDIR=$(TOPDIR)/gnu-efi \
+ -f $(TOPDIR)/gnu-efi/Makefile \
+ clean
+
+fuzz-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S mock-variables.c
+fuzz-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID
+
+fuzzers := $(patsubst %.c,%,$(wildcard fuzz-*.c))
+
+$(fuzzers) :: fuzz-% : | libefi-test.a
+
+$(fuzzers) :: fuzz-% : test.c fuzz-%.c $(fuzz-%_FILES)
+ $(CC) $(CFLAGS) -o $@ $(sort $^ $(wildcard $*.c) $(fuzz-$*_FILES)) libefi-test.a -lefivar
+ $(VALGRIND) ./$@ -max_len=4096 -jobs=24 $(FUZZ_ARGS)
+
+fuzz : $(fuzzers)
+ $(MAKE) -f include/fuzz.mk fuzz-clean
+
+fuzz-clean :
+ @rm -vf random.bin libefi-test.a
+ @rm -vf vgcore.* fuzz*.log
+
+clean : fuzz-clean
+
+all : fuzz-clean fuzz
+
+.PHONY: $(fuzzers) all fuzz clean
+.SECONDARY: random.bin
+
+# vim:ft=make
diff --git a/include/guid.h b/include/guid.h
index dad63f0f..898c4fad 100644
--- a/include/guid.h
+++ b/include/guid.h
@@ -37,5 +37,6 @@ extern EFI_GUID SECURITY2_PROTOCOL_GUID;
extern EFI_GUID EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
extern EFI_GUID SHIM_LOCK_GUID;
extern EFI_GUID MOK_VARIABLE_STORE;
+extern EFI_GUID SECUREBOOT_EFI_NAMESPACE_GUID;
#endif /* SHIM_GUID_H */
diff --git a/include/httpboot.h b/include/httpboot.h
index ea9c57fe..119c546d 100644
--- a/include/httpboot.h
+++ b/include/httpboot.h
@@ -12,6 +12,6 @@
extern BOOLEAN find_httpboot(EFI_HANDLE device);
extern EFI_STATUS httpboot_fetch_buffer(EFI_HANDLE image, VOID **buffer,
- UINT64 *buf_size);
+ UINT64 *buf_size, CHAR8 *name);
#endif /* SHIM_HTTPBOOT_H */
diff --git a/include/netboot.h b/include/netboot.h
index 98b174a3..a7bf6cd8 100644
--- a/include/netboot.h
+++ b/include/netboot.h
@@ -5,7 +5,7 @@
extern BOOLEAN findNetboot(EFI_HANDLE image_handle);
-extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle);
+extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle, CHAR8 *name);
extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz);
diff --git a/include/pe.h b/include/pe.h
index ccc8798b..9ea9eb44 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -22,6 +22,20 @@ EFI_STATUS
verify_sbat_section(char *SBATBase, size_t SBATSize);
EFI_STATUS
+get_section_vma (UINTN section_num,
+ char *buffer, size_t bufsz UNUSED,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ char **basep, size_t *sizep,
+ EFI_IMAGE_SECTION_HEADER **sectionp);
+
+EFI_STATUS
+get_section_vma_by_name (char *name, size_t namesz,
+ char *buffer, size_t bufsz,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ char **basep, size_t *sizep,
+ EFI_IMAGE_SECTION_HEADER **sectionp);
+
+EFI_STATUS
handle_image (void *data, unsigned int datasize,
EFI_LOADED_IMAGE *li,
EFI_IMAGE_ENTRY_POINT *entry_point,
diff --git a/include/peimage.h b/include/peimage.h
index e97b29c4..6eef1051 100644
--- a/include/peimage.h
+++ b/include/peimage.h
@@ -29,6 +29,9 @@
#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))
+// Check if `val` is evenly aligned to the page size.
+#define IS_PAGE_ALIGNED(val) (!((val) & EFI_PAGE_MASK))
+
//
// PE32+ Subsystem type for EFI images
//
diff --git a/include/sbat.h b/include/sbat.h
index c94c4fba..bb523e7e 100644
--- a/include/sbat.h
+++ b/include/sbat.h
@@ -30,10 +30,15 @@
#define SBAT_POLICY L"SbatPolicy"
#define SBAT_POLICY8 "SbatPolicy"
+#define SSP_POLICY L"SSPPolicy"
+#define SSP_POLICY8 "SSPPolicy"
-#define SBAT_POLICY_LATEST 1
-#define SBAT_POLICY_PREVIOUS 2
-#define SBAT_POLICY_RESET 3
+#define POLICY_LATEST 1
+#define POLICY_AUTOMATIC 2
+#define POLICY_RESET 3
+#define POLICY_NOTREAD 255
+
+#define REVOCATIONFILE L"revocations.efi"
extern UINTN _sbat, _esbat;
@@ -50,9 +55,10 @@ extern list_t sbat_var;
#define SBAT_VAR_COLUMNS ((sizeof (struct sbat_var_entry) - sizeof(list_t)) / sizeof(CHAR8 *))
#define SBAT_VAR_REQUIRED_COLUMNS (SBAT_VAR_COLUMNS - 1)
-EFI_STATUS parse_sbat_var(list_t *entries);
+EFI_STATUS parse_sbat_var(list_t *entries, char *sbat_var_candidate);
void cleanup_sbat_var(list_t *entries);
-EFI_STATUS set_sbat_uefi_variable(void);
+EFI_STATUS set_sbat_uefi_variable_internal(void);
+EFI_STATUS set_sbat_uefi_variable(char *, char *);
bool preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize,
UINT32 attributes, char *sbar_var);
diff --git a/include/sbat_var_defs.h b/include/sbat_var_defs.h
index 6b01573e..f8cba029 100644
--- a/include/sbat_var_defs.h
+++ b/include/sbat_var_defs.h
@@ -3,6 +3,9 @@
#ifndef SBAT_VAR_DEFS_H_
#define SBAT_VAR_DEFS_H_
+#define QUOTEVAL(s) QUOTE(s)
+#define QUOTE(s) #s
+
/*
* This is the entry for the sbat data format
*/
@@ -13,11 +16,9 @@
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_AUTOMATIC_DATE "2021030218"
+#define SBAT_VAR_AUTOMATIC \
+ SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_AUTOMATIC_DATE "\n"
#define SBAT_VAR_LATEST_DATE "2022050100"
#define SBAT_VAR_LATEST_REVOCATIONS "component,2\nothercomponent,2\n"
@@ -25,21 +26,42 @@
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.
+ * Some distros may want to apply revocations from 2022052400
+ * or 2022111500 automatically. They can be selected by setting
+ * SBAT_AUTOMATIC_DATE=<datestamp> at build time. Otherwise the
+ * default is to apply the second to most recent revocations
+ * automatically. Distros that need to manage automatic updates
+ * externally from shim can choose the epoch 2021030218 emtpy
+ * revocations.
*/
-#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
+#ifndef SBAT_AUTOMATIC_DATE
+#define SBAT_AUTOMATIC_DATE 2023012900
+#endif /* SBAT_AUTOMATIC_DATE */
+#if SBAT_AUTOMATIC_DATE == 2021030218
+#define SBAT_VAR_AUTOMATIC_REVOCATIONS
+#elif SBAT_AUTOMATIC_DATE == 2022052400
+#define SBAT_VAR_AUTOMATIC_REVOCATIONS "grub,2\n"
+#elif SBAT_AUTOMATIC_DATE == 2022111500
+#define SBAT_VAR_AUTOMATIC_REVOCATIONS "shim,2\ngrub,3\n"
+#elif SBAT_AUTOMATIC_DATE == 2023012900
+#define SBAT_VAR_AUTOMATIC_REVOCATIONS "shim,2\ngrub,3\ngrub.debian,4\n"
+#else
+#error "Unknown SBAT_AUTOMATIC_DATE"
+#endif /* SBAT_AUTOMATIC_DATE == */
+#define SBAT_VAR_AUTOMATIC_DATE QUOTEVAL(SBAT_AUTOMATIC_DATE)
+#define SBAT_VAR_AUTOMATIC \
+ SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_AUTOMATIC_DATE "\n" \
+ SBAT_VAR_AUTOMATIC_REVOCATIONS
-#define SBAT_VAR_LATEST_DATE "2022111500"
-#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,3\n"
+/*
+ * Revocations for January 2024 shim CVEs
+ */
+#define SBAT_VAR_LATEST_DATE "2024010900"
+#define SBAT_VAR_LATEST_REVOCATIONS "shim,4\ngrub,3\ngrub.debian,4\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/scan-build.mk b/include/scan-build.mk
index 3ed7660e..170ba836 100644
--- a/include/scan-build.mk
+++ b/include/scan-build.mk
@@ -22,6 +22,7 @@ scan-build-unchecked-openssl : Cryptlib/OpenSSL/libopenssl.a
scan-build-all : CCACHE_DISABLE=1
scan-build-all : COMPILER=clang
+scan-build-all : IGNORE_COMPILER_ERRORS=" || :"
scan-build-all : | scan-test
scan-build-all :
+scan-build -o scan-results make $(MAKEARGS) $(DASHJ) CCACHE_DISABLE=1 all
diff --git a/include/ssp.h b/include/ssp.h
new file mode 100644
index 00000000..f25590c6
--- /dev/null
+++ b/include/ssp.h
@@ -0,0 +1,14 @@
+#ifndef SSP_H_
+#define SSP_H_
+
+#define SSPVER_VAR_NAME L"SkuSiPolicyVersion"
+#define SSPSIG_VAR_NAME L"SkuSiPolicyUpdateSigners"
+#define SSP_VAR_ATTRS UEFI_VAR_NV_BS
+
+#define SSPVER_SIZE 8
+#define SSPSIG_SIZE 131
+
+EFI_STATUS set_ssp_uefi_variable_internal(void);
+EFI_STATUS set_ssp_uefi_variable(uint8_t*, uint8_t*, uint8_t*, uint8_t*);
+
+#endif /* !SSP_H_ */
diff --git a/include/ssp_var_defs.h b/include/ssp_var_defs.h
new file mode 100644
index 00000000..4bfad878
--- /dev/null
+++ b/include/ssp_var_defs.h
@@ -0,0 +1,19 @@
+/*
+ * variable definitions to enable bootmgr self revocation
+ */
+#ifndef SSP_VAR_DEFS_H_
+#define SSP_VAR_DEFS_H_
+
+uint8_t SkuSiPolicyVersion[] = { 0x2,0x0,0x0,0x0,0x0,0x0,0x2,0x0 };
+uint8_t SkuSiPolicyUpdateSigners[] = {
+0x01,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+0x0b,0x00,0x00,0x00,0xd0,0x91,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
+0x00,0x00,0x00,0x00,0x54,0xa6,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
+0x00,0x00,0x00,0x00,0x5c,0xa6,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,
+0x00,0x00,0x00,0x00,0x64,0xa6,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x03,0x06,0x00,
+0x00,0x00,0x00 };
+
+#endif /* !SSP_VAR_DEFS_H_ */
diff --git a/include/test.mk b/include/test.mk
index c0e24095..e6d46594 100644
--- a/include/test.mk
+++ b/include/test.mk
@@ -92,9 +92,12 @@ 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 sbat_var.S
+test-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S mock-variables.c
test-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID
+test-pe-relocate_FILES = globals.c
+test-pe-relocate :: CFLAGS+=-DHAVE_SHIM_LOCK_GUID
+
test-str_FILES = lib/string.c
tests := $(patsubst %.c,%,$(wildcard test-*.c))