import shim-unsigned-x64-15-7.el8
This commit is contained in:
parent
6bae97a401
commit
00a828377a
@ -0,0 +1,29 @@
|
|||||||
|
From 1d50318f448b73b072724eb6664d311e6084a446 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Tue, 10 Apr 2018 12:36:34 -0400
|
||||||
|
Subject: [PATCH 01/62] Make some things dprint() instead of console_print()
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: dad59f8c0f36
|
||||||
|
---
|
||||||
|
shim.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 00155346c12..ff0817009cd 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2087,8 +2087,8 @@ static int is_our_path(EFI_LOADED_IMAGE *li, CHAR16 *path, UINTN len)
|
||||||
|
if (!dppath)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- console_print(L"dppath: %s\n", dppath);
|
||||||
|
- console_print(L"path: %s\n", path);
|
||||||
|
+ dprint(L"dppath: %s\n", dppath);
|
||||||
|
+ dprint(L"path: %s\n", path);
|
||||||
|
if (StrnCaseCmp(dppath, path, len))
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,131 @@
|
|||||||
|
From 32f71225382ddb7dd1ad51f584bc3d42a7ee39d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 12 Apr 2018 13:24:48 -0400
|
||||||
|
Subject: [PATCH 02/62] Makefiles: ensure -m32 gets propogated to our gcc
|
||||||
|
parameter queries
|
||||||
|
|
||||||
|
'gcc -print-file-name=include' and 'gcc -print-libgcc-file-name' both
|
||||||
|
need -m32 when we're building 32-on-64 on some distros, so ensure that
|
||||||
|
gets propogated correctly.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 104d6e54ac7
|
||||||
|
---
|
||||||
|
Make.defaults | 66 ++++++++++++++++++++++++++-------------------------
|
||||||
|
1 file changed, 34 insertions(+), 32 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Make.defaults b/Make.defaults
|
||||||
|
index e11ab5a7f2c..bbfc1d7f77b 100644
|
||||||
|
--- a/Make.defaults
|
||||||
|
+++ b/Make.defaults
|
||||||
|
@@ -33,66 +33,46 @@ EFI_INCLUDES = -nostdinc -I$(TOPDIR)/Cryptlib -I$(TOPDIR)/Cryptlib/Include \
|
||||||
|
-I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol \
|
||||||
|
-I$(TOPDIR)/include -iquote $(TOPDIR) -iquote $(shell pwd)
|
||||||
|
|
||||||
|
-LIB_GCC = $(shell $(CC) -print-libgcc-file-name)
|
||||||
|
-EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC)
|
||||||
|
-
|
||||||
|
EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o
|
||||||
|
EFI_LDS = $(TOPDIR)/elf_$(ARCH)_efi.lds
|
||||||
|
|
||||||
|
-CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
|
||||||
|
- -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
|
||||||
|
- -Werror=sign-compare -ffreestanding -std=gnu89 \
|
||||||
|
- -I$(shell $(CC) -print-file-name=include) \
|
||||||
|
- "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
|
||||||
|
- "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
|
||||||
|
- $(EFI_INCLUDES)
|
||||||
|
-
|
||||||
|
CLANG_BUGS = $(if $(findstring gcc,$(CC)),-maccumulate-outgoing-args,)
|
||||||
|
|
||||||
|
COMMIT_ID ?= $(shell if [ -e .git ] ; then git log -1 --pretty=format:%H ; elif [ -f commit ]; then cat commit ; else echo master; fi)
|
||||||
|
|
||||||
|
-ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
|
||||||
|
- CFLAGS += -DOVERRIDE_SECURITY_POLICY
|
||||||
|
-endif
|
||||||
|
-
|
||||||
|
-ifneq ($(origin ENABLE_HTTPBOOT), undefined)
|
||||||
|
- CFLAGS += -DENABLE_HTTPBOOT
|
||||||
|
-endif
|
||||||
|
-
|
||||||
|
-ifneq ($(origin REQUIRE_TPM), undefined)
|
||||||
|
- CFLAGS += -DREQUIRE_TPM
|
||||||
|
-endif
|
||||||
|
-
|
||||||
|
ifeq ($(ARCH),x86_64)
|
||||||
|
- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
||||||
|
- $(CLANG_BUGS) -m64 \
|
||||||
|
- -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \
|
||||||
|
- -DNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 -DPAGE_SIZE=4096
|
||||||
|
+ ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
||||||
|
+ $(CLANG_BUGS) -m64 \
|
||||||
|
+ -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI \
|
||||||
|
+ -DNO_BUILTIN_VA_FUNCS -DMDE_CPU_X64 \
|
||||||
|
+ -DPAGE_SIZE=4096
|
||||||
|
LIBDIR ?= $(prefix)/lib64
|
||||||
|
ARCH_SUFFIX ?= x64
|
||||||
|
ARCH_SUFFIX_UPPER ?= X64
|
||||||
|
ARCH_LDFLAGS ?=
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),ia32)
|
||||||
|
- CFLAGS += -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
||||||
|
- $(CLANG_BUGS) -m32 \
|
||||||
|
- -DMDE_CPU_IA32 -DPAGE_SIZE=4096
|
||||||
|
+ ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
||||||
|
+ $(CLANG_BUGS) -m32 \
|
||||||
|
+ -DMDE_CPU_IA32 -DPAGE_SIZE=4096
|
||||||
|
LIBDIR ?= $(prefix)/lib
|
||||||
|
ARCH_SUFFIX ?= ia32
|
||||||
|
ARCH_SUFFIX_UPPER ?= IA32
|
||||||
|
ARCH_LDFLAGS ?=
|
||||||
|
+ ARCH_CFLAGS ?= -m32
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),aarch64)
|
||||||
|
- CFLAGS += -DMDE_CPU_AARCH64 -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
+ ARCH_CFLAGS ?= -DMDE_CPU_AARCH64 -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
LIBDIR ?= $(prefix)/lib64
|
||||||
|
ARCH_SUFFIX ?= aa64
|
||||||
|
ARCH_SUFFIX_UPPER ?= AA64
|
||||||
|
FORMAT := -O binary
|
||||||
|
SUBSYSTEM := 0xa
|
||||||
|
ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
|
||||||
|
+ ARCH_CFLAGS ?=
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),arm)
|
||||||
|
- CFLAGS += -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
+ ARCH_CFLAGS ?= -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
LIBDIR ?= $(prefix)/lib
|
||||||
|
ARCH_SUFFIX ?= arm
|
||||||
|
ARCH_SUFFIX_UPPER ?= ARM
|
||||||
|
@@ -101,6 +81,28 @@ ifeq ($(ARCH),arm)
|
||||||
|
ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
|
||||||
|
endif
|
||||||
|
|
||||||
|
+CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
|
||||||
|
+ -fshort-wchar -Wall -Wsign-compare -Werror -fno-builtin \
|
||||||
|
+ -Werror=sign-compare -ffreestanding -std=gnu89 \
|
||||||
|
+ -I$(shell $(CC) $(ARCH_CFLAGS) -print-file-name=include) \
|
||||||
|
+ "-DDEFAULT_LOADER=L\"$(DEFAULT_LOADER)\"" \
|
||||||
|
+ "-DDEFAULT_LOADER_CHAR=\"$(DEFAULT_LOADER)\"" \
|
||||||
|
+ $(EFI_INCLUDES) $(ARCH_CFLAGS)
|
||||||
|
+
|
||||||
|
+ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
|
||||||
|
+ CFLAGS += -DOVERRIDE_SECURITY_POLICY
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+ifneq ($(origin ENABLE_HTTPBOOT), undefined)
|
||||||
|
+ CFLAGS += -DENABLE_HTTPBOOT
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+ifneq ($(origin REQUIRE_TPM), undefined)
|
||||||
|
+ CFLAGS += -DREQUIRE_TPM
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+LIB_GCC = $(shell $(CC) $(ARCH_CFLAGS) -print-libgcc-file-name)
|
||||||
|
+EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC)
|
||||||
|
FORMAT ?= --target efi-app-$(ARCH)
|
||||||
|
EFI_PATH ?= $(LIBDIR)/gnuefi
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From 74718677945b1ab825130b317c63f5002876e772 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
|
||||||
|
Date: Thu, 5 Jul 2018 11:28:12 -0400
|
||||||
|
Subject: [PATCH 03/62] Let MokManager follow a MokTimeout var for timeout
|
||||||
|
length for the prompt
|
||||||
|
|
||||||
|
This timeout can have the values [-1,0..0x7fff]; where -1 means "no timeout",
|
||||||
|
with MokManager going directly to the menu, and is capped to 0x7fff to avoid
|
||||||
|
unecessary long timeouts. The default remains 10, which will be used whenever
|
||||||
|
the MokTimeout variable isn't set.
|
||||||
|
|
||||||
|
Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
|
||||||
|
Upstream-commit-id: 93708c11083
|
||||||
|
---
|
||||||
|
MokManager.c | 23 ++++++++++++++++++++++-
|
||||||
|
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index 7e40a38f1d1..0767e4a6cde 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -40,6 +40,10 @@ typedef struct {
|
||||||
|
CHAR16 Password[SB_PASSWORD_LEN];
|
||||||
|
} __attribute__ ((packed)) MokDBvar;
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ INT32 Timeout;
|
||||||
|
+} __attribute__ ((packed)) MokTimeoutvar;
|
||||||
|
+
|
||||||
|
static EFI_STATUS get_sha1sum(void *Data, int DataSize, UINT8 * hash)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
@@ -2041,7 +2045,24 @@ static int draw_countdown()
|
||||||
|
UINTN cols, rows;
|
||||||
|
CHAR16 *title[2];
|
||||||
|
CHAR16 *message = L"Press any key to perform MOK management";
|
||||||
|
- int timeout = 10, wait = 10000000;
|
||||||
|
+ void *MokTimeout = NULL;
|
||||||
|
+ MokTimeoutvar *var;
|
||||||
|
+ UINTN MokTimeoutSize = 0;
|
||||||
|
+ int timeout, wait = 10000000;
|
||||||
|
+
|
||||||
|
+ efi_status = get_variable(L"MokTimeout", (UINT8 **) &MokTimeout,
|
||||||
|
+ &MokTimeoutSize, SHIM_LOCK_GUID);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ timeout = 10;
|
||||||
|
+ } else {
|
||||||
|
+ var = MokTimeout;
|
||||||
|
+ timeout = (int)var->Timeout;
|
||||||
|
+ FreePool(MokTimeout);
|
||||||
|
+ LibDeleteVariable(L"MokTimeout", &SHIM_LOCK_GUID);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (timeout < 0)
|
||||||
|
+ return timeout;
|
||||||
|
|
||||||
|
console_save_and_set_mode(&SavedMode);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From 8a66f5571bb059d2692e804f4ba9817e978dd103 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Mon, 28 May 2018 16:05:38 +0800
|
||||||
|
Subject: [PATCH 04/62] httpboot: return EFI_NOT_FOUND when it fails to find
|
||||||
|
the NIC handle
|
||||||
|
|
||||||
|
httpboot_fetch_buffer() should return EFI_NOT_FOUND to reflect the error
|
||||||
|
status when get_nic_handle() returns NULL.
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 2be5c7dc4b0
|
||||||
|
---
|
||||||
|
httpboot.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/httpboot.c b/httpboot.c
|
||||||
|
index 4cfa3aab3b7..d656073c633 100644
|
||||||
|
--- a/httpboot.c
|
||||||
|
+++ b/httpboot.c
|
||||||
|
@@ -715,6 +715,7 @@ httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size)
|
||||||
|
also supports the HTTP service binding protocol */
|
||||||
|
nic = get_nic_handle(&mac_addr);
|
||||||
|
if (!nic) {
|
||||||
|
+ efi_status = EFI_NOT_FOUND;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
From 0ba6c87bdf55f749a0ec1c3b0fd24ebb8200d537 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Mon, 28 May 2018 17:24:30 +0800
|
||||||
|
Subject: [PATCH 05/62] httpboot: print more messages when it fails to set IP
|
||||||
|
|
||||||
|
We previously only print the return status and it may not be clear
|
||||||
|
enough in some situations. Print the IP address and the gateway to help
|
||||||
|
the user to identify the possible errors.
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 3abe94516c7
|
||||||
|
---
|
||||||
|
httpboot.c | 45 +++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 41 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/httpboot.c b/httpboot.c
|
||||||
|
index d656073c633..6f27b01bf71 100644
|
||||||
|
--- a/httpboot.c
|
||||||
|
+++ b/httpboot.c
|
||||||
|
@@ -311,6 +311,20 @@ is_unspecified_addr (EFI_IPv6_ADDRESS ip6)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline void
|
||||||
|
+print_ip6_addr(EFI_IPv6_ADDRESS ip6addr)
|
||||||
|
+{
|
||||||
|
+ perror(L"%x:%x:%x:%x:%x:%x:%x:%x\n",
|
||||||
|
+ ip6addr.Addr[0] << 8 | ip6addr.Addr[1],
|
||||||
|
+ ip6addr.Addr[2] << 8 | ip6addr.Addr[3],
|
||||||
|
+ ip6addr.Addr[4] << 8 | ip6addr.Addr[5],
|
||||||
|
+ ip6addr.Addr[6] << 8 | ip6addr.Addr[7],
|
||||||
|
+ ip6addr.Addr[8] << 8 | ip6addr.Addr[9],
|
||||||
|
+ ip6addr.Addr[10] << 8 | ip6addr.Addr[11],
|
||||||
|
+ ip6addr.Addr[12] << 8 | ip6addr.Addr[13],
|
||||||
|
+ ip6addr.Addr[14] << 8 | ip6addr.Addr[15]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static EFI_STATUS
|
||||||
|
set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
||||||
|
{
|
||||||
|
@@ -329,8 +343,12 @@ set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
||||||
|
ip6.IsAnycast = FALSE;
|
||||||
|
efi_status = ip6cfg->SetData(ip6cfg, Ip6ConfigDataTypeManualAddress,
|
||||||
|
sizeof(ip6), &ip6);
|
||||||
|
- if (EFI_ERROR(efi_status))
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to set IPv6 Address:\nIP: ");
|
||||||
|
+ print_ip6_addr(ip6.Address);
|
||||||
|
+ perror(L"Prefix Length: %u\n", ip6.PrefixLength);
|
||||||
|
return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
gateway = ip6node->GatewayIpAddress;
|
||||||
|
if (is_unspecified_addr(gateway))
|
||||||
|
@@ -338,12 +356,23 @@ set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
||||||
|
|
||||||
|
efi_status = ip6cfg->SetData(ip6cfg, Ip6ConfigDataTypeGateway,
|
||||||
|
sizeof(gateway), &gateway);
|
||||||
|
- if (EFI_ERROR(efi_status))
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to set IPv6 Gateway:\nIP: ");
|
||||||
|
+ print_ip6_addr(gateway);
|
||||||
|
return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline void
|
||||||
|
+print_ip4_addr(EFI_IPv4_ADDRESS ip4addr)
|
||||||
|
+{
|
||||||
|
+ perror(L"%u.%u.%u.%u\n",
|
||||||
|
+ ip4addr.Addr[0], ip4addr.Addr[1],
|
||||||
|
+ ip4addr.Addr[2], ip4addr.Addr[3]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static EFI_STATUS
|
||||||
|
set_ip4(EFI_HANDLE *nic, IPv4_DEVICE_PATH *ip4node)
|
||||||
|
{
|
||||||
|
@@ -361,14 +390,22 @@ set_ip4(EFI_HANDLE *nic, IPv4_DEVICE_PATH *ip4node)
|
||||||
|
ip4.SubnetMask = ip4node->SubnetMask;
|
||||||
|
efi_status = ip4cfg2->SetData(ip4cfg2, Ip4Config2DataTypeManualAddress,
|
||||||
|
sizeof(ip4), &ip4);
|
||||||
|
- if (EFI_ERROR(efi_status))
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to Set IPv4 Address:\nIP: ");
|
||||||
|
+ print_ip4_addr(ip4.Address);
|
||||||
|
+ perror(L"Mask: ");
|
||||||
|
+ print_ip4_addr(ip4.SubnetMask);
|
||||||
|
return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
gateway = ip4node->GatewayIpAddress;
|
||||||
|
efi_status = ip4cfg2->SetData(ip4cfg2, Ip4Config2DataTypeGateway,
|
||||||
|
sizeof(gateway), &gateway);
|
||||||
|
- if (EFI_ERROR(efi_status))
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to Set IPv4 Gateway:\nGateway: ");
|
||||||
|
+ print_ip4_addr(gateway);
|
||||||
|
return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From 80e52895f206fcb40a60f031e7b721627bb193ca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Mon, 28 May 2018 17:42:56 +0800
|
||||||
|
Subject: [PATCH 06/62] httpboot: allow the IPv4 gateway to be empty
|
||||||
|
|
||||||
|
The gateway is not mandatory.
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 69089e9c678
|
||||||
|
---
|
||||||
|
httpboot.c | 20 ++++++++++++++++++--
|
||||||
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/httpboot.c b/httpboot.c
|
||||||
|
index 6f27b01bf71..16dd6621f66 100644
|
||||||
|
--- a/httpboot.c
|
||||||
|
+++ b/httpboot.c
|
||||||
|
@@ -299,7 +299,7 @@ out:
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN
|
||||||
|
-is_unspecified_addr (EFI_IPv6_ADDRESS ip6)
|
||||||
|
+is_unspecified_ip6addr (EFI_IPv6_ADDRESS ip6)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
@@ -351,7 +351,7 @@ set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
||||||
|
}
|
||||||
|
|
||||||
|
gateway = ip6node->GatewayIpAddress;
|
||||||
|
- if (is_unspecified_addr(gateway))
|
||||||
|
+ if (is_unspecified_ip6addr(gateway))
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
efi_status = ip6cfg->SetData(ip6cfg, Ip6ConfigDataTypeGateway,
|
||||||
|
@@ -365,6 +365,19 @@ set_ip6(EFI_HANDLE *nic, IPv6_DEVICE_PATH *ip6node)
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static BOOLEAN
|
||||||
|
+is_unspecified_ip4addr (EFI_IPv4_ADDRESS ip4)
|
||||||
|
+{
|
||||||
|
+ UINT8 i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i<4; i++) {
|
||||||
|
+ if (ip4.Addr[i] != 0)
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static inline void
|
||||||
|
print_ip4_addr(EFI_IPv4_ADDRESS ip4addr)
|
||||||
|
{
|
||||||
|
@@ -399,6 +412,9 @@ set_ip4(EFI_HANDLE *nic, IPv4_DEVICE_PATH *ip4node)
|
||||||
|
}
|
||||||
|
|
||||||
|
gateway = ip4node->GatewayIpAddress;
|
||||||
|
+ if (is_unspecified_ip4addr(gateway))
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+
|
||||||
|
efi_status = ip4cfg2->SetData(ip4cfg2, Ip4Config2DataTypeGateway,
|
||||||
|
sizeof(gateway), &gateway);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From c2f645c7cd9872585e7b4522b01c368bb545258b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Mon, 28 May 2018 18:03:39 +0800
|
||||||
|
Subject: [PATCH 07/62] httpboot: show the error message for the ChildHandle
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 0fd3c7e8518
|
||||||
|
---
|
||||||
|
httpboot.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/httpboot.c b/httpboot.c
|
||||||
|
index 16dd6621f66..3622e85867c 100644
|
||||||
|
--- a/httpboot.c
|
||||||
|
+++ b/httpboot.c
|
||||||
|
@@ -696,8 +696,10 @@ http_fetch (EFI_HANDLE image, EFI_HANDLE device,
|
||||||
|
/* Set the handle to NULL to request a new handle */
|
||||||
|
http_handle = NULL;
|
||||||
|
efi_status = service->CreateChild(service, &http_handle);
|
||||||
|
- if (EFI_ERROR(efi_status))
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to create the ChildHandle\n");
|
||||||
|
return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Get the http protocol */
|
||||||
|
efi_status = gBS->HandleProtocol(http_handle, &EFI_HTTP_PROTOCOL_GUID,
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
54
SOURCES/0008-Fix-typo-in-debug-path-in-shim.h.patch
Normal file
54
SOURCES/0008-Fix-typo-in-debug-path-in-shim.h.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 409b59af29b8749207a527c91dccba7eee98232b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Wed, 23 May 2018 15:15:56 +0800
|
||||||
|
Subject: [PATCH 08/62] Fix typo in debug path in shim.h
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: a98c20bbdbb
|
||||||
|
---
|
||||||
|
shim.h | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index a25a660df6a..2b359d821e3 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -43,7 +43,7 @@
|
||||||
|
#define EFI_ARCH L"x64"
|
||||||
|
#endif
|
||||||
|
#ifndef DEBUGDIR
|
||||||
|
-#define DEBUGDIR L"/usr/lub/debug/usr/share/shim/x64/"
|
||||||
|
+#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/x64/"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@
|
||||||
|
#define EFI_ARCH L"ia32"
|
||||||
|
#endif
|
||||||
|
#ifndef DEBUGDIR
|
||||||
|
-#define DEBUGDIR L"/usr/lub/debug/usr/share/shim/ia32/"
|
||||||
|
+#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/ia32/"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -73,7 +73,7 @@
|
||||||
|
#define EFI_ARCH L"aa64"
|
||||||
|
#endif
|
||||||
|
#ifndef DEBUGDIR
|
||||||
|
-#define DEBUGDIR L"/usr/lub/debug/usr/share/shim/aa64/"
|
||||||
|
+#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/aa64/"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -88,7 +88,7 @@
|
||||||
|
#define EFI_ARCH L"arm"
|
||||||
|
#endif
|
||||||
|
#ifndef DEBUGDIR
|
||||||
|
-#define DEBUGDIR L"/usr/lub/debug/usr/share/shim/arm/"
|
||||||
|
+#define DEBUGDIR L"/usr/lib/debug/usr/share/shim/arm/"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From 85c837d67fef9cd831a3126398ed8da1421f61c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Fri, 11 May 2018 16:59:03 +0800
|
||||||
|
Subject: [PATCH 09/62] MokManager: Stop using EFI_VARIABLE_APPEND_WRITE
|
||||||
|
|
||||||
|
When writing MokList with EFI_VARIABLE_APPEND_WRITE, some HP laptops
|
||||||
|
may just return EFI_SUCCESS without writing the content into the flash,
|
||||||
|
so we have no way to detect if MokList is updated or not. Now we always
|
||||||
|
read MokList first and write it back with the new content.
|
||||||
|
|
||||||
|
https://github.com/rhboot/shim/issues/105
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: f442c8424b4
|
||||||
|
---
|
||||||
|
MokManager.c | 11 +++--------
|
||||||
|
1 file changed, 3 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index 0767e4a6cde..df9b6fe6912 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -880,14 +880,9 @@ static EFI_STATUS write_db(CHAR16 * db_name, void *MokNew, UINTN MokNewSize)
|
||||||
|
UINTN old_size;
|
||||||
|
UINTN new_size;
|
||||||
|
|
||||||
|
- efi_status = gRT->SetVariable(db_name, &SHIM_LOCK_GUID,
|
||||||
|
- EFI_VARIABLE_NON_VOLATILE |
|
||||||
|
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
- EFI_VARIABLE_APPEND_WRITE,
|
||||||
|
- MokNewSize, MokNew);
|
||||||
|
- if (!EFI_ERROR(efi_status) || efi_status != EFI_INVALID_PARAMETER) {
|
||||||
|
- return efi_status;
|
||||||
|
- }
|
||||||
|
+ /* Do not use EFI_VARIABLE_APPEND_WRITE due to faulty firmwares.
|
||||||
|
+ * ref: https://github.com/rhboot/shim/issues/55
|
||||||
|
+ * https://github.com/rhboot/shim/issues/105 */
|
||||||
|
|
||||||
|
efi_status = get_variable_attr(db_name, (UINT8 **)&old_data, &old_size,
|
||||||
|
SHIM_LOCK_GUID, &attributes);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 956717e2b375d7c7f0faafec8f12a7692708eb9a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Menzel <pmenzel@molgen.mpg.de>
|
||||||
|
Date: Wed, 23 May 2018 12:32:37 +0200
|
||||||
|
Subject: [PATCH 10/62] shim: Extend invalid reloc size warning message
|
||||||
|
|
||||||
|
Knowing the value of the reloc directory size is helpful for debugging,
|
||||||
|
cf. issue #131 [1],
|
||||||
|
|
||||||
|
[1]: https://github.com/rhboot/shim/issues/131
|
||||||
|
|
||||||
|
Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
|
||||||
|
Upstream-commit-id: dd3230d07f3
|
||||||
|
---
|
||||||
|
shim.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index ff0817009cd..05fc65005d1 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -280,8 +280,14 @@ static EFI_STATUS relocate_coff (PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
||||||
|
while (RelocBase < RelocBaseEnd) {
|
||||||
|
Reloc = (UINT16 *) ((char *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
|
||||||
|
|
||||||
|
- if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > context->RelocDir->Size)) {
|
||||||
|
- perror(L"Reloc %d block size %d is invalid\n", n, RelocBase->SizeOfBlock);
|
||||||
|
+ if (RelocBase->SizeOfBlock == 0) {
|
||||||
|
+ perror(L"Reloc %d block size 0 is invalid\n", n);
|
||||||
|
+ return EFI_UNSUPPORTED;
|
||||||
|
+ } else if (RelocBase->SizeOfBlock > context->RelocDir->Size) {
|
||||||
|
+ perror(L"Reloc %d block size %d greater than reloc dir"
|
||||||
|
+ "size %d, which is invalid\n", n,
|
||||||
|
+ RelocBase->SizeOfBlock,
|
||||||
|
+ context->RelocDir->Size);
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
34
SOURCES/0011-Add-GRUB-s-PCR-Usage-to-README.tpm.patch
Normal file
34
SOURCES/0011-Add-GRUB-s-PCR-Usage-to-README.tpm.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From bd97e72f0490b2be766949f448bf6ea3ec2bba1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Wed, 1 Aug 2018 09:58:09 -0500
|
||||||
|
Subject: [PATCH 11/62] Add GRUB's PCR Usage to README.tpm
|
||||||
|
|
||||||
|
This didn't seem to get documented anywhere, and this is as good a place as any.
|
||||||
|
Upstream-commit-id: 4fab7281a8c
|
||||||
|
---
|
||||||
|
README.tpm | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/README.tpm b/README.tpm
|
||||||
|
index b7314f12d57..d9c7c53483b 100644
|
||||||
|
--- a/README.tpm
|
||||||
|
+++ b/README.tpm
|
||||||
|
@@ -19,6 +19,15 @@ PCR7:
|
||||||
|
- MokSBState will be extended into PCR7 if it is set, logged as
|
||||||
|
"MokSBState".
|
||||||
|
|
||||||
|
+PCR8:
|
||||||
|
+- If you're using the grub2 TPM patchset we cary in Fedora, the kernel command
|
||||||
|
+ line and all grub commands (including all of grub.cfg that gets run) are
|
||||||
|
+ measured into PCR8.
|
||||||
|
+
|
||||||
|
+PCR9:
|
||||||
|
+- If you're using the grub2 TPM patchset we cary in Fedora, the kernel,
|
||||||
|
+ initramfs, and any multiboot modules loaded are measured into PCR9.
|
||||||
|
+
|
||||||
|
PCR14:
|
||||||
|
- MokList, MokListX, and MokSBState will be extended into PCR14 if they are
|
||||||
|
set.
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From c4e3516e303daa42b3381ddd889a90641717f720 Mon Sep 17 00:00:00 2001
|
||||||
|
From: TanMing <tanminger@TanMing-WorkPC.sh.intel.com>
|
||||||
|
Date: Tue, 21 Aug 2018 02:25:52 -0400
|
||||||
|
Subject: [PATCH 12/62] Fix the compile error of mkdir wrong directory.
|
||||||
|
|
||||||
|
In Ubuntu 14.04, the following code in old Makefile:
|
||||||
|
mkdir -p Cryptlib/{Hash,Hmac,Cipher,Rand,Pk,Pem,SysCall}
|
||||||
|
will create a directory named "{Hash,Hmac,Cipher,Rand,Pk,Pem,SysCall}".
|
||||||
|
|
||||||
|
Signed-off-by: Ming Tan <ming.tan@intel.com>
|
||||||
|
Upstream-commit-id: 39b83455d68
|
||||||
|
---
|
||||||
|
Makefile | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 115e7f08c0f..3f2105595a6 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -102,11 +102,11 @@ $(MMSONAME): $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a li
|
||||||
|
$(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a
|
||||||
|
|
||||||
|
Cryptlib/libcryptlib.a:
|
||||||
|
- mkdir -p Cryptlib/{Hash,Hmac,Cipher,Rand,Pk,Pem,SysCall}
|
||||||
|
+ for i in Hash Hmac Cipher Rand Pk Pem SysCall; do mkdir -p Cryptlib/$$i; done
|
||||||
|
$(MAKE) VPATH=$(TOPDIR)/Cryptlib TOPDIR=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile
|
||||||
|
|
||||||
|
Cryptlib/OpenSSL/libopenssl.a:
|
||||||
|
- mkdir -p Cryptlib/OpenSSL/crypto/{x509v3,x509,txt_db,stack,sha,rsa,rc4,rand,pkcs7,pkcs12,pem,ocsp,objects,modes,md5,lhash,kdf,hmac,evp,err,dso,dh,conf,comp,cmac,buffer,bn,bio,async{,/arch},asn1,aes}/
|
||||||
|
+ for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done
|
||||||
|
$(MAKE) VPATH=$(TOPDIR)/Cryptlib/OpenSSL TOPDIR=$(TOPDIR)/Cryptlib/OpenSSL -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile
|
||||||
|
|
||||||
|
lib/lib.a: | $(TOPDIR)/lib/Makefile $(wildcard $(TOPDIR)/include/*.[ch])
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
From 79be2af5260b1f2e2a4680e74e14da0fdb42b570 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Fri, 7 Sep 2018 14:11:02 +0200
|
||||||
|
Subject: [PATCH 13/62] shim: Properly generate absolute paths from relative
|
||||||
|
image paths
|
||||||
|
|
||||||
|
The generate_path_from_image_path() doesn't properly handle the case when
|
||||||
|
shim is invoked using a relative path (e.g: from the EFI shell). In that
|
||||||
|
function, always the last component is stripped from absolute file path
|
||||||
|
to calculate the dirname, and this is concatenated with the image path.
|
||||||
|
|
||||||
|
But if the path is a relative one, the function will wrongly concatenate
|
||||||
|
the dirname with the relative image path, i.e:
|
||||||
|
|
||||||
|
Shell> FS0:
|
||||||
|
FS0:\> cd EFI
|
||||||
|
FS0:\EFI\> BOOT\BOOTX64.EFI
|
||||||
|
Failed to open \EFI\BOOT\BOOT\BOOTX64.EFI - Not found
|
||||||
|
Failed to load image \EFI\BOOT\BOOT\BOOTX64.EFI: Not found
|
||||||
|
start_image() returned Not found
|
||||||
|
|
||||||
|
Calculate the image path basename and concatenate that with the dirname.
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Reviewed-by: Maran Wilson maran.wilson@oracle.com
|
||||||
|
Tested-by: Maran Wilson maran.wilson@oracle.com
|
||||||
|
Upstream-commit-id: a625fa5096c
|
||||||
|
---
|
||||||
|
shim.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 05fc65005d1..5ab23d03db4 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -1610,9 +1610,11 @@ static EFI_STATUS generate_path_from_image_path(EFI_LOADED_IMAGE *li,
|
||||||
|
bootpath[j] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
- while (*ImagePath == '\\')
|
||||||
|
- ImagePath++;
|
||||||
|
+ for (i = 0, last = 0; i < StrLen(ImagePath); i++)
|
||||||
|
+ if (ImagePath[i] == '\\')
|
||||||
|
+ last = i + 1;
|
||||||
|
|
||||||
|
+ ImagePath = ImagePath + last;
|
||||||
|
*PathName = AllocatePool(StrSize(bootpath) + StrSize(ImagePath));
|
||||||
|
|
||||||
|
if (!*PathName) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
From 818a0dbd247f7c83d844febfa0a037b396d22701 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Fri, 7 Sep 2018 15:10:51 +0200
|
||||||
|
Subject: [PATCH 14/62] shim: Prevent shim to set itself as a second stage
|
||||||
|
loader
|
||||||
|
|
||||||
|
When shim is invoked from a relative path (e.g: from the UEFI shell), the
|
||||||
|
Loaded Image handle LoadOptions can be set to the binary relative path.
|
||||||
|
|
||||||
|
But the is_our_path() function only checks if LoadOptions is set to the
|
||||||
|
absolute path of shim to ignore it. So if a relative path is there, shim
|
||||||
|
would set itself as the secondary loader and invoke itself in a loop.
|
||||||
|
|
||||||
|
To prevent that, use the path in LoadOptions to calculate the absolute
|
||||||
|
path and compare it with the one in the Loader Image handle FilePath.
|
||||||
|
|
||||||
|
Resolves: bz#1622485
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Reviewed-by: Maran Wilson maran.wilson@oracle.com
|
||||||
|
Tested-by: Maran Wilson maran.wilson@oracle.com
|
||||||
|
Upstream-commit-id: e563bc3dcd1
|
||||||
|
---
|
||||||
|
shim.c | 17 ++++++++++++++---
|
||||||
|
1 file changed, 14 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 5ab23d03db4..ae03da7eddf 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2086,21 +2086,32 @@ get_load_option_optional_data(UINT8 *data, UINTN data_size,
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int is_our_path(EFI_LOADED_IMAGE *li, CHAR16 *path, UINTN len)
|
||||||
|
+static int is_our_path(EFI_LOADED_IMAGE *li, CHAR16 *path)
|
||||||
|
{
|
||||||
|
CHAR16 *dppath = NULL;
|
||||||
|
+ CHAR16 *PathName = NULL;
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
dppath = DevicePathToStr(li->FilePath);
|
||||||
|
if (!dppath)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ efi_status = generate_path_from_image_path(li, path, &PathName);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Unable to generate path %s: %r\n", path,
|
||||||
|
+ efi_status);
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
dprint(L"dppath: %s\n", dppath);
|
||||||
|
dprint(L"path: %s\n", path);
|
||||||
|
- if (StrnCaseCmp(dppath, path, len))
|
||||||
|
+ if (StrnCaseCmp(dppath, PathName, strlen(dppath)))
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
+done:
|
||||||
|
FreePool(dppath);
|
||||||
|
+ FreePool(PathName);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2289,7 +2300,7 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
|
||||||
|
|
||||||
|
* which is just cruel... So yeah, just don't use it.
|
||||||
|
*/
|
||||||
|
- if (strings == 1 && is_our_path(li, start, loader_len))
|
||||||
|
+ if (strings == 1 && is_our_path(li, start))
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,121 @@
|
|||||||
|
From 3d04aef8d80293d701f7efee6b5300f9f528ddfc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Maran Wilson <maran.wilson@oracle.com>
|
||||||
|
Date: Tue, 7 Aug 2018 15:32:29 -0700
|
||||||
|
Subject: [PATCH 15/62] Fix for "Section 0 has negative size" error when
|
||||||
|
loading fbaa64.efi
|
||||||
|
|
||||||
|
The current code is incorrectly failing to load the fbaa64.efi image found
|
||||||
|
in Arm servers even though the UEFI shell code is able to properly load
|
||||||
|
and execute the same image.
|
||||||
|
|
||||||
|
The problem is due to the presence of a section header that has zero size
|
||||||
|
and address and marked "discardable" in the fbaa64.efi image.
|
||||||
|
|
||||||
|
Although there is already a check further down in the code to look for
|
||||||
|
the discardable bit and skip further verification checks if set, we never
|
||||||
|
get to that point due to the "end < base" check at the start of the loop.
|
||||||
|
|
||||||
|
Here is a dump of the fbaa64.efi image as compiled on an Arm machine
|
||||||
|
from the latest code in this repo:
|
||||||
|
|
||||||
|
% # First I used hexedit to change header byte from 'AA' to '86'
|
||||||
|
% # so that objdump was able to correctly parse the file:
|
||||||
|
% objdump -x -m aarch64 fbaa64.efi
|
||||||
|
|
||||||
|
fbaa64.efi: file format pei-x86-64
|
||||||
|
fbaa64.efi
|
||||||
|
architecture: i386:x86-64, flags 0x00000103:
|
||||||
|
HAS_RELOC, EXEC_P, D_PAGED
|
||||||
|
start address 0x0000000000000148
|
||||||
|
|
||||||
|
Characteristics 0x20e
|
||||||
|
executable
|
||||||
|
line numbers stripped
|
||||||
|
symbols stripped
|
||||||
|
debugging information removed
|
||||||
|
|
||||||
|
Time/Date Wed Dec 31 16:00:00 1969
|
||||||
|
Magic 020b (PE32+)
|
||||||
|
MajorLinkerVersion 2
|
||||||
|
MinorLinkerVersion 20
|
||||||
|
SizeOfCode 000b15d0
|
||||||
|
SizeOfInitializedData 00000000
|
||||||
|
SizeOfUninitializedData 00000000
|
||||||
|
AddressOfEntryPoint 0000000000000148
|
||||||
|
BaseOfCode 0000000000000148
|
||||||
|
ImageBase 0000000000000000
|
||||||
|
SectionAlignment 0000000000000020
|
||||||
|
FileAlignment 0000000000000008
|
||||||
|
MajorOSystemVersion 0
|
||||||
|
MinorOSystemVersion 0
|
||||||
|
MajorImageVersion 0
|
||||||
|
MinorImageVersion 0
|
||||||
|
MajorSubsystemVersion 0
|
||||||
|
MinorSubsystemVersion 0
|
||||||
|
Win32Version 00000000
|
||||||
|
SizeOfImage 000b1718
|
||||||
|
SizeOfHeaders 00000148
|
||||||
|
CheckSum 00000000
|
||||||
|
Subsystem 0000000a (EFI application)
|
||||||
|
DllCharacteristics 00000000
|
||||||
|
SizeOfStackReserve 0000000000000000
|
||||||
|
SizeOfStackCommit 0000000000000000
|
||||||
|
SizeOfHeapReserve 0000000000000000
|
||||||
|
SizeOfHeapCommit 0000000000000000
|
||||||
|
LoaderFlags 00000000
|
||||||
|
NumberOfRvaAndSizes 00000006
|
||||||
|
|
||||||
|
The Data Directory
|
||||||
|
Entry 0 0000000000000000 00000000 Export Directory [.edata (or where ever we found it)]
|
||||||
|
Entry 1 0000000000000000 00000000 Import Directory [parts of .idata]
|
||||||
|
Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
|
||||||
|
Entry 3 0000000000000000 00000000 Exception Directory [.pdata]
|
||||||
|
Entry 4 0000000000000000 00000000 Security Directory
|
||||||
|
Entry 5 0000000000000000 00000000 Base Relocation Directory [.reloc]
|
||||||
|
Entry 6 0000000000000000 00000000 Debug Directory
|
||||||
|
Entry 7 0000000000000000 00000000 Description Directory
|
||||||
|
Entry 8 0000000000000000 00000000 Special Directory
|
||||||
|
Entry 9 0000000000000000 00000000 Thread Storage Directory [.tls]
|
||||||
|
Entry a 0000000000000000 00000000 Load Configuration Directory
|
||||||
|
Entry b 0000000000000000 00000000 Bound Import Directory
|
||||||
|
Entry c 0000000000000000 00000000 Import Address Table Directory
|
||||||
|
Entry d 0000000000000000 00000000 Delay Import Directory
|
||||||
|
Entry e 0000000000000000 00000000 CLR Runtime Header
|
||||||
|
Entry f 0000000000000000 00000000 Reserved
|
||||||
|
|
||||||
|
Sections:
|
||||||
|
Idx Name Size VMA LMA File off Algn
|
||||||
|
0 .reloc 00000000 0000000000000000 0000000000000000 00000000 2**0
|
||||||
|
ALLOC, LOAD, READONLY, DATA
|
||||||
|
1 .text 000b15d0 0000000000000148 0000000000000148 00000148 2**4
|
||||||
|
CONTENTS, ALLOC, LOAD, CODE
|
||||||
|
SYMBOL TABLE:
|
||||||
|
no symbols
|
||||||
|
|
||||||
|
Signed-off-by: Maran Wilson <maran.wilson@oracle.com>
|
||||||
|
Reviewed-by: Aaron Young <aaron.young@oracle.com>
|
||||||
|
Reviewed-by: Jack Schwartz <jack.schwartz@oracle.com>
|
||||||
|
Upstream-commit-id: 6df7a8f5609
|
||||||
|
---
|
||||||
|
shim.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index ae03da7eddf..d980cadacfc 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -1347,6 +1347,11 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
|
||||||
|
*/
|
||||||
|
Section = context.FirstSection;
|
||||||
|
for (i = 0; i < context.NumberOfSections; i++, Section++) {
|
||||||
|
+ /* Don't try to copy discardable sections with zero size */
|
||||||
|
+ if ((Section->Characteristics & EFI_IMAGE_SCN_MEM_DISCARDABLE) &&
|
||||||
|
+ !Section->Misc.VirtualSize)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
base = ImageAddress (buffer, context.ImageSize,
|
||||||
|
Section->VirtualAddress);
|
||||||
|
end = ImageAddress (buffer, context.ImageSize,
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
30
SOURCES/0016-Fix-apparent-typo-in-ARM-32-on-64-code.patch
Normal file
30
SOURCES/0016-Fix-apparent-typo-in-ARM-32-on-64-code.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From d5b72b322d5b7c6c115833c518e1aa5798076309 Mon Sep 17 00:00:00 2001
|
||||||
|
From: dann frazier <dann.frazier@canonical.com>
|
||||||
|
Date: Mon, 14 Jan 2019 15:25:11 -0700
|
||||||
|
Subject: [PATCH 16/62] Fix apparent typo in ARM 32-on-64 code
|
||||||
|
|
||||||
|
The architecture is aarch64, not arch64.
|
||||||
|
|
||||||
|
Fixes: 750584c20775 ("Make 64-on-32 maybe work on x86_64.")
|
||||||
|
Signed-off-by: dann frazier <dann.frazier@canonical.com>
|
||||||
|
Upstream-commit-id: e9f67aaa75a
|
||||||
|
---
|
||||||
|
shim.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index d980cadacfc..e4d4fea226d 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -150,7 +150,7 @@ allow_32_bit(void)
|
||||||
|
#endif
|
||||||
|
#elif defined(__i386__) || defined(__i686__)
|
||||||
|
return 1;
|
||||||
|
-#elif defined(__arch64__)
|
||||||
|
+#elif defined(__aarch64__)
|
||||||
|
return 0;
|
||||||
|
#else /* assuming everything else is 32-bit... */
|
||||||
|
return 1;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 8544018093b8aa4311b1e970f8396140c22ede0b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luca Boccassi <bluca@debian.org>
|
||||||
|
Date: Mon, 14 Jan 2019 19:29:34 +0000
|
||||||
|
Subject: [PATCH 17/62] Makefile: do not run git on clean if there's no .git
|
||||||
|
directory
|
||||||
|
|
||||||
|
When building in minimal chroot on build workers, like in Debian (where
|
||||||
|
make clean is called at the beginning of the build process), git will
|
||||||
|
not be available. Skip the git clean.
|
||||||
|
|
||||||
|
Signed-off-by: Luca Boccassi <bluca@debian.org>
|
||||||
|
Upstream-commit-id: be352762a01
|
||||||
|
---
|
||||||
|
Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 3f2105595a6..fd7e83dc764 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -225,7 +225,7 @@ clean-shim-objs:
|
||||||
|
@rm -rvf $(TARGET) *.o $(SHIM_OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb $(BOOTCSVNAME)
|
||||||
|
@rm -vf *.debug *.so *.efi *.efi.* *.tar.* version.c buildid
|
||||||
|
@rm -vf Cryptlib/*.[oa] Cryptlib/*/*.[oa]
|
||||||
|
- @git clean -f -d -e 'Cryptlib/OpenSSL/*'
|
||||||
|
+ @if [ -d .git ] ; then git clean -f -d -e 'Cryptlib/OpenSSL/*'; fi
|
||||||
|
|
||||||
|
clean: clean-shim-objs
|
||||||
|
$(MAKE) -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile clean
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 7f080b30f3c3718d6b2533f62a50f373fd2cda21 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Korsgaard <peter@korsgaard.com>
|
||||||
|
Date: Thu, 10 Jan 2019 23:34:11 +0100
|
||||||
|
Subject: [PATCH 18/62] Make.default: use correct flags to disable unaligned
|
||||||
|
access for 32 bit ARM
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The GCC flag to disable unaligned access on 32bit ARM is
|
||||||
|
-mno-unaligned-access, not -mstrict-align (which is used on aarch64):
|
||||||
|
|
||||||
|
https://lkml.org/lkml/2018/8/3/294
|
||||||
|
|
||||||
|
Otherwise build dies with:
|
||||||
|
arm-linux-gnueabihf-gcc: error: unrecognized command line option
|
||||||
|
‘-mstrict-align’; did you mean ‘-Wstrict-aliasing’?
|
||||||
|
|
||||||
|
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
||||||
|
Upstream-commit-id: 41b93358e8c
|
||||||
|
---
|
||||||
|
Make.defaults | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Make.defaults b/Make.defaults
|
||||||
|
index bbfc1d7f77b..09807bd8108 100644
|
||||||
|
--- a/Make.defaults
|
||||||
|
+++ b/Make.defaults
|
||||||
|
@@ -72,7 +72,7 @@ ifeq ($(ARCH),aarch64)
|
||||||
|
ARCH_CFLAGS ?=
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),arm)
|
||||||
|
- ARCH_CFLAGS ?= -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
+ ARCH_CFLAGS ?= -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mno-unaligned-access
|
||||||
|
LIBDIR ?= $(prefix)/lib
|
||||||
|
ARCH_SUFFIX ?= arm
|
||||||
|
ARCH_SUFFIX_UPPER ?= ARM
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
34
SOURCES/0019-Cryptlib-fix-build-on-32bit-ARM.patch
Normal file
34
SOURCES/0019-Cryptlib-fix-build-on-32bit-ARM.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From ee832f21c6706d6b3890d82f9d8bcb2bd249ee04 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Korsgaard <peter@korsgaard.com>
|
||||||
|
Date: Fri, 11 Jan 2019 09:17:42 +0100
|
||||||
|
Subject: [PATCH 19/62] Cryptlib: fix build on 32bit ARM
|
||||||
|
|
||||||
|
Pass MDE_CPU_ARM, similar to how it is done for the other supported
|
||||||
|
architectures, otherwise the build fails in:
|
||||||
|
|
||||||
|
Cryptlib/Include/OpenSslSupport.h:55:2: error:
|
||||||
|
#error Unknown target architecture
|
||||||
|
|
||||||
|
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
|
||||||
|
Upstream-commit-id: cb83c14628b
|
||||||
|
---
|
||||||
|
Cryptlib/Makefile | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile
|
||||||
|
index 2aa569594a0..5c098f34cec 100644
|
||||||
|
--- a/Cryptlib/Makefile
|
||||||
|
+++ b/Cryptlib/Makefile
|
||||||
|
@@ -19,6 +19,9 @@ endif
|
||||||
|
ifeq ($(ARCH),aarch64)
|
||||||
|
CFLAGS += -DMDE_CPU_AARCH64
|
||||||
|
endif
|
||||||
|
+ifeq ($(ARCH),arm)
|
||||||
|
+ CFLAGS += -DMDE_CPU_ARM
|
||||||
|
+endif
|
||||||
|
LDFLAGS = -nostdlib -znocombreloc
|
||||||
|
|
||||||
|
TARGET = libcryptlib.a
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 9ab0d796bdc9cefdaa3b0df7434845d26c43d894 Mon Sep 17 00:00:00 2001
|
From ac0400b20264ef67b67891d2216edd3fe20e5571 Mon Sep 17 00:00:00 2001
|
||||||
From: Patrick Uiterwijk <patrick@puiterwijk.org>
|
From: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||||
Date: Mon, 5 Nov 2018 14:51:16 +0100
|
Date: Mon, 5 Nov 2018 14:51:16 +0100
|
||||||
Subject: [PATCH 1/3] Make sure that MOK variables always get mirrored
|
Subject: [PATCH 20/62] Make sure that MOK variables always get mirrored
|
||||||
|
|
||||||
Without this, if a Mok variable doesn't exist in Boot Services, it will also
|
Without this, if a Mok variable doesn't exist in Boot Services, it will also
|
||||||
not be copied to Runtime, even if we have data to be added to it (vendor cert).
|
not be copied to Runtime, even if we have data to be added to it (vendor cert).
|
||||||
@ -9,6 +9,7 @@ This patch makes sure that if we have extra data to append, we still mirror
|
|||||||
the variable.
|
the variable.
|
||||||
|
|
||||||
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
|
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||||
|
Upstream-commit-id: 9ab0d796bdc
|
||||||
---
|
---
|
||||||
mok.c | 20 ++++++++++++++++----
|
mok.c | 20 ++++++++++++++++----
|
||||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||||
@ -56,5 +57,5 @@ index 38675211e0e..00dd1ad3034 100644
|
|||||||
if (v->flags & MOK_VARIABLE_MEASURE && present) {
|
if (v->flags & MOK_VARIABLE_MEASURE && present) {
|
||||||
/*
|
/*
|
||||||
--
|
--
|
||||||
2.20.1
|
2.26.2
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
From 4b27ae034ba9885960e72f77b3f687a9b7fea824 Mon Sep 17 00:00:00 2001
|
From f748139695384fb4e09833898f0b8cb3ab85d810 Mon Sep 17 00:00:00 2001
|
||||||
From: Gary Lin <glin@suse.com>
|
From: Gary Lin <glin@suse.com>
|
||||||
Date: Wed, 21 Nov 2018 12:47:43 +0800
|
Date: Wed, 21 Nov 2018 12:47:43 +0800
|
||||||
Subject: [PATCH 2/3] mok: fix the mirroring of RT variables
|
Subject: [PATCH 21/62] mok: fix the mirroring of RT variables
|
||||||
|
|
||||||
When there is no key in MokList, import_mok_state() just skipped MokList
|
When there is no key in MokList, import_mok_state() just skipped MokList
|
||||||
even though it should always mirror the vendor cert. Besides, the faulty
|
even though it should always mirror the vendor cert. Besides, the faulty
|
||||||
@ -11,6 +11,7 @@ MokSBStateRT, and MokIgnoreDB.
|
|||||||
https://github.com/rhboot/shim/issues/154
|
https://github.com/rhboot/shim/issues/154
|
||||||
|
|
||||||
Signed-off-by: Gary Lin <glin@suse.com>
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 4b27ae034ba
|
||||||
---
|
---
|
||||||
mok.c | 11 ++++-------
|
mok.c | 11 ++++-------
|
||||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||||
@ -45,5 +46,5 @@ index 00dd1ad3034..41925abbb49 100644
|
|||||||
LibDeleteVariable(v->rtname, v->guid);
|
LibDeleteVariable(v->rtname, v->guid);
|
||||||
|
|
||||||
--
|
--
|
||||||
2.20.1
|
2.26.2
|
||||||
|
|
@ -1,20 +1,21 @@
|
|||||||
From 29c11483101b460869a5e0dba1f425073862127d Mon Sep 17 00:00:00 2001
|
From ff6e5cda136c8fd637d3d6b8334f4f221ba2b1ee Mon Sep 17 00:00:00 2001
|
||||||
From: Peter Jones <pjones@redhat.com>
|
From: Peter Jones <pjones@redhat.com>
|
||||||
Date: Thu, 31 Jan 2019 13:45:30 -0500
|
Date: Thu, 31 Jan 2019 13:45:30 -0500
|
||||||
Subject: [PATCH 3/3] mok: consolidate mirroring code in a helper instead of
|
Subject: [PATCH 22/62] mok: consolidate mirroring code in a helper instead of
|
||||||
using goto
|
using goto
|
||||||
|
|
||||||
There's no reason to complicate the logic with a goto here, instead just
|
There's no reason to complicate the logic with a goto here, instead just
|
||||||
pull the logic we're jumping to out to a helper function.
|
pull the logic we're jumping to out to a helper function.
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 29c11483101
|
||||||
---
|
---
|
||||||
mok.c | 41 ++++++++++++++++++++++++++++-------------
|
mok.c | 42 +++++++++++++++++++++++++++++-------------
|
||||||
shim.h | 2 ++
|
shim.h | 2 ++
|
||||||
2 files changed, 30 insertions(+), 13 deletions(-)
|
2 files changed, 31 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
diff --git a/mok.c b/mok.c
|
diff --git a/mok.c b/mok.c
|
||||||
index 41925abbb49..2f495e6cf25 100644
|
index 41925abbb49..2b9d796a0e8 100644
|
||||||
--- a/mok.c
|
--- a/mok.c
|
||||||
+++ b/mok.c
|
+++ b/mok.c
|
||||||
@@ -130,7 +130,8 @@ struct mok_state_variable mok_state_variables[] = {
|
@@ -130,7 +130,8 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
@ -105,5 +106,5 @@ index 2b359d821e3..c26d5f06538 100644
|
|||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
--
|
--
|
||||||
2.20.1
|
2.26.2
|
||||||
|
|
82
SOURCES/0023-shim-only-include-shim_cert.h-in-shim.c.patch
Normal file
82
SOURCES/0023-shim-only-include-shim_cert.h-in-shim.c.patch
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
From 7a3638173e406ce7cbd682213606e3152244fcb2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Wed, 19 Dec 2018 11:27:42 +0800
|
||||||
|
Subject: [PATCH 23/62] shim: only include shim_cert.h in shim.c
|
||||||
|
|
||||||
|
The shim_cert array was declared as a static array, and every user of
|
||||||
|
shim_cert.h would create a shim_cert array for its own and grow the file
|
||||||
|
size. To remove the unnecessary duplicate shim_cert arrays, this commit
|
||||||
|
declares shim_cert in shim.c while other users still can access the
|
||||||
|
array through the external variables: build_cert and build_cert_size.
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: 4e2d62f0f4e
|
||||||
|
---
|
||||||
|
shim.c | 11 +++++++++++
|
||||||
|
shim.h | 7 ++++---
|
||||||
|
2 files changed, 15 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index e4d4fea226d..0a95f94b360 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -34,6 +34,9 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shim.h"
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+#include "shim_cert.h"
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/bn.h>
|
||||||
|
@@ -75,6 +78,10 @@ UINT32 vendor_cert_size;
|
||||||
|
UINT32 vendor_dbx_size;
|
||||||
|
UINT8 *vendor_cert;
|
||||||
|
UINT8 *vendor_dbx;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+UINT32 build_cert_size;
|
||||||
|
+UINT8 *build_cert;
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* indicator of how an image has been verified
|
||||||
|
@@ -2562,6 +2569,10 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
vendor_dbx_size = cert_table.vendor_dbx_size;
|
||||||
|
vendor_cert = (UINT8 *)&cert_table + cert_table.vendor_cert_offset;
|
||||||
|
vendor_dbx = (UINT8 *)&cert_table + cert_table.vendor_dbx_offset;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ build_cert_size = sizeof(shim_cert);
|
||||||
|
+ build_cert = shim_cert;
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
CHAR16 *msgs[] = {
|
||||||
|
L"import_mok_state() failed\n",
|
||||||
|
L"shim_int() failed\n",
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index c26d5f06538..e4d40505f09 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -122,9 +122,6 @@
|
||||||
|
#include "include/variables.h"
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
-#ifdef ENABLE_SHIM_CERT
|
||||||
|
-#include "shim_cert.h"
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
INTERFACE_DECL(_SHIM_LOCK);
|
||||||
|
|
||||||
|
@@ -172,6 +169,10 @@ extern UINT32 vendor_cert_size;
|
||||||
|
extern UINT32 vendor_dbx_size;
|
||||||
|
extern UINT8 *vendor_cert;
|
||||||
|
extern UINT8 *vendor_dbx;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+extern UINT32 build_cert_size;
|
||||||
|
+extern UINT8 *build_cert;
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
|
||||||
|
extern UINT8 user_insecure_mode;
|
||||||
|
extern UINT8 ignore_db;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
153
SOURCES/0024-mok-also-mirror-the-build-cert-to-MokListRT.patch
Normal file
153
SOURCES/0024-mok-also-mirror-the-build-cert-to-MokListRT.patch
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
From 3d62232feb296b238ca5d7963ba40a2c346767e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Wed, 19 Dec 2018 12:40:02 +0800
|
||||||
|
Subject: [PATCH 24/62] mok: also mirror the build cert to MokListRT
|
||||||
|
|
||||||
|
If the build cert is enabled, we should also mirror it to MokListRT.
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: aecbe1f99b6
|
||||||
|
---
|
||||||
|
mok.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 72 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index 2b9d796a0e8..6150d8c8868 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -68,6 +68,10 @@ struct mok_state_variable {
|
||||||
|
*/
|
||||||
|
UINT8 **addend_source;
|
||||||
|
UINT32 *addend_size;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ UINT8 **build_cert;
|
||||||
|
+ UINT32 *build_cert_size;
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
UINT32 yes_attr;
|
||||||
|
UINT32 no_attr;
|
||||||
|
UINT32 flags;
|
||||||
|
@@ -90,6 +94,10 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
.no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
.addend_source = &vendor_cert,
|
||||||
|
.addend_size = &vendor_cert_size,
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ .build_cert = &build_cert,
|
||||||
|
+ .build_cert_size = &build_cert_size,
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
.flags = MOK_MIRROR_KEYDB |
|
||||||
|
MOK_VARIABLE_LOG,
|
||||||
|
.pcr = 14,
|
||||||
|
@@ -130,6 +138,22 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
{ NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
+inline BOOLEAN check_vendor_cert(struct mok_state_variable *v)
|
||||||
|
+{
|
||||||
|
+ return (v->addend_source && v->addend_size &&
|
||||||
|
+ *v->addend_source && *v->addend_size) ? TRUE : FALSE;
|
||||||
|
+}
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+inline BOOLEAN check_build_cert(struct mok_state_variable *v)
|
||||||
|
+{
|
||||||
|
+ return (v->build_cert && v->build_cert_size &&
|
||||||
|
+ *v->build_cert && *v->build_cert_size) ? TRUE : FALSE;
|
||||||
|
+}
|
||||||
|
+#define check_addend(v) (check_vendor_cert(v) || check_build_cert(v))
|
||||||
|
+#else
|
||||||
|
+#define check_addend(v) check_vendor_cert(v)
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
static EFI_STATUS nonnull(1)
|
||||||
|
mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
{
|
||||||
|
@@ -138,15 +162,27 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
UINTN FullDataSize = 0;
|
||||||
|
uint8_t *p = NULL;
|
||||||
|
|
||||||
|
- if ((v->flags & MOK_MIRROR_KEYDB) &&
|
||||||
|
- v->addend_source && *v->addend_source &&
|
||||||
|
- v->addend_size && *v->addend_size) {
|
||||||
|
+ if ((v->flags & MOK_MIRROR_KEYDB) && check_addend(v)) {
|
||||||
|
EFI_SIGNATURE_LIST *CertList = NULL;
|
||||||
|
EFI_SIGNATURE_DATA *CertData = NULL;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ FullDataSize = v->data_size;
|
||||||
|
+ if (check_build_cert(v)) {
|
||||||
|
+ FullDataSize += sizeof (*CertList)
|
||||||
|
+ + sizeof (EFI_GUID)
|
||||||
|
+ + *v->build_cert_size;
|
||||||
|
+ }
|
||||||
|
+ if (check_vendor_cert(v)) {
|
||||||
|
+ FullDataSize += sizeof (*CertList)
|
||||||
|
+ + sizeof (EFI_GUID)
|
||||||
|
+ + *v->addend_size;
|
||||||
|
+ }
|
||||||
|
+#else
|
||||||
|
FullDataSize = v->data_size
|
||||||
|
+ sizeof (*CertList)
|
||||||
|
+ sizeof (EFI_GUID)
|
||||||
|
+ *v->addend_size;
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
FullData = AllocatePool(FullDataSize);
|
||||||
|
if (!FullData) {
|
||||||
|
perror(L"Failed to allocate space for MokListRT\n");
|
||||||
|
@@ -158,6 +194,35 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
CopyMem(p, v->data, v->data_size);
|
||||||
|
p += v->data_size;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ if (check_build_cert(v) == FALSE)
|
||||||
|
+ goto skip_build_cert;
|
||||||
|
+
|
||||||
|
+ CertList = (EFI_SIGNATURE_LIST *)p;
|
||||||
|
+ p += sizeof (*CertList);
|
||||||
|
+ CertData = (EFI_SIGNATURE_DATA *)p;
|
||||||
|
+ p += sizeof (EFI_GUID);
|
||||||
|
+
|
||||||
|
+ CertList->SignatureType = EFI_CERT_TYPE_X509_GUID;
|
||||||
|
+ CertList->SignatureListSize = *v->build_cert_size
|
||||||
|
+ + sizeof (*CertList)
|
||||||
|
+ + sizeof (*CertData)
|
||||||
|
+ -1;
|
||||||
|
+ CertList->SignatureHeaderSize = 0;
|
||||||
|
+ CertList->SignatureSize = *v->build_cert_size +
|
||||||
|
+ sizeof (EFI_GUID);
|
||||||
|
+
|
||||||
|
+ CertData->SignatureOwner = SHIM_LOCK_GUID;
|
||||||
|
+ CopyMem(p, *v->build_cert, *v->build_cert_size);
|
||||||
|
+
|
||||||
|
+ p += *v->build_cert_size;
|
||||||
|
+
|
||||||
|
+ if (check_vendor_cert(v) == FALSE)
|
||||||
|
+ goto skip_vendor_cert;
|
||||||
|
+skip_build_cert:
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
CertList = (EFI_SIGNATURE_LIST *)p;
|
||||||
|
p += sizeof (*CertList);
|
||||||
|
CertData = (EFI_SIGNATURE_DATA *)p;
|
||||||
|
@@ -174,6 +239,9 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
CertData->SignatureOwner = SHIM_LOCK_GUID;
|
||||||
|
CopyMem(p, *v->addend_source, *v->addend_size);
|
||||||
|
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+skip_vendor_cert:
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
if (v->data && v->data_size)
|
||||||
|
FreePool(v->data);
|
||||||
|
v->data = FullData;
|
||||||
|
@@ -247,9 +315,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
UINT32 attrs = 0;
|
||||||
|
BOOLEAN delete = FALSE, present, addend;
|
||||||
|
|
||||||
|
- addend = (v->addend_source && v->addend_size &&
|
||||||
|
- *v->addend_source && *v->addend_size)
|
||||||
|
- ? TRUE : FALSE;
|
||||||
|
+ addend = check_addend(v);
|
||||||
|
|
||||||
|
efi_status = get_variable_attr(v->name,
|
||||||
|
&v->data, &v->data_size,
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
37
SOURCES/0025-mok-minor-cleanups.patch
Normal file
37
SOURCES/0025-mok-minor-cleanups.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
From ff890cf45224926574eee93b0ea1494468870bd3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 31 Jan 2019 14:04:57 -0500
|
||||||
|
Subject: [PATCH 25/62] mok: minor cleanups
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 617b9007668
|
||||||
|
---
|
||||||
|
mok.c | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index 6150d8c8868..59630e74425 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -138,13 +138,16 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
{ NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
-inline BOOLEAN check_vendor_cert(struct mok_state_variable *v)
|
||||||
|
+static inline BOOLEAN nonnull(1)
|
||||||
|
+check_vendor_cert(struct mok_state_variable *v)
|
||||||
|
{
|
||||||
|
return (v->addend_source && v->addend_size &&
|
||||||
|
*v->addend_source && *v->addend_size) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
-inline BOOLEAN check_build_cert(struct mok_state_variable *v)
|
||||||
|
+static inline BOOLEAN nonnull(1)
|
||||||
|
+check_build_cert(struct mok_state_variable *v)
|
||||||
|
{
|
||||||
|
return (v->build_cert && v->build_cert_size &&
|
||||||
|
*v->build_cert && *v->build_cert_size) ? TRUE : FALSE;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
91
SOURCES/0026-Remove-call-to-TPM2-get_event_log.patch
Normal file
91
SOURCES/0026-Remove-call-to-TPM2-get_event_log.patch
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
From cf3f99c3b1e11c8c83938784975331db5efb410f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Matthew Garrett <mjg59@google.com>
|
||||||
|
Date: Tue, 11 Dec 2018 15:25:44 -0800
|
||||||
|
Subject: [PATCH 26/62] Remove call to TPM2 get_event_log()
|
||||||
|
|
||||||
|
Calling the TPM2 get_event_log causes the firmware to start logging
|
||||||
|
events to the final events table, but implementations may also continue
|
||||||
|
logging to the boot services event log. Any OS that wishes to
|
||||||
|
reconstruct the full PCR state must already look at both the final
|
||||||
|
events log and the boot services event log, so if this call is made
|
||||||
|
anywhere other than immediately before ExitBootServices() then the OS
|
||||||
|
must deduplicate events that occur in both, complicating things
|
||||||
|
immensely.
|
||||||
|
|
||||||
|
Linux already has support for copying up the boot services event log
|
||||||
|
across the ExitBootServices() boundary, so there's no reason to make
|
||||||
|
this call. Remove it.
|
||||||
|
|
||||||
|
Signed-off-by: Matthew Garrett <mjg59@google.com>
|
||||||
|
Upstream-commit-id: fd7c3bd920b
|
||||||
|
---
|
||||||
|
tpm.c | 46 ----------------------------------------------
|
||||||
|
1 file changed, 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index 674e69b715f..f07362c70bb 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -70,41 +70,6 @@ static BOOLEAN tpm2_present(EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps,
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline EFI_TCG2_EVENT_LOG_BITMAP
|
||||||
|
-tpm2_get_supported_logs(efi_tpm2_protocol_t *tpm,
|
||||||
|
- EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps,
|
||||||
|
- BOOLEAN old_caps)
|
||||||
|
-{
|
||||||
|
- if (old_caps)
|
||||||
|
- return ((TREE_BOOT_SERVICE_CAPABILITY *)caps)->SupportedEventLogs;
|
||||||
|
-
|
||||||
|
- return caps->SupportedEventLogs;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * According to TCG EFI Protocol Specification for TPM 2.0 family,
|
||||||
|
- * all events generated after the invocation of EFI_TCG2_GET_EVENT_LOG
|
||||||
|
- * shall be stored in an instance of an EFI_CONFIGURATION_TABLE aka
|
||||||
|
- * EFI TCG 2.0 final events table. Hence, it is necessary to trigger the
|
||||||
|
- * internal switch through calling get_event_log() in order to allow
|
||||||
|
- * to retrieve the logs from OS runtime.
|
||||||
|
- */
|
||||||
|
-static EFI_STATUS trigger_tcg2_final_events_table(efi_tpm2_protocol_t *tpm2,
|
||||||
|
- EFI_TCG2_EVENT_LOG_BITMAP supported_logs)
|
||||||
|
-{
|
||||||
|
- EFI_TCG2_EVENT_LOG_FORMAT log_fmt;
|
||||||
|
- EFI_PHYSICAL_ADDRESS start;
|
||||||
|
- EFI_PHYSICAL_ADDRESS end;
|
||||||
|
- BOOLEAN truncated;
|
||||||
|
-
|
||||||
|
- if (supported_logs & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
|
||||||
|
- log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
|
||||||
|
- else
|
||||||
|
- log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
|
||||||
|
-
|
||||||
|
- return tpm2->get_event_log(tpm2, log_fmt, &start, &end, &truncated);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static EFI_STATUS tpm_locate_protocol(efi_tpm_protocol_t **tpm,
|
||||||
|
efi_tpm2_protocol_t **tpm2,
|
||||||
|
BOOLEAN *old_caps_p,
|
||||||
|
@@ -166,17 +131,6 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
#endif
|
||||||
|
} else if (tpm2) {
|
||||||
|
EFI_TCG2_EVENT *event;
|
||||||
|
- EFI_TCG2_EVENT_LOG_BITMAP supported_logs;
|
||||||
|
-
|
||||||
|
- supported_logs = tpm2_get_supported_logs(tpm2, &caps, old_caps);
|
||||||
|
-
|
||||||
|
- efi_status = trigger_tcg2_final_events_table(tpm2,
|
||||||
|
- supported_logs);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Unable to trigger tcg2 final events table: %r\n",
|
||||||
|
- efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
- }
|
||||||
|
|
||||||
|
event = AllocatePool(sizeof(*event) + logsize);
|
||||||
|
if (!event) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 95bd1d88003a9a7c2732472b061ad2a9c7140419 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||||
|
Date: Thu, 6 Dec 2018 10:08:45 +0100
|
||||||
|
Subject: [PATCH 27/62] Make EFI variable copying fatal only on secureboot
|
||||||
|
enabled systems
|
||||||
|
|
||||||
|
I have come across systems that are unwilling to reserve enough memory for
|
||||||
|
a MokListRT big enough for big certificates.
|
||||||
|
This seems to be the case with firmware implementations that do not support
|
||||||
|
secureboot, which is probably the reason they went with much lower variable
|
||||||
|
storage.
|
||||||
|
|
||||||
|
This patch set makes sure we can still boot on those systems, by only
|
||||||
|
making the copy action fatal if the system has secure boot enabled, or if
|
||||||
|
the error was anything other than EFI_INVALID_PARAMETER.
|
||||||
|
|
||||||
|
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||||
|
Upstream-commit-id: 741c61abba7
|
||||||
|
---
|
||||||
|
shim.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 0a95f94b360..d4ed332f901 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2609,7 +2609,17 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
* boot-services-only state variables are what we think they are.
|
||||||
|
*/
|
||||||
|
efi_status = import_mok_state(image_handle);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
+ if (!secure_mode() && efi_status == EFI_INVALID_PARAMETER) {
|
||||||
|
+ /*
|
||||||
|
+ * Make copy failures fatal only if secure_mode is enabled, or
|
||||||
|
+ * the error was anything else than EFI_INVALID_PARAMETER.
|
||||||
|
+ * There are non-secureboot firmware implementations that don't
|
||||||
|
+ * reserve enough EFI variable memory to fit the variable.
|
||||||
|
+ */
|
||||||
|
+ console_print(L"Importing MOK states has failed: %s: %r\n",
|
||||||
|
+ msgs[msg], efi_status);
|
||||||
|
+ console_print(L"Continuing boot since secure mode is disabled");
|
||||||
|
+ } else if (EFI_ERROR(efi_status)) {
|
||||||
|
die:
|
||||||
|
console_print(L"Something has gone seriously wrong: %s: %r\n",
|
||||||
|
msgs[msg], efi_status);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -1,9 +1,25 @@
|
|||||||
From 0bff94b170116737e6e0838c35c0ac376542a5c0 Mon Sep 17 00:00:00 2001
|
From 344a8364cb05cdaafc43231d0f73d5217c4e118c Mon Sep 17 00:00:00 2001
|
||||||
From: Peter Jones <pjones@redhat.com>
|
From: Peter Jones <pjones@redhat.com>
|
||||||
Date: Tue, 12 Feb 2019 18:04:49 -0500
|
Date: Tue, 12 Feb 2019 18:04:49 -0500
|
||||||
Subject: [PATCH 4/4] Make VLogError() behave as expected.
|
Subject: [PATCH 28/62] VLogError(): Avoid NULL pointer dereferences in
|
||||||
|
(V)Sprint calls
|
||||||
|
|
||||||
|
VLogError() calculates the size of format strings by using calls to
|
||||||
|
SPrint and VSPrint with a StrSize of 0 and NULL for an output buffer.
|
||||||
|
Unfortunately, this is an incorrect usage of (V)Sprint. A StrSize
|
||||||
|
of "0" is special-cased to mean "there is no limit". So, we end up
|
||||||
|
writing our string to address 0x0. This was discovered because it
|
||||||
|
causes a crash on ARM where, unlike x86, it does not necessarily
|
||||||
|
have memory mapped at 0x0.
|
||||||
|
|
||||||
|
Avoid the (V)Sprint calls altogether by using (V)PoolPrint, which
|
||||||
|
handles the size calculation and allocation for us.
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Fixes: 25f6fd08cd26 ("try to show errors more usefully.")
|
||||||
|
[dannf: commit message ]
|
||||||
|
Signed-off-by: dann frazier <dann.frazier@canonical.com>
|
||||||
|
Upstream-commit-id: 20e731f423a
|
||||||
---
|
---
|
||||||
errlog.c | 15 +++------------
|
errlog.c | 15 +++------------
|
||||||
1 file changed, 3 insertions(+), 12 deletions(-)
|
1 file changed, 3 insertions(+), 12 deletions(-)
|
||||||
@ -46,5 +62,5 @@ index 18be4822d53..eebb266d396 100644
|
|||||||
|
|
||||||
nerrs += 2;
|
nerrs += 2;
|
||||||
--
|
--
|
||||||
2.20.1
|
2.26.2
|
||||||
|
|
@ -0,0 +1,98 @@
|
|||||||
|
From 10d6e3d90f1ea504a1dedaea50478c444e92951c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Fri, 15 Mar 2019 09:52:02 -0400
|
||||||
|
Subject: [PATCH 29/62] Once again, try even harder to get binaries without
|
||||||
|
timestamps in them.
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
$ objdump -x /builddir/build/BUILDROOT/shim-*/usr/share/shim/*/shimx64.efi | grep 'Time/Date'
|
||||||
|
Time/Date Thu Jan 1 00:00:08 1970
|
||||||
|
$ _
|
||||||
|
|
||||||
|
"What is despair? I have known it—hear my song. Despair is when you’re
|
||||||
|
debugging a kernel driver and you look at a memory dump and you see that
|
||||||
|
a pointer has a value of 7."
|
||||||
|
- http://scholar.harvard.edu/files/mickens/files/thenightwatch.pdf
|
||||||
|
|
||||||
|
objcopy only knows about -D for some targets.
|
||||||
|
ld only believes in --no-insert-timestamp in some versions.
|
||||||
|
dd takes off and nukes the site from orbit.
|
||||||
|
|
||||||
|
It's the only way to be sure.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: a4a1fbe728c
|
||||||
|
---
|
||||||
|
Make.defaults | 4 ++++
|
||||||
|
Makefile | 6 ++++--
|
||||||
|
2 files changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Make.defaults b/Make.defaults
|
||||||
|
index 09807bd8108..f0bfa9fd573 100644
|
||||||
|
--- a/Make.defaults
|
||||||
|
+++ b/Make.defaults
|
||||||
|
@@ -50,6 +50,7 @@ ifeq ($(ARCH),x86_64)
|
||||||
|
ARCH_SUFFIX ?= x64
|
||||||
|
ARCH_SUFFIX_UPPER ?= X64
|
||||||
|
ARCH_LDFLAGS ?=
|
||||||
|
+ TIMESTAMP_LOCATION := 136
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),ia32)
|
||||||
|
ARCH_CFLAGS ?= -mno-mmx -mno-sse -mno-red-zone -nostdinc \
|
||||||
|
@@ -60,6 +61,7 @@ ifeq ($(ARCH),ia32)
|
||||||
|
ARCH_SUFFIX_UPPER ?= IA32
|
||||||
|
ARCH_LDFLAGS ?=
|
||||||
|
ARCH_CFLAGS ?= -m32
|
||||||
|
+ TIMESTAMP_LOCATION := 136
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),aarch64)
|
||||||
|
ARCH_CFLAGS ?= -DMDE_CPU_AARCH64 -DPAGE_SIZE=4096 -mstrict-align
|
||||||
|
@@ -70,6 +72,7 @@ ifeq ($(ARCH),aarch64)
|
||||||
|
SUBSYSTEM := 0xa
|
||||||
|
ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
|
||||||
|
ARCH_CFLAGS ?=
|
||||||
|
+ TIMESTAMP_LOCATION := 72
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),arm)
|
||||||
|
ARCH_CFLAGS ?= -DMDE_CPU_ARM -DPAGE_SIZE=4096 -mno-unaligned-access
|
||||||
|
@@ -79,6 +82,7 @@ ifeq ($(ARCH),arm)
|
||||||
|
FORMAT := -O binary
|
||||||
|
SUBSYSTEM := 0xa
|
||||||
|
ARCH_LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
|
||||||
|
+ TIMESTAMP_LOCATION := 72
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index fd7e83dc764..49e14a26521 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -189,11 +189,13 @@ endif
|
||||||
|
ifneq ($(OBJCOPY_GTE224),1)
|
||||||
|
$(error objcopy >= 2.24 is required)
|
||||||
|
endif
|
||||||
|
- $(OBJCOPY) -j .text -j .sdata -j .data -j .data.ident \
|
||||||
|
+ $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \
|
||||||
|
-j .dynamic -j .dynsym -j .rel* \
|
||||||
|
-j .rela* -j .reloc -j .eh_frame \
|
||||||
|
-j .vendor_cert \
|
||||||
|
$(FORMAT) $^ $@
|
||||||
|
+ # I am tired of wasting my time fighting binutils timestamp code.
|
||||||
|
+ dd conv=notrunc bs=1 count=4 seek=$(TIMESTAMP_LOCATION) if=/dev/zero of=$@
|
||||||
|
|
||||||
|
ifneq ($(origin ENABLE_SHIM_HASH),undefined)
|
||||||
|
%.hash : %.efi
|
||||||
|
@@ -204,7 +206,7 @@ endif
|
||||||
|
ifneq ($(OBJCOPY_GTE224),1)
|
||||||
|
$(error objcopy >= 2.24 is required)
|
||||||
|
endif
|
||||||
|
- $(OBJCOPY) -j .text -j .sdata -j .data \
|
||||||
|
+ $(OBJCOPY) -D -j .text -j .sdata -j .data \
|
||||||
|
-j .dynamic -j .dynsym -j .rel* \
|
||||||
|
-j .rela* -j .reloc -j .eh_frame \
|
||||||
|
-j .debug_info -j .debug_abbrev -j .debug_aranges \
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,280 @@
|
|||||||
|
From 1b382ef850de5a6c59b192c146a0e8d898d2d961 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Tue, 23 Oct 2018 18:17:57 -0400
|
||||||
|
Subject: [PATCH 30/62] shim: Rework pause functions and add read_counter()
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: fc6b0bca84e
|
||||||
|
---
|
||||||
|
shim.c | 4 +-
|
||||||
|
include/asm.h | 59 +++++++++++++++++
|
||||||
|
include/compiler.h | 156 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
shim.h | 1 +
|
||||||
|
4 files changed, 217 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 include/asm.h
|
||||||
|
create mode 100644 include/compiler.h
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index d4ed332f901..f69e69487fc 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2543,16 +2543,14 @@ debug_hook(void)
|
||||||
|
#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
|
||||||
|
if (x > 4294967294ULL)
|
||||||
|
break;
|
||||||
|
- __asm__ __volatile__("pause");
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
if (x > 1000)
|
||||||
|
break;
|
||||||
|
- __asm__ __volatile__("wfi");
|
||||||
|
#else
|
||||||
|
if (x > 12000)
|
||||||
|
break;
|
||||||
|
- msleep(5000);
|
||||||
|
#endif
|
||||||
|
+ pause();
|
||||||
|
}
|
||||||
|
x = 1;
|
||||||
|
}
|
||||||
|
diff --git a/include/asm.h b/include/asm.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..5e8f9ed9d7c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/asm.h
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * asm.h
|
||||||
|
+ * Copyright 2018 Peter Jones <pjones@redhat.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef SHIM_ASM_H_
|
||||||
|
+#define SHIM_ASM_H_
|
||||||
|
+
|
||||||
|
+#define __stringify_1(x...) #x
|
||||||
|
+#define __stringify(x...) __stringify_1(x)
|
||||||
|
+
|
||||||
|
+static inline uint64_t read_counter(void)
|
||||||
|
+{
|
||||||
|
+ uint64_t val;
|
||||||
|
+#if defined (__x86_64__)
|
||||||
|
+ unsigned long low, high;
|
||||||
|
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
|
||||||
|
+ val = (low) | (high) << 32;
|
||||||
|
+#elif defined(__i386__) || defined(__i686__)
|
||||||
|
+ __asm__ __volatile__("rdtsc" : "=A" (val));
|
||||||
|
+#elif defined(__aarch64__)
|
||||||
|
+ __asm__ __volatile__ ("mrs %0, pmccntr_el0" : "=r" (val));
|
||||||
|
+#elif defined(__arm__)
|
||||||
|
+ __asm__ __volatile__ ("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
|
||||||
|
+#else
|
||||||
|
+#error unsupported arch
|
||||||
|
+#endif
|
||||||
|
+ return val;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
|
||||||
|
+static inline void pause(void)
|
||||||
|
+{
|
||||||
|
+ __asm__ __volatile__("pause");
|
||||||
|
+}
|
||||||
|
+#elif defined(__aarch64__)
|
||||||
|
+static inline void pause(void)
|
||||||
|
+{
|
||||||
|
+ __asm__ __volatile__("wfi");
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static inline void pause(void)
|
||||||
|
+{
|
||||||
|
+ uint64_t a, b;
|
||||||
|
+ int x;
|
||||||
|
+ extern void msleep(unsigned long msecs);
|
||||||
|
+
|
||||||
|
+ a = read_counter();
|
||||||
|
+ for (x = 0; x < 1000; x++) {
|
||||||
|
+ msleep(1000);
|
||||||
|
+ b = read_counter();
|
||||||
|
+ if (a != b)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* !SHIM_ASM_H_ */
|
||||||
|
+// vim:fenc=utf-8:tw=75:et
|
||||||
|
diff --git a/include/compiler.h b/include/compiler.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..a2a0859379f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/compiler.h
|
||||||
|
@@ -0,0 +1,156 @@
|
||||||
|
+/*
|
||||||
|
+ * compiler.h
|
||||||
|
+ * Copyright 2019 Peter Jones <pjones@redhat.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef COMPILER_H_
|
||||||
|
+#define COMPILER_H_
|
||||||
|
+
|
||||||
|
+#ifndef UNUSED
|
||||||
|
+#define UNUSED __attribute__((__unused__))
|
||||||
|
+#endif
|
||||||
|
+#ifndef HIDDEN
|
||||||
|
+#define HIDDEN __attribute__((__visibility__ ("hidden")))
|
||||||
|
+#endif
|
||||||
|
+#ifndef PUBLIC
|
||||||
|
+#define PUBLIC __attribute__((__visibility__ ("default")))
|
||||||
|
+#endif
|
||||||
|
+#ifndef DESTRUCTOR
|
||||||
|
+#define DESTRUCTOR __attribute__((destructor))
|
||||||
|
+#endif
|
||||||
|
+#ifndef CONSTRUCTOR
|
||||||
|
+#define CONSTRUCTOR __attribute__((constructor))
|
||||||
|
+#endif
|
||||||
|
+#ifndef ALIAS
|
||||||
|
+#define ALIAS(x) __attribute__((weak, alias (#x)))
|
||||||
|
+#endif
|
||||||
|
+#ifndef NONNULL
|
||||||
|
+#endif
|
||||||
|
+#define NONNULL(first, args...) __attribute__((__nonnull__(first, ## args)))
|
||||||
|
+#ifndef PRINTF
|
||||||
|
+#define PRINTF(first, args...) __attribute__((__format__(printf, first, ## args)))
|
||||||
|
+#endif
|
||||||
|
+#ifndef FLATTEN
|
||||||
|
+#define FLATTEN __attribute__((__flatten__))
|
||||||
|
+#endif
|
||||||
|
+#ifndef PACKED
|
||||||
|
+#define PACKED __attribute__((__packed__))
|
||||||
|
+#endif
|
||||||
|
+#ifndef VERSION
|
||||||
|
+#define VERSION(sym, ver) __asm__(".symver " # sym "," # ver)
|
||||||
|
+#endif
|
||||||
|
+#ifndef NORETURN
|
||||||
|
+#define NORETURN __attribute__((__noreturn__))
|
||||||
|
+#endif
|
||||||
|
+#ifndef ALIGNED
|
||||||
|
+#define ALIGNED(n) __attribute__((__aligned__(n)))
|
||||||
|
+#endif
|
||||||
|
+#ifndef CLEANUP_FUNC
|
||||||
|
+#define CLEANUP_FUNC(x) __attribute__((__cleanup__(x)))
|
||||||
|
+#endif
|
||||||
|
+#ifndef USED
|
||||||
|
+#define USED __attribute__((__used__))
|
||||||
|
+#endif
|
||||||
|
+#ifndef SECTION
|
||||||
|
+#define SECTION(x) __attribute__((__section__(x)))
|
||||||
|
+#endif
|
||||||
|
+#ifndef OPTIMIZE
|
||||||
|
+#define OPTIMIZE(x) __attribute__((__optimize__(x)))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef __CONCAT
|
||||||
|
+#define __CONCAT3(a, b, c) a ## b ## c
|
||||||
|
+#endif
|
||||||
|
+#ifndef CAT
|
||||||
|
+#define CAT(a, b) __CONCAT(a, b)
|
||||||
|
+#endif
|
||||||
|
+#ifndef CAT3
|
||||||
|
+#define CAT3(a, b, c) __CONCAT3(a, b, c)
|
||||||
|
+#endif
|
||||||
|
+#ifndef STRING
|
||||||
|
+#define STRING(x) __STRING(x)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef WRITE_ONCE
|
||||||
|
+#define WRITE_ONCE(var, val) \
|
||||||
|
+ (*((volatile typeof(val) *)(&(var))) = (val))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef READ_ONCE
|
||||||
|
+#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef likely
|
||||||
|
+#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef unlikely
|
||||||
|
+#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Are two types/vars the same type (ignoring qualifiers)? */
|
||||||
|
+#ifndef __same_type
|
||||||
|
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Compile time object size, -1 for unknown */
|
||||||
|
+#ifndef __compiletime_object_size
|
||||||
|
+# define __compiletime_object_size(obj) -1
|
||||||
|
+#endif
|
||||||
|
+#ifndef __compiletime_warning
|
||||||
|
+# define __compiletime_warning(message)
|
||||||
|
+#endif
|
||||||
|
+#ifndef __compiletime_error
|
||||||
|
+# define __compiletime_error(message)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef __compiletime_assert
|
||||||
|
+#define __compiletime_assert(condition, msg, prefix, suffix) \
|
||||||
|
+ do { \
|
||||||
|
+ extern void prefix ## suffix(void) __compiletime_error(msg); \
|
||||||
|
+ if (!(condition)) \
|
||||||
|
+ prefix ## suffix(); \
|
||||||
|
+ } while (0)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef _compiletime_assert
|
||||||
|
+#define _compiletime_assert(condition, msg, prefix, suffix) \
|
||||||
|
+ __compiletime_assert(condition, msg, prefix, suffix)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * compiletime_assert - break build and emit msg if condition is false
|
||||||
|
+ * @condition: a compile-time constant condition to check
|
||||||
|
+ * @msg: a message to emit if condition is false
|
||||||
|
+ *
|
||||||
|
+ * In tradition of POSIX assert, this macro will break the build if the
|
||||||
|
+ * supplied condition is *false*, emitting the supplied error message if the
|
||||||
|
+ * compiler has support to do so.
|
||||||
|
+ */
|
||||||
|
+#ifndef compiletime_assert
|
||||||
|
+#define compiletime_assert(condition, msg) \
|
||||||
|
+ _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
|
||||||
|
+ * error message.
|
||||||
|
+ * @condition: the condition which the compiler should know is false.
|
||||||
|
+ *
|
||||||
|
+ * See BUILD_BUG_ON for description.
|
||||||
|
+ */
|
||||||
|
+#ifndef BUILD_BUG_ON_MSG
|
||||||
|
+#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef ALIGN
|
||||||
|
+#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||||
|
+#define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
|
||||||
|
+#define ALIGN(x, a) __ALIGN((x), (a))
|
||||||
|
+#endif
|
||||||
|
+#ifndef ALIGN_DOWN
|
||||||
|
+#define ALIGN_DOWN(x, a) __ALIGN((x) - ((a) - 1), (a))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* !COMPILER_H_ */
|
||||||
|
+// vim:fenc=utf-8:tw=75:et
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index e4d40505f09..a0fa5a75e7e 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -97,6 +97,7 @@
|
||||||
|
#define FALLBACK L"\\fb" EFI_ARCH L".efi"
|
||||||
|
#define MOK_MANAGER L"\\mm" EFI_ARCH L".efi"
|
||||||
|
|
||||||
|
+#include "include/asm.h"
|
||||||
|
#include "include/configtable.h"
|
||||||
|
#include "include/console.h"
|
||||||
|
#include "include/crypt_blowfish.h"
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From b5e10f70c7a495dc1788e3604803ee633f1e5f76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stuart Hayes <stuart.w.hayes@gmail.com>
|
||||||
|
Date: Fri, 8 Feb 2019 15:48:20 -0500
|
||||||
|
Subject: [PATCH 31/62] Hook exit when shim_lock protocol installed
|
||||||
|
|
||||||
|
A recent commit moved where the shim_lock protocol is loaded and
|
||||||
|
unloaded, but did not move where exit was hooked and unhooked. Exit
|
||||||
|
needs to be hooked when the protocol is installed, so that the protocol
|
||||||
|
will be uninstalled on exit. Otherwise, the system can crash if, for
|
||||||
|
example, shim loads grub, the user exits grub, shim is run again, which
|
||||||
|
installs a second instance of the protocol, and then grub tries to use
|
||||||
|
the shim_lock protocol that was installed by the first instance of shim.
|
||||||
|
|
||||||
|
Signed-off-by: Stuart Hayes <stuart.w.hayes@gmail.com>
|
||||||
|
Upstream-commit-id: 06c92591e94
|
||||||
|
---
|
||||||
|
shim.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index f69e69487fc..16911a37b17 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2474,9 +2474,9 @@ shim_init(void)
|
||||||
|
loader_is_participating = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- hook_exit(systab);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ hook_exit(systab);
|
||||||
|
return install_shim_protocols();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2494,9 +2494,10 @@ shim_fini(void)
|
||||||
|
* Remove our hooks from system services.
|
||||||
|
*/
|
||||||
|
unhook_system_services();
|
||||||
|
- unhook_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ unhook_exit();
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Free the space allocated for the alternative 2nd stage loader
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,89 @@
|
|||||||
|
From 2cbf56b82a5102777b37c4f7f47c8cf058cea027 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Mon, 13 May 2019 16:34:35 -0400
|
||||||
|
Subject: [PATCH 32/62] Work around stuff -Waddress-of-packed-member finds.
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
In MokManager we get a lot of these:
|
||||||
|
|
||||||
|
../src/MokManager.c:1063:19: error: taking address of packed member of ‘struct <anonymous>’ may result in an unaligned pointer value [-Werror=address-of-packed-member]
|
||||||
|
1063 | if (CompareGuid(&(list[i].Type), &X509_GUID) == 0)
|
||||||
|
| ^~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The reason for this is that gnu-efi takes EFI_GUID * as its argument
|
||||||
|
instead of VOID *, and there's nothing telling the compiler that it
|
||||||
|
doesn't have alignment constraints on the input, so the compiler wants
|
||||||
|
it to have 16-byte alignment.
|
||||||
|
|
||||||
|
Just use CompareMem() for these, as that's all CompareGuid is calling
|
||||||
|
anyway.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 08c14376b59
|
||||||
|
---
|
||||||
|
MokManager.c | 12 +++++++-----
|
||||||
|
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index df9b6fe6912..a1bd39a68e2 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -22,6 +22,8 @@
|
||||||
|
#define CERT_STRING L"Select an X509 certificate to enroll:\n\n"
|
||||||
|
#define HASH_STRING L"Select a file to trust:\n\n"
|
||||||
|
|
||||||
|
+#define CompareMemberGuid(x, y) CompareMem(x, y, sizeof(EFI_GUID))
|
||||||
|
+
|
||||||
|
typedef struct {
|
||||||
|
UINT32 MokSize;
|
||||||
|
UINT8 *Mok;
|
||||||
|
@@ -1077,7 +1079,7 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DataSize += sizeof(EFI_SIGNATURE_LIST);
|
||||||
|
- if (CompareGuid(&(list[i].Type), &X509_GUID) == 0)
|
||||||
|
+ if (CompareMemberGuid(&(list[i].Type), &X509_GUID) == 0)
|
||||||
|
DataSize += sizeof(EFI_GUID);
|
||||||
|
DataSize += list[i].MokSize;
|
||||||
|
}
|
||||||
|
@@ -1099,7 +1101,7 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
CertList->SignatureType = list[i].Type;
|
||||||
|
CertList->SignatureHeaderSize = 0;
|
||||||
|
|
||||||
|
- if (CompareGuid(&(list[i].Type), &X509_GUID) == 0) {
|
||||||
|
+ if (CompareMemberGuid(&(list[i].Type), &X509_GUID) == 0) {
|
||||||
|
CertList->SignatureListSize = list[i].MokSize +
|
||||||
|
sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
|
||||||
|
CertList->SignatureSize =
|
||||||
|
@@ -1140,7 +1142,7 @@ static void delete_cert(void *key, UINT32 key_size,
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if (CompareGuid(&(mok[i].Type), &X509_GUID) != 0)
|
||||||
|
+ if (CompareMemberGuid(&(mok[i].Type), &X509_GUID) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mok[i].MokSize == key_size &&
|
||||||
|
@@ -1191,7 +1193,7 @@ static void delete_hash_in_list(EFI_GUID Type, UINT8 * hash, UINT32 hash_size,
|
||||||
|
sig_size = hash_size + sizeof(EFI_GUID);
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if ((CompareGuid(&(mok[i].Type), &Type) != 0) ||
|
||||||
|
+ if ((CompareMemberGuid(&(mok[i].Type), &Type) != 0) ||
|
||||||
|
(mok[i].MokSize < sig_size))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
@@ -1355,7 +1357,7 @@ static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||||
|
|
||||||
|
/* Search and destroy */
|
||||||
|
for (i = 0; i < del_num; i++) {
|
||||||
|
- if (CompareGuid(&(del_key[i].Type), &X509_GUID) == 0) {
|
||||||
|
+ if (CompareMemberGuid(&(del_key[i].Type), &X509_GUID) == 0) {
|
||||||
|
delete_cert(del_key[i].Mok, del_key[i].MokSize,
|
||||||
|
mok, mok_num);
|
||||||
|
} else if (is_sha2_hash(del_key[i].Type)) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
27
SOURCES/0033-Fix-a-use-of-strlen-instead-of-Strlen.patch
Normal file
27
SOURCES/0033-Fix-a-use-of-strlen-instead-of-Strlen.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From c372ec7a254147f70d62c1f72da5806d42df6994 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 5 Sep 2019 10:36:23 -0400
|
||||||
|
Subject: [PATCH 33/62] Fix a use of strlen() instead of Strlen()
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 1870bae7960
|
||||||
|
---
|
||||||
|
shim.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 16911a37b17..a0eb19b91fe 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2118,7 +2118,7 @@ static int is_our_path(EFI_LOADED_IMAGE *li, CHAR16 *path)
|
||||||
|
|
||||||
|
dprint(L"dppath: %s\n", dppath);
|
||||||
|
dprint(L"path: %s\n", path);
|
||||||
|
- if (StrnCaseCmp(dppath, PathName, strlen(dppath)))
|
||||||
|
+ if (StrnCaseCmp(dppath, PathName, StrLen(dppath)))
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
From 5d30a31fef4eb7e773da24c5e6c20576282a9c3a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gary Lin <glin@suse.com>
|
||||||
|
Date: Tue, 26 Feb 2019 11:33:53 +0800
|
||||||
|
Subject: [PATCH 34/62] MokManager: Use CompareMem on MokListNode.Type instead
|
||||||
|
of CompareGuid
|
||||||
|
|
||||||
|
Fix the errors from gcc9 '-Werror=address-of-packed-member'
|
||||||
|
|
||||||
|
https://github.com/rhboot/shim/issues/161
|
||||||
|
|
||||||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||||||
|
Upstream-commit-id: aaa09b35e73
|
||||||
|
---
|
||||||
|
MokManager.c | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index a1bd39a68e2..30192c16789 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -1079,7 +1079,8 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DataSize += sizeof(EFI_SIGNATURE_LIST);
|
||||||
|
- if (CompareMemberGuid(&(list[i].Type), &X509_GUID) == 0)
|
||||||
|
+ if (CompareMem(&(list[i].Type), &X509_GUID,
|
||||||
|
+ sizeof(EFI_GUID)) == 0)
|
||||||
|
DataSize += sizeof(EFI_GUID);
|
||||||
|
DataSize += list[i].MokSize;
|
||||||
|
}
|
||||||
|
@@ -1101,7 +1102,8 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
CertList->SignatureType = list[i].Type;
|
||||||
|
CertList->SignatureHeaderSize = 0;
|
||||||
|
|
||||||
|
- if (CompareMemberGuid(&(list[i].Type), &X509_GUID) == 0) {
|
||||||
|
+ if (CompareMem(&(list[i].Type), &X509_GUID,
|
||||||
|
+ sizeof(EFI_GUID)) == 0) {
|
||||||
|
CertList->SignatureListSize = list[i].MokSize +
|
||||||
|
sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
|
||||||
|
CertList->SignatureSize =
|
||||||
|
@@ -1142,7 +1144,8 @@ static void delete_cert(void *key, UINT32 key_size,
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if (CompareMemberGuid(&(mok[i].Type), &X509_GUID) != 0)
|
||||||
|
+ if (CompareMem(&(mok[i].Type), &X509_GUID,
|
||||||
|
+ sizeof(EFI_GUID)) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mok[i].MokSize == key_size &&
|
||||||
|
@@ -1193,7 +1196,7 @@ static void delete_hash_in_list(EFI_GUID Type, UINT8 * hash, UINT32 hash_size,
|
||||||
|
sig_size = hash_size + sizeof(EFI_GUID);
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if ((CompareMemberGuid(&(mok[i].Type), &Type) != 0) ||
|
||||||
|
+ if ((CompareMem(&(mok[i].Type), &Type, sizeof(EFI_GUID)) != 0) ||
|
||||||
|
(mok[i].MokSize < sig_size))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
@@ -1357,7 +1360,8 @@ static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||||
|
|
||||||
|
/* Search and destroy */
|
||||||
|
for (i = 0; i < del_num; i++) {
|
||||||
|
- if (CompareMemberGuid(&(del_key[i].Type), &X509_GUID) == 0) {
|
||||||
|
+ if (CompareMem(&(del_key[i].Type), &X509_GUID,
|
||||||
|
+ sizeof(EFI_GUID)) == 0) {
|
||||||
|
delete_cert(del_key[i].Mok, del_key[i].MokSize,
|
||||||
|
mok, mok_num);
|
||||||
|
} else if (is_sha2_hash(del_key[i].Type)) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 44b211bcf7ad58ff29e6495e1c3978e4660cb7d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Tue, 15 Jan 2019 18:04:34 -0500
|
||||||
|
Subject: [PATCH 35/62] OpenSSL: always provide OBJ_create() with name strings.
|
||||||
|
|
||||||
|
Some versions of OpenSSL seem to go back and forth as to whether NULL
|
||||||
|
for these names are okay. Don't risk it.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 46b76a01717
|
||||||
|
---
|
||||||
|
shim.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index a0eb19b91fe..d7ee2b6de6f 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -388,7 +388,9 @@ static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize)
|
||||||
|
EXTENDED_KEY_USAGE *eku;
|
||||||
|
ASN1_OBJECT *module_signing;
|
||||||
|
|
||||||
|
- module_signing = OBJ_nid2obj(OBJ_create(OID_EKU_MODSIGN, NULL, NULL));
|
||||||
|
+ module_signing = OBJ_nid2obj(OBJ_create(OID_EKU_MODSIGN,
|
||||||
|
+ "modsign-eku",
|
||||||
|
+ "modsign-eku"));
|
||||||
|
|
||||||
|
x509 = d2i_X509 (NULL, &Temp, (long) CertSize);
|
||||||
|
if (x509 != NULL) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 07de085dabab8daaea589b597e3915893cc98445 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= <bjorn.forsman@gmail.com>
|
||||||
|
Date: Fri, 26 Apr 2019 11:41:02 +0200
|
||||||
|
Subject: [PATCH 36/62] Use portable shebangs: /bin/bash -> /usr/bin/env bash
|
||||||
|
|
||||||
|
Upstream-commit-id: 6a73ca814af
|
||||||
|
---
|
||||||
|
Cryptlib/update.sh | 2 +-
|
||||||
|
make-certs | 4 +++-
|
||||||
|
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cryptlib/update.sh b/Cryptlib/update.sh
|
||||||
|
index 31a082d4db6..7ea59831a06 100755
|
||||||
|
--- a/Cryptlib/update.sh
|
||||||
|
+++ b/Cryptlib/update.sh
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-#!/bin/bash
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
|
||||||
|
DIR=$1
|
||||||
|
OPENSSL_VERSION="1.0.2k"
|
||||||
|
diff --git a/make-certs b/make-certs
|
||||||
|
index 3e9293b2497..6f40b234d6a 100755
|
||||||
|
--- a/make-certs
|
||||||
|
+++ b/make-certs
|
||||||
|
@@ -1,10 +1,12 @@
|
||||||
|
-#!/bin/bash -e
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Generate a root CA cert for signing, and then a subject cert.
|
||||||
|
# Usage: make-certs.sh hostname [user[@domain]] [more ...]
|
||||||
|
# For testing only, probably still has some bugs in it.
|
||||||
|
#
|
||||||
|
|
||||||
|
+set -e
|
||||||
|
+
|
||||||
|
DOMAIN=xn--u4h.net
|
||||||
|
DAYS=365
|
||||||
|
KEYTYPE=RSA
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From 6fd8db6bb3b23b9e41f109135253f77263071f46 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Coulson <chris.coulson@canonical.com>
|
||||||
|
Date: Sat, 22 Jun 2019 15:33:03 +0100
|
||||||
|
Subject: [PATCH 37/62] tpm: Fix off-by-one error when calculating event size
|
||||||
|
|
||||||
|
tpm_log_event_raw() allocates a buffer for the EFI_TCG2_EVENT structure
|
||||||
|
that is one byte larger than necessary, and sets event->Size accordingly.
|
||||||
|
The result of this is that the event data recorded in the log differs
|
||||||
|
from the data that is measured to the TPM (it has an extra zero byte
|
||||||
|
at the end).
|
||||||
|
|
||||||
|
Upstream-commit-id: 8a27a4809a6
|
||||||
|
---
|
||||||
|
tpm.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index f07362c70bb..516fb876caa 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -131,8 +131,10 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
#endif
|
||||||
|
} else if (tpm2) {
|
||||||
|
EFI_TCG2_EVENT *event;
|
||||||
|
+ UINTN event_size = sizeof(*event) - sizeof(event->Event) +
|
||||||
|
+ logsize;
|
||||||
|
|
||||||
|
- event = AllocatePool(sizeof(*event) + logsize);
|
||||||
|
+ event = AllocatePool(event_size);
|
||||||
|
if (!event) {
|
||||||
|
perror(L"Unable to allocate event structure\n");
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
@@ -142,7 +144,7 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
event->Header.HeaderVersion = 1;
|
||||||
|
event->Header.PCRIndex = pcr;
|
||||||
|
event->Header.EventType = type;
|
||||||
|
- event->Size = sizeof(*event) - sizeof(event->Event) + logsize + 1;
|
||||||
|
+ event->Size = event_size;
|
||||||
|
CopyMem(event->Event, (VOID *)log, logsize);
|
||||||
|
if (hash) {
|
||||||
|
/* TPM 2 systems will generate the appropriate hash
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 9f80be9f16a854e3946568fa92edebe26eb79e78 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Coulson <chris.coulson@canonical.com>
|
||||||
|
Date: Sat, 22 Jun 2019 15:37:29 +0100
|
||||||
|
Subject: [PATCH 38/62] tpm: Define EFI_VARIABLE_DATA_TREE as packed
|
||||||
|
|
||||||
|
tpm_measure_variable() calculates VarLogSize by adding the size of VarName
|
||||||
|
and VarData to the size of EFI_VARIABLE_DATA_TREE, and then subtracting
|
||||||
|
the size of the UnicodeName and VariableData members. This results in a
|
||||||
|
calculation that is 5 bytes larger than necessary because it doesn't take
|
||||||
|
in to account the padding of these members. The effect of this is that
|
||||||
|
shim measures an additional 5 zero bytes when measuring UEFI variables
|
||||||
|
(at least on 64-bit architectures).
|
||||||
|
|
||||||
|
Byte packing EFI_VARIABLE_DATA_TREE fixes this.
|
||||||
|
|
||||||
|
Upstream-commit-id: 7e4d3f1c8c7
|
||||||
|
---
|
||||||
|
tpm.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index 516fb876caa..c0617bb479e 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -233,7 +233,7 @@ typedef struct {
|
||||||
|
UINT64 VariableDataLength;
|
||||||
|
CHAR16 UnicodeName[1];
|
||||||
|
INT8 VariableData[1];
|
||||||
|
-} EFI_VARIABLE_DATA_TREE;
|
||||||
|
+} __attribute__ ((packed)) EFI_VARIABLE_DATA_TREE;
|
||||||
|
|
||||||
|
static BOOLEAN tpm_data_measured(CHAR16 *VarName, EFI_GUID VendorGuid, UINTN VarSize, VOID *VarData)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,223 @@
|
|||||||
|
From 55163bc82c5179adb109c3d8b982c2689d68b4c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ivan Hu <ivan.hu@canonical.com>
|
||||||
|
Date: Fri, 10 May 2019 17:50:12 +0800
|
||||||
|
Subject: [PATCH 39/62] MokManager: console mode modification for hi-dpi screen
|
||||||
|
devices
|
||||||
|
|
||||||
|
There are lots of hi-dpi laptops nowadays, as doing mok enrollment, the font
|
||||||
|
is too small to see.
|
||||||
|
https://bugs.launchpad.net/ubuntu/+source/shim/+bug/1822043
|
||||||
|
|
||||||
|
This patch checks if the resolution is larger than Full HD (1920x1080) and
|
||||||
|
current console output columns and rows is in a good mode. Then swith the
|
||||||
|
console output to a better mode.
|
||||||
|
|
||||||
|
Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
|
||||||
|
Upstream-commit-id: cf05af6d899
|
||||||
|
---
|
||||||
|
MokManager.c | 2 +
|
||||||
|
lib/console.c | 161 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
include/console.h | 2 +
|
||||||
|
3 files changed, 164 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index 30192c16789..78da9fd95ee 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -2560,6 +2560,8 @@ EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * systab)
|
||||||
|
|
||||||
|
setup_rand();
|
||||||
|
|
||||||
|
+ console_mode_handle();
|
||||||
|
+
|
||||||
|
efi_status = check_mok_request(image_handle);
|
||||||
|
|
||||||
|
console_fini();
|
||||||
|
diff --git a/lib/console.c b/lib/console.c
|
||||||
|
index 3aee41cd276..c92d27f3c86 100644
|
||||||
|
--- a/lib/console.c
|
||||||
|
+++ b/lib/console.c
|
||||||
|
@@ -409,7 +409,166 @@ console_notify(CHAR16 *string)
|
||||||
|
console_alertbox(str_arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
|
||||||
|
+void
|
||||||
|
+console_save_and_set_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
|
||||||
|
+{
|
||||||
|
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||||||
|
+
|
||||||
|
+ if (!SavedMode) {
|
||||||
|
+ console_print(L"Invalid parameter: SavedMode\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ CopyMem(SavedMode, co->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
|
||||||
|
+ co->EnableCursor(co, FALSE);
|
||||||
|
+ co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+console_restore_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
|
||||||
|
+{
|
||||||
|
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||||||
|
+
|
||||||
|
+ co->EnableCursor(co, SavedMode->CursorVisible);
|
||||||
|
+ co->SetCursorPosition(co, SavedMode->CursorColumn,
|
||||||
|
+ SavedMode->CursorRow);
|
||||||
|
+ co->SetAttribute(co, SavedMode->Attribute);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+console_countdown(CHAR16* title, const CHAR16* message, int timeout)
|
||||||
|
+{
|
||||||
|
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||||||
|
+ SIMPLE_INPUT_INTERFACE *ci = ST->ConIn;
|
||||||
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||||||
|
+ EFI_INPUT_KEY key;
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+ UINTN cols, rows;
|
||||||
|
+ CHAR16 *titles[2];
|
||||||
|
+ int wait = 10000000;
|
||||||
|
+
|
||||||
|
+ console_save_and_set_mode(&SavedMode);
|
||||||
|
+
|
||||||
|
+ titles[0] = title;
|
||||||
|
+ titles[1] = NULL;
|
||||||
|
+
|
||||||
|
+ console_print_box_at(titles, -1, 0, 0, -1, -1, 1, 1);
|
||||||
|
+
|
||||||
|
+ co->QueryMode(co, co->Mode->Mode, &cols, &rows);
|
||||||
|
+
|
||||||
|
+ console_print_at((cols - StrLen(message)) / 2, rows / 2, message);
|
||||||
|
+ while (1) {
|
||||||
|
+ if (timeout > 1)
|
||||||
|
+ console_print_at(2, rows - 3,
|
||||||
|
+ L"Booting in %d seconds ",
|
||||||
|
+ timeout);
|
||||||
|
+ else if (timeout)
|
||||||
|
+ console_print_at(2, rows - 3,
|
||||||
|
+ L"Booting in %d second ",
|
||||||
|
+ timeout);
|
||||||
|
+
|
||||||
|
+ efi_status = WaitForSingleEvent(ci->WaitForKey, wait);
|
||||||
|
+ if (efi_status != EFI_TIMEOUT) {
|
||||||
|
+ /* Clear the key in the queue */
|
||||||
|
+ ci->ReadKeyStroke(ci, &key);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ timeout--;
|
||||||
|
+ if (!timeout)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ console_restore_mode(&SavedMode);
|
||||||
|
+
|
||||||
|
+ return timeout;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define HORIZONTAL_MAX_OK 1920
|
||||||
|
+#define VERTICAL_MAX_OK 1080
|
||||||
|
+#define COLUMNS_MAX_OK 200
|
||||||
|
+#define ROWS_MAX_OK 100
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+console_mode_handle(VOID)
|
||||||
|
+{
|
||||||
|
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
|
||||||
|
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||||
|
+ EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
|
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
|
||||||
|
+
|
||||||
|
+ UINTN mode_set;
|
||||||
|
+ UINTN rows = 0, columns = 0;
|
||||||
|
+ EFI_STATUS efi_status = EFI_SUCCESS;
|
||||||
|
+
|
||||||
|
+ efi_status = gBS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ console_error(L"Locate graphic output protocol fail", efi_status);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Info = gop->Mode->Info;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Start verifying if we are in a resolution larger than Full HD
|
||||||
|
+ * (1920x1080). If we're not, assume we're in a good mode and do not
|
||||||
|
+ * try to change it.
|
||||||
|
+ */
|
||||||
|
+ if (Info->HorizontalResolution <= HORIZONTAL_MAX_OK &&
|
||||||
|
+ Info->VerticalResolution <= VERTICAL_MAX_OK) {
|
||||||
|
+ /* keep original mode and return */
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ efi_status = co->QueryMode(co, co->Mode->Mode, &columns, &rows);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ console_error(L"Console query mode fail", efi_status);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Verify current console output to check if the character columns and
|
||||||
|
+ * rows in a good mode.
|
||||||
|
+ */
|
||||||
|
+ if (columns <= COLUMNS_MAX_OK && rows <= ROWS_MAX_OK) {
|
||||||
|
+ /* keep original mode and return */
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!console_text_mode)
|
||||||
|
+ setup_console(1);
|
||||||
|
+
|
||||||
|
+ co->Reset(co, TRUE);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If we reached here, then we have a high resolution screen and the
|
||||||
|
+ * text too small. Try to switch to a better mode. Mode number 2 is
|
||||||
|
+ * first non standard mode, which is provided by the device
|
||||||
|
+ * manufacturer, so it should be a good mode.
|
||||||
|
+ */
|
||||||
|
+ if (co->Mode->MaxMode > 2)
|
||||||
|
+ mode_set = 2;
|
||||||
|
+ else
|
||||||
|
+ mode_set = 0;
|
||||||
|
+
|
||||||
|
+ efi_status = co->SetMode(co, mode_set);
|
||||||
|
+ if (EFI_ERROR(efi_status) && mode_set != 0) {
|
||||||
|
+ /*
|
||||||
|
+ * Set to 0 mode which is required that all output devices
|
||||||
|
+ * support at least 80x25 text mode.
|
||||||
|
+ */
|
||||||
|
+ mode_set = 0;
|
||||||
|
+ efi_status = co->SetMode(co, mode_set);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ co->ClearScreen(co);
|
||||||
|
+
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ console_error(L"Console set mode fail", efi_status);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Copy of gnu-efi-3.0 with the added secure boot strings */
|
||||||
|
static struct {
|
||||||
|
diff --git a/include/console.h b/include/console.h
|
||||||
|
index deb4fa3db23..9f259c71b72 100644
|
||||||
|
--- a/include/console.h
|
||||||
|
+++ b/include/console.h
|
||||||
|
@@ -34,6 +34,8 @@ void
|
||||||
|
console_notify(CHAR16 *string);
|
||||||
|
void
|
||||||
|
console_reset(void);
|
||||||
|
+void
|
||||||
|
+console_mode_handle(void);
|
||||||
|
#define NOSEL 0x7fffffff
|
||||||
|
|
||||||
|
typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,111 @@
|
|||||||
|
From d57e53f3bddc4bc7299b3d5efd5ba8c547e8dfa5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonas Witschel <diabonas@gmx.de>
|
||||||
|
Date: Thu, 5 Sep 2019 10:39:37 +0200
|
||||||
|
Subject: [PATCH 40/62] MokManager: avoid -Werror=address-of-packed-member
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
When compiling with GCC 9, there are a couple of errors of the form
|
||||||
|
|
||||||
|
MokManager.c: In function ‘write_back_mok_list’:
|
||||||
|
MokManager.c:1056:19: error: taking address of packed member of ‘struct <anonymous>’ may result in an unaligned pointer value [-Werror=address-of-packed-member]
|
||||||
|
1056 | if (CompareGuid(&(list[i].Type), &X509_GUID) == 0)
|
||||||
|
| ^~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copying the member of the packed struct to a temporary variable and
|
||||||
|
pointing to that variable solves the problem.
|
||||||
|
|
||||||
|
Upstream-commit-id: 58532e12e9a
|
||||||
|
---
|
||||||
|
MokManager.c | 22 +++++++++++++---------
|
||||||
|
1 file changed, 13 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index 78da9fd95ee..fa73e2fd865 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -1064,6 +1064,7 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
EFI_SIGNATURE_LIST *CertList;
|
||||||
|
EFI_SIGNATURE_DATA *CertData;
|
||||||
|
+ EFI_GUID type;
|
||||||
|
void *Data = NULL, *ptr;
|
||||||
|
INTN DataSize = 0;
|
||||||
|
int i;
|
||||||
|
@@ -1079,8 +1080,8 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DataSize += sizeof(EFI_SIGNATURE_LIST);
|
||||||
|
- if (CompareMem(&(list[i].Type), &X509_GUID,
|
||||||
|
- sizeof(EFI_GUID)) == 0)
|
||||||
|
+ type = list[i].Type; /* avoid -Werror=address-of-packed-member */
|
||||||
|
+ if (CompareGuid(&type, &X509_GUID) == 0)
|
||||||
|
DataSize += sizeof(EFI_GUID);
|
||||||
|
DataSize += list[i].MokSize;
|
||||||
|
}
|
||||||
|
@@ -1102,8 +1103,7 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
CertList->SignatureType = list[i].Type;
|
||||||
|
CertList->SignatureHeaderSize = 0;
|
||||||
|
|
||||||
|
- if (CompareMem(&(list[i].Type), &X509_GUID,
|
||||||
|
- sizeof(EFI_GUID)) == 0) {
|
||||||
|
+ if (CompareGuid(&(CertList->SignatureType), &X509_GUID) == 0) {
|
||||||
|
CertList->SignatureListSize = list[i].MokSize +
|
||||||
|
sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
|
||||||
|
CertList->SignatureSize =
|
||||||
|
@@ -1141,11 +1141,12 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
static void delete_cert(void *key, UINT32 key_size,
|
||||||
|
MokListNode * mok, INTN mok_num)
|
||||||
|
{
|
||||||
|
+ EFI_GUID type;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if (CompareMem(&(mok[i].Type), &X509_GUID,
|
||||||
|
- sizeof(EFI_GUID)) != 0)
|
||||||
|
+ type = mok[i].Type; /* avoid -Werror=address-of-packed-member */
|
||||||
|
+ if (CompareGuid(&type, &X509_GUID) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mok[i].MokSize == key_size &&
|
||||||
|
@@ -1187,6 +1188,7 @@ static void mem_move(void *dest, void *src, UINTN size)
|
||||||
|
static void delete_hash_in_list(EFI_GUID Type, UINT8 * hash, UINT32 hash_size,
|
||||||
|
MokListNode * mok, INTN mok_num)
|
||||||
|
{
|
||||||
|
+ EFI_GUID type;
|
||||||
|
UINT32 sig_size;
|
||||||
|
UINT32 list_num;
|
||||||
|
int i, del_ind;
|
||||||
|
@@ -1196,7 +1198,8 @@ static void delete_hash_in_list(EFI_GUID Type, UINT8 * hash, UINT32 hash_size,
|
||||||
|
sig_size = hash_size + sizeof(EFI_GUID);
|
||||||
|
|
||||||
|
for (i = 0; i < mok_num; i++) {
|
||||||
|
- if ((CompareMem(&(mok[i].Type), &Type, sizeof(EFI_GUID)) != 0) ||
|
||||||
|
+ type = mok[i].Type; /* avoid -Werror=address-of-packed-member */
|
||||||
|
+ if ((CompareGuid(&type, &Type) != 0) ||
|
||||||
|
(mok[i].MokSize < sig_size))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
@@ -1252,6 +1255,7 @@ static void delete_hash_list(EFI_GUID Type, void *hash_list, UINT32 list_size,
|
||||||
|
static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
+ EFI_GUID type;
|
||||||
|
CHAR16 *db_name;
|
||||||
|
CHAR16 *auth_name;
|
||||||
|
CHAR16 *err_strs[] = { NULL, NULL, NULL };
|
||||||
|
@@ -1360,8 +1364,8 @@ static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||||
|
|
||||||
|
/* Search and destroy */
|
||||||
|
for (i = 0; i < del_num; i++) {
|
||||||
|
- if (CompareMem(&(del_key[i].Type), &X509_GUID,
|
||||||
|
- sizeof(EFI_GUID)) == 0) {
|
||||||
|
+ type = del_key[i].Type; /* avoid -Werror=address-of-packed-member */
|
||||||
|
+ if (CompareGuid(&type, &X509_GUID) == 0) {
|
||||||
|
delete_cert(del_key[i].Mok, del_key[i].MokSize,
|
||||||
|
mok, mok_num);
|
||||||
|
} else if (is_sha2_hash(del_key[i].Type)) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
31
SOURCES/0041-tpm-Don-t-log-duplicate-identical-events.patch
Normal file
31
SOURCES/0041-tpm-Don-t-log-duplicate-identical-events.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 58df8d745c6516818ba6ebfa8fe826702c1621a0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Coulson <chris.coulson@canonical.com>
|
||||||
|
Date: Thu, 26 Sep 2019 20:01:01 +0100
|
||||||
|
Subject: [PATCH 41/62] tpm: Don't log duplicate identical events
|
||||||
|
|
||||||
|
According to the comment in tpm_measure_variable ("Don't measure something that we've already measured"), shim
|
||||||
|
shouldn't measure duplicate events if they are identical, which also aligns with section 2.3.4.8 of the TCG PC
|
||||||
|
Client Platform Firmware Profile Specification ("If it has been measured previously, it MUST NOT be measured
|
||||||
|
again"). This is currently broken because tpm_data_measured() uses the return value of CompareGuid() incorrectly.
|
||||||
|
|
||||||
|
Upstream-commit-id: 103adc89ce5
|
||||||
|
---
|
||||||
|
tpm.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index c0617bb479e..196b93c30f6 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -241,7 +241,7 @@ static BOOLEAN tpm_data_measured(CHAR16 *VarName, EFI_GUID VendorGuid, UINTN Var
|
||||||
|
|
||||||
|
for (i=0; i<measuredcount; i++) {
|
||||||
|
if ((StrCmp (VarName, measureddata[i].VariableName) == 0) &&
|
||||||
|
- (CompareGuid (&VendorGuid, measureddata[i].VendorGuid)) &&
|
||||||
|
+ (CompareGuid (&VendorGuid, measureddata[i].VendorGuid) == 0) &&
|
||||||
|
(VarSize == measureddata[i].Size) &&
|
||||||
|
(CompareMem (VarData, measureddata[i].Data, VarSize) == 0)) {
|
||||||
|
return TRUE;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
57
SOURCES/0042-Slightly-better-debugging-messages.patch
Normal file
57
SOURCES/0042-Slightly-better-debugging-messages.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
From 5e6e0792cedb3b71cbe061ae56e96906cf710579 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Mon, 18 Nov 2019 13:59:14 -0500
|
||||||
|
Subject: [PATCH 42/62] Slightly better debugging messages
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 173d35fe8f5
|
||||||
|
---
|
||||||
|
shim.c | 14 ++++++++++----
|
||||||
|
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index d7ee2b6de6f..2f7aba07421 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2459,6 +2459,8 @@ uninstall_shim_protocols(void)
|
||||||
|
EFI_STATUS
|
||||||
|
shim_init(void)
|
||||||
|
{
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+
|
||||||
|
setup_verbosity();
|
||||||
|
dprint(L"%a", shim_version);
|
||||||
|
|
||||||
|
@@ -2479,7 +2481,12 @@ shim_init(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_exit(systab);
|
||||||
|
- return install_shim_protocols();
|
||||||
|
+
|
||||||
|
+ efi_status = install_shim_protocols();
|
||||||
|
+ if (EFI_ERROR(efi_status))
|
||||||
|
+ perror(L"install_shim_protocols() failed: %r\n", efi_status);
|
||||||
|
+
|
||||||
|
+ return efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -2575,13 +2582,12 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
build_cert = shim_cert;
|
||||||
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
CHAR16 *msgs[] = {
|
||||||
|
- L"import_mok_state() failed\n",
|
||||||
|
- L"shim_int() failed\n",
|
||||||
|
+ L"import_mok_state() failed",
|
||||||
|
+ L"shim_init() failed",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int msg = 0;
|
||||||
|
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Set up the shim lock protocol so that grub and MokManager can
|
||||||
|
* call back in and use shim functions
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From 959f5e4e993a82020fef48c7e7c012a44074645c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Mon, 18 Nov 2019 13:58:46 -0500
|
||||||
|
Subject: [PATCH 43/62] Actually check for errors from set_second_stage()
|
||||||
|
|
||||||
|
This changes shim_init() to check for errors from set_second_stage().
|
||||||
|
In order to make that work, it also does the following:
|
||||||
|
|
||||||
|
- correctly /always/ allocate second_stage, not sometimes allocate and
|
||||||
|
sometimes point at .data
|
||||||
|
- test for LoadOptionSize == 0 and return success
|
||||||
|
- print an error message for the failure so we can see it.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 354bd9b1931
|
||||||
|
---
|
||||||
|
shim.c | 21 +++++++++++++++++++--
|
||||||
|
1 file changed, 19 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 2f7aba07421..5329795c333 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2141,8 +2141,15 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
|
||||||
|
CHAR16 *loader_str = NULL;
|
||||||
|
UINTN loader_len = 0;
|
||||||
|
unsigned int i;
|
||||||
|
+ UINTN second_stage_len;
|
||||||
|
|
||||||
|
- second_stage = DEFAULT_LOADER;
|
||||||
|
+ second_stage_len = StrLen(DEFAULT_LOADER) + 1;
|
||||||
|
+ second_stage = AllocatePool(second_stage_len);
|
||||||
|
+ if (!second_stage) {
|
||||||
|
+ perror(L"Could not allocate %lu bytes\n", second_stage_len);
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ }
|
||||||
|
+ StrCpy(second_stage, DEFAULT_LOADER);
|
||||||
|
load_options = NULL;
|
||||||
|
load_options_size = 0;
|
||||||
|
|
||||||
|
@@ -2199,6 +2206,12 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
|
||||||
|
* BDS will add that, but we ignore that here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Maybe there just aren't any options...
|
||||||
|
+ */
|
||||||
|
+ if (li->LoadOptionsSize == 0)
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* In either case, we've got to have at least a UCS2 NUL...
|
||||||
|
*/
|
||||||
|
@@ -2465,7 +2478,11 @@ shim_init(void)
|
||||||
|
dprint(L"%a", shim_version);
|
||||||
|
|
||||||
|
/* Set the second stage loader */
|
||||||
|
- set_second_stage (global_image_handle);
|
||||||
|
+ efi_status = set_second_stage(global_image_handle);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"set_second_stage() failed: %r\n", efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (secure_mode()) {
|
||||||
|
if (vendor_cert_size || vendor_dbx_size) {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,140 @@
|
|||||||
|
From c6bedd5b83529925c3ec08f96a3bf61c81bff0ae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
Date: Tue, 28 Jan 2020 23:33:46 +0100
|
||||||
|
Subject: [PATCH 44/62] translate_slashes(): don't write to string literals
|
||||||
|
|
||||||
|
Currently, all three invocations of the translate_slashes() function may
|
||||||
|
lead to writes to the string literal that is #defined with the
|
||||||
|
DEFAULT_LOADER_CHAR macro. According to ISO C99 6.4.5p6, this is undefined
|
||||||
|
behavior ("If the program attempts to modify such an array, the behavior
|
||||||
|
is undefined").
|
||||||
|
|
||||||
|
This bug crashes shim on e.g. the 64-bit ArmVirtQemu platform ("Data
|
||||||
|
abort: Permission fault"), where the platform firmware maps the .text
|
||||||
|
section (which contains the string literal) read-only.
|
||||||
|
|
||||||
|
Modify translate_slashes() so that it copies and translates characters
|
||||||
|
from an input array of "char" to an output array of "CHAR8".
|
||||||
|
|
||||||
|
While at it, fix another bug. Before this patch, if translate_slashes()
|
||||||
|
ever encountered a double backslash (translating it to a single forward
|
||||||
|
slash), then the output would end up shorter than the input. However, the
|
||||||
|
output was not NUL-terminated in-place, therefore the original string
|
||||||
|
length (and according trailing garbage) would be preserved. After this
|
||||||
|
patch, the NUL-termination on contraction is automatic, as the output
|
||||||
|
array's contents are indeterminate when entering the function, and so we
|
||||||
|
must NUL-terminate it anyway.
|
||||||
|
|
||||||
|
Fixes: 8e9124227d18475d3bc634c33518963fc8db7c98
|
||||||
|
Fixes: e62b69a5b0b87c6df7a4fc23906134945309e927
|
||||||
|
Fixes: 3d79bcb2651b9eae809b975b3e03e2f96c067072
|
||||||
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795654
|
||||||
|
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
Upstream-commit-id: 9813e8bc8b3
|
||||||
|
---
|
||||||
|
httpboot.c | 4 ++--
|
||||||
|
netboot.c | 16 +++++++++++-----
|
||||||
|
include/str.h | 14 ++++++++------
|
||||||
|
3 files changed, 21 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/httpboot.c b/httpboot.c
|
||||||
|
index 3622e85867c..2d27e8ed993 100644
|
||||||
|
--- a/httpboot.c
|
||||||
|
+++ b/httpboot.c
|
||||||
|
@@ -743,14 +743,14 @@ httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
EFI_HANDLE nic;
|
||||||
|
- CHAR8 *next_loader = NULL;
|
||||||
|
+ CHAR8 next_loader[sizeof DEFAULT_LOADER_CHAR];
|
||||||
|
CHAR8 *next_uri = NULL;
|
||||||
|
CHAR8 *hostname = NULL;
|
||||||
|
|
||||||
|
if (!uri)
|
||||||
|
return EFI_NOT_READY;
|
||||||
|
|
||||||
|
- next_loader = translate_slashes(DEFAULT_LOADER_CHAR);
|
||||||
|
+ translate_slashes(next_loader, DEFAULT_LOADER_CHAR);
|
||||||
|
|
||||||
|
/* Create the URI for the next loader based on the original URI */
|
||||||
|
efi_status = generate_next_uri(uri, next_loader, &next_uri);
|
||||||
|
diff --git a/netboot.c b/netboot.c
|
||||||
|
index 58babfb4d2e..4922ef284b1 100644
|
||||||
|
--- a/netboot.c
|
||||||
|
+++ b/netboot.c
|
||||||
|
@@ -189,7 +189,9 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
|
||||||
|
CHAR8 *start, *end;
|
||||||
|
CHAR8 ip6str[40];
|
||||||
|
CHAR8 ip6inv[16];
|
||||||
|
- CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
|
||||||
|
+ CHAR8 template[sizeof DEFAULT_LOADER_CHAR];
|
||||||
|
+
|
||||||
|
+ translate_slashes(template, DEFAULT_LOADER_CHAR);
|
||||||
|
|
||||||
|
// to check against str2ip6() errors
|
||||||
|
memset(ip6inv, 0, sizeof(ip6inv));
|
||||||
|
@@ -254,10 +256,14 @@ static EFI_STATUS parseDhcp6()
|
||||||
|
|
||||||
|
static EFI_STATUS parseDhcp4()
|
||||||
|
{
|
||||||
|
- CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
|
||||||
|
- INTN template_len = strlen(template) + 1;
|
||||||
|
+ CHAR8 template[sizeof DEFAULT_LOADER_CHAR];
|
||||||
|
+ INTN template_len;
|
||||||
|
+ UINTN template_ofs = 0;
|
||||||
|
EFI_PXE_BASE_CODE_DHCPV4_PACKET* pkt_v4 = (EFI_PXE_BASE_CODE_DHCPV4_PACKET *)&pxe->Mode->DhcpAck.Dhcpv4;
|
||||||
|
|
||||||
|
+ translate_slashes(template, DEFAULT_LOADER_CHAR);
|
||||||
|
+ template_len = strlen(template) + 1;
|
||||||
|
+
|
||||||
|
if(pxe->Mode->ProxyOfferReceived) {
|
||||||
|
/*
|
||||||
|
* Proxy should not have precedence. Check if DhcpAck
|
||||||
|
@@ -288,8 +294,8 @@ static EFI_STATUS parseDhcp4()
|
||||||
|
full_path[dir_len-1] = '\0';
|
||||||
|
}
|
||||||
|
if (dir_len == 0 && dir[0] != '/' && template[0] == '/')
|
||||||
|
- template++;
|
||||||
|
- strcata(full_path, template);
|
||||||
|
+ template_ofs++;
|
||||||
|
+ strcata(full_path, template + template_ofs);
|
||||||
|
memcpy(&tftp_addr.v4, pkt_v4->BootpSiAddr, 4);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
diff --git a/include/str.h b/include/str.h
|
||||||
|
index 9a748366bd1..f73c6212cd9 100644
|
||||||
|
--- a/include/str.h
|
||||||
|
+++ b/include/str.h
|
||||||
|
@@ -45,21 +45,23 @@ strcata(CHAR8 *dest, const CHAR8 *src)
|
||||||
|
static inline
|
||||||
|
__attribute__((unused))
|
||||||
|
CHAR8 *
|
||||||
|
-translate_slashes(char *str)
|
||||||
|
+translate_slashes(CHAR8 *out, const char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
- if (str == NULL)
|
||||||
|
- return (CHAR8 *)str;
|
||||||
|
+ if (str == NULL || out == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
|
||||||
|
if (str[i] == '\\') {
|
||||||
|
- str[j] = '/';
|
||||||
|
+ out[j] = '/';
|
||||||
|
if (str[i+1] == '\\')
|
||||||
|
i++;
|
||||||
|
- }
|
||||||
|
+ } else
|
||||||
|
+ out[j] = str[i];
|
||||||
|
}
|
||||||
|
- return (CHAR8 *)str;
|
||||||
|
+ out[j] = '\0';
|
||||||
|
+ return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SHIM_STR_H */
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,93 @@
|
|||||||
|
From 89d72301aa67c82f00fe7fa4f42d7f6eb6045538 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Tue, 18 Feb 2020 12:03:28 +0100
|
||||||
|
Subject: [PATCH 45/62] shim: Update EFI_LOADED_IMAGE with the second stage
|
||||||
|
loader file path
|
||||||
|
|
||||||
|
When shim loads the second stage loader (e.g: GRUB) the FilePath field of
|
||||||
|
the EFI_LOADED_IMAGE structure isn't updated with the path of the loaded
|
||||||
|
binary. So it still contains the file path of the shim binary.
|
||||||
|
|
||||||
|
This isn't a problem since the file path is currently not used. But should
|
||||||
|
be used to set the DevicePath field of the EFI_IMAGE_LOAD_EVENT structure
|
||||||
|
that is logged when measuring the PE/COFF binaries. In that case the TPM
|
||||||
|
Event Log will have an incorrect file path for the measured binary, i.e:
|
||||||
|
|
||||||
|
$ hexdump -Cv /sys/kernel/security/tpm0/binary_bios_measurements
|
||||||
|
...
|
||||||
|
00000a50 00 00 00 00 00 00 04 04 34 00 5c 00 45 00 46 00 |........4.\.E.F.|
|
||||||
|
00000a60 49 00 5c 00 72 00 65 00 64 00 68 00 61 00 74 00 |I.\.r.e.d.h.a.t.|
|
||||||
|
00000a70 5c 00 73 00 68 00 69 00 6d 00 78 00 36 00 34 00 |\.s.h.i.m.x.6.4.|
|
||||||
|
00000a80 2e 00 65 00 66 00 69 00 00 00 7f ff 04 00 00 00 |..e.f.i.........|
|
||||||
|
00000a90 00 00 00 00 00 00 af 08 00 00 00 0d 00 00 00 b5 |................|
|
||||||
|
00000aa0 cd d0 8f bb 16 31 e2 80 8b e8 58 75 c9 89 18 95 |.....1....Xu....|
|
||||||
|
00000ab0 d2 de 15 15 00 00 00 67 72 75 62 5f 63 6d 64 20 |.......grub_cmd |
|
||||||
|
00000ac0 73 65 74 20 70 61 67 65 72 3d 31 00 08 00 00 00 |set pager=1.....|
|
||||||
|
...
|
||||||
|
|
||||||
|
So update the EFI_LOADED_IMAGE structure with the second stage loader file
|
||||||
|
path to have the correct value in the log, i.e:
|
||||||
|
|
||||||
|
$ hexdump -Cv /sys/kernel/security/tpm0/binary_bios_measurements
|
||||||
|
...
|
||||||
|
00000a50 00 00 00 00 00 00 04 04 34 00 5c 00 45 00 46 00 |........4.\.E.F.|
|
||||||
|
00000a60 49 00 5c 00 72 00 65 00 64 00 68 00 61 00 74 00 |I.\.r.e.d.h.a.t.|
|
||||||
|
00000a70 5c 00 67 00 72 00 75 00 62 00 78 00 36 00 34 00 |\.g.r.u.b.x.6.4.|
|
||||||
|
00000a80 2e 00 65 00 66 00 69 00 00 00 7f ff 04 00 00 00 |..e.f.i.........|
|
||||||
|
00000a90 00 00 00 00 00 00 af 08 00 00 00 0d 00 00 00 b5 |................|
|
||||||
|
00000aa0 cd d0 8f bb 16 31 e2 80 8b e8 58 75 c9 89 18 95 |.....1....Xu....|
|
||||||
|
00000ab0 d2 de 15 15 00 00 00 67 72 75 62 5f 63 6d 64 20 |.......grub_cmd |
|
||||||
|
00000ac0 73 65 74 20 70 61 67 65 72 3d 31 00 08 00 00 00 |set pager=1.....|
|
||||||
|
...
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Upstream-commit-id: cd7d42d493d
|
||||||
|
---
|
||||||
|
shim.c | 17 +++++++++++++++--
|
||||||
|
1 file changed, 15 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 5329795c333..a4f7769b38b 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -1925,6 +1925,16 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
|
||||||
|
*/
|
||||||
|
CopyMem(&li_bak, li, sizeof(li_bak));
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Update the loaded image with the second stage loader file path
|
||||||
|
+ */
|
||||||
|
+ li->FilePath = FileDevicePath(NULL, PathName);
|
||||||
|
+ if (!li->FilePath) {
|
||||||
|
+ perror(L"Unable to update loaded image file path\n");
|
||||||
|
+ efi_status = EFI_OUT_OF_RESOURCES;
|
||||||
|
+ goto restore;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Verify and, if appropriate, relocate and execute the executable
|
||||||
|
*/
|
||||||
|
@@ -1934,8 +1944,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
|
||||||
|
perror(L"Failed to load image: %r\n", efi_status);
|
||||||
|
PrintErrors();
|
||||||
|
ClearErrors();
|
||||||
|
- CopyMem(li, &li_bak, sizeof(li_bak));
|
||||||
|
- goto done;
|
||||||
|
+ goto restore;
|
||||||
|
}
|
||||||
|
|
||||||
|
loader_is_participating = 0;
|
||||||
|
@@ -1945,6 +1954,10 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
|
||||||
|
*/
|
||||||
|
efi_status = entry_point(image_handle, systab);
|
||||||
|
|
||||||
|
+restore:
|
||||||
|
+ if (li->FilePath)
|
||||||
|
+ FreePool(li->FilePath);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Restore our original loaded image values
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,124 @@
|
|||||||
|
From 0a8f7ade76ff3eede486027eaa638181e6bed3b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Tue, 18 Feb 2020 12:03:17 +0100
|
||||||
|
Subject: [PATCH 46/62] tpm: Include information about PE/COFF images in the
|
||||||
|
TPM Event Log
|
||||||
|
|
||||||
|
The "TCG PC Client Specific Platform Firmware Profile Specification" says
|
||||||
|
that when measuring a PE/COFF image, the TCG_PCR_EVENT2 structure Event
|
||||||
|
field MUST contain a UEFI_IMAGE_LOAD_EVENT structure.
|
||||||
|
|
||||||
|
Currently an empty UEFI_IMAGE_LOAD_EVENT structure is passed so users only
|
||||||
|
have the hash of the PE/COFF image, but not information such the file path
|
||||||
|
of the binary.
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Upstream-commit-id: c252b9ee94c
|
||||||
|
---
|
||||||
|
shim.c | 7 +++++--
|
||||||
|
tpm.c | 46 ++++++++++++++++++++++++++++++++--------------
|
||||||
|
include/tpm.h | 5 +++--
|
||||||
|
3 files changed, 40 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index a4f7769b38b..b35b0ad90cc 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -1274,7 +1274,9 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
|
||||||
|
#ifdef REQUIRE_TPM
|
||||||
|
efi_status =
|
||||||
|
#endif
|
||||||
|
- tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)data, datasize, sha1hash, 4);
|
||||||
|
+ tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)data, datasize,
|
||||||
|
+ (EFI_PHYSICAL_ADDRESS)(UINTN)context.ImageAddress,
|
||||||
|
+ li->FilePath, sha1hash, 4);
|
||||||
|
#ifdef REQUIRE_TPM
|
||||||
|
if (efi_status != EFI_SUCCESS) {
|
||||||
|
return efi_status;
|
||||||
|
@@ -1788,7 +1790,8 @@ EFI_STATUS shim_verify (void *buffer, UINT32 size)
|
||||||
|
#ifdef REQUIRE_TPM
|
||||||
|
efi_status =
|
||||||
|
#endif
|
||||||
|
- tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)buffer, size, sha1hash, 4);
|
||||||
|
+ tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)buffer, size, 0, NULL,
|
||||||
|
+ sha1hash, 4);
|
||||||
|
#ifdef REQUIRE_TPM
|
||||||
|
if (EFI_ERROR(efi_status))
|
||||||
|
goto done;
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index 196b93c30f6..22ad148b35a 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -210,21 +210,39 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
|
||||||
|
strlen(description) + 1, 0xd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 *sha1hash,
|
||||||
|
- UINT8 pcr)
|
||||||
|
+EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
+ EFI_PHYSICAL_ADDRESS addr, EFI_DEVICE_PATH *path,
|
||||||
|
+ UINT8 *sha1hash, UINT8 pcr)
|
||||||
|
{
|
||||||
|
- EFI_IMAGE_LOAD_EVENT ImageLoad;
|
||||||
|
-
|
||||||
|
- // All of this is informational and forces us to do more parsing before
|
||||||
|
- // we can generate it, so let's just leave it out for now
|
||||||
|
- ImageLoad.ImageLocationInMemory = 0;
|
||||||
|
- ImageLoad.ImageLengthInMemory = 0;
|
||||||
|
- ImageLoad.ImageLinkTimeAddress = 0;
|
||||||
|
- ImageLoad.LengthOfDevicePath = 0;
|
||||||
|
-
|
||||||
|
- return tpm_log_event_raw(buf, size, pcr, (CHAR8 *)&ImageLoad,
|
||||||
|
- sizeof(ImageLoad),
|
||||||
|
- EV_EFI_BOOT_SERVICES_APPLICATION, sha1hash);
|
||||||
|
+ EFI_IMAGE_LOAD_EVENT *ImageLoad = NULL;
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+ UINTN path_size = 0;
|
||||||
|
+
|
||||||
|
+ if (path)
|
||||||
|
+ path_size = DevicePathSize(path);
|
||||||
|
+
|
||||||
|
+ ImageLoad = AllocateZeroPool(sizeof(*ImageLoad) + path_size);
|
||||||
|
+ if (!ImageLoad) {
|
||||||
|
+ perror(L"Unable to allocate image load event structure\n");
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ImageLoad->ImageLocationInMemory = buf;
|
||||||
|
+ ImageLoad->ImageLengthInMemory = size;
|
||||||
|
+ ImageLoad->ImageLinkTimeAddress = addr;
|
||||||
|
+
|
||||||
|
+ if (path_size > 0) {
|
||||||
|
+ CopyMem(ImageLoad->DevicePath, path, path_size);
|
||||||
|
+ ImageLoad->LengthOfDevicePath = path_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ efi_status = tpm_log_event_raw(buf, size, pcr, (CHAR8 *)ImageLoad,
|
||||||
|
+ sizeof(*ImageLoad) + path_size,
|
||||||
|
+ EV_EFI_BOOT_SERVICES_APPLICATION,
|
||||||
|
+ sha1hash);
|
||||||
|
+ FreePool(ImageLoad);
|
||||||
|
+
|
||||||
|
+ return efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
diff --git a/include/tpm.h b/include/tpm.h
|
||||||
|
index 746e871ff22..a05c24949e5 100644
|
||||||
|
--- a/include/tpm.h
|
||||||
|
+++ b/include/tpm.h
|
||||||
|
@@ -10,8 +10,9 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
|
||||||
|
const CHAR8 *description);
|
||||||
|
EFI_STATUS fallback_should_prefer_reset(void);
|
||||||
|
|
||||||
|
-EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 *sha1hash,
|
||||||
|
- UINT8 pcr);
|
||||||
|
+EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
+ EFI_PHYSICAL_ADDRESS addr, EFI_DEVICE_PATH *path,
|
||||||
|
+ UINT8 *sha1hash, UINT8 pcr);
|
||||||
|
|
||||||
|
EFI_STATUS tpm_measure_variable(CHAR16 *dbname, EFI_GUID guid, UINTN size, void *data);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
27
SOURCES/0047-Fix-the-license-on-our-buildid-extractor.patch
Normal file
27
SOURCES/0047-Fix-the-license-on-our-buildid-extractor.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From dce3659ac3d14ed338cdb37798a429751898c078 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Apr 2020 18:55:34 -0400
|
||||||
|
Subject: [PATCH 47/62] Fix the license on our buildid extractor.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 71439f848f6
|
||||||
|
---
|
||||||
|
buildid.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/buildid.c b/buildid.c
|
||||||
|
index f213f3bc921..6b414cdcffb 100644
|
||||||
|
--- a/buildid.c
|
||||||
|
+++ b/buildid.c
|
||||||
|
@@ -1,8 +1,6 @@
|
||||||
|
/*
|
||||||
|
* Walk a list of input files, printing the name and buildid of any file
|
||||||
|
* that has one.
|
||||||
|
- *
|
||||||
|
- * This program is licensed under the GNU Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
27
SOURCES/0048-Update-README.tpm.patch
Normal file
27
SOURCES/0048-Update-README.tpm.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 633169fe3291c832236ca1074fc679852f9caee1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: noahbliss <noah@superuser.sh>
|
||||||
|
Date: Wed, 4 Mar 2020 19:46:28 -0500
|
||||||
|
Subject: [PATCH 48/62] Update README.tpm
|
||||||
|
|
||||||
|
typo
|
||||||
|
Upstream-commit-id: bc24c9eb1d4
|
||||||
|
---
|
||||||
|
README.tpm | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/README.tpm b/README.tpm
|
||||||
|
index d9c7c53483b..c060dbe22db 100644
|
||||||
|
--- a/README.tpm
|
||||||
|
+++ b/README.tpm
|
||||||
|
@@ -25,7 +25,7 @@ PCR8:
|
||||||
|
measured into PCR8.
|
||||||
|
|
||||||
|
PCR9:
|
||||||
|
-- If you're using the grub2 TPM patchset we cary in Fedora, the kernel,
|
||||||
|
+- If you're using the grub2 TPM patchset we carry in Fedora, the kernel,
|
||||||
|
initramfs, and any multiboot modules loaded are measured into PCR9.
|
||||||
|
|
||||||
|
PCR14:
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From 9a209af5d84f4015ec399e1d1fa9dab31ef4d2b7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Frauendorfer | Miray Software <tf@miray.de>
|
||||||
|
Date: Wed, 25 Mar 2020 09:19:19 +0100
|
||||||
|
Subject: [PATCH 49/62] Check PxeReplyReceived as fallback in netboot
|
||||||
|
|
||||||
|
Some mainboards do not update the ProxyOffset dhcp information when using
|
||||||
|
proxy dhcp and boot menus.
|
||||||
|
This adds a fallback to check the PxeReply field if no boot information is
|
||||||
|
found in the v4 dhcp or proxy dhcp information
|
||||||
|
|
||||||
|
Upstream-commit-id: cc7ebe0f9f4
|
||||||
|
---
|
||||||
|
netboot.c | 15 ++++++++++++---
|
||||||
|
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||||
|
mode change 100644 => 100755 netboot.c
|
||||||
|
|
||||||
|
diff --git a/netboot.c b/netboot.c
|
||||||
|
old mode 100644
|
||||||
|
new mode 100755
|
||||||
|
index 4922ef284b1..047dad3a760
|
||||||
|
--- a/netboot.c
|
||||||
|
+++ b/netboot.c
|
||||||
|
@@ -273,7 +273,16 @@ static EFI_STATUS parseDhcp4()
|
||||||
|
pkt_v4 = &pxe->Mode->ProxyOffer.Dhcpv4;
|
||||||
|
}
|
||||||
|
|
||||||
|
- INTN dir_len = strnlena(pkt_v4->BootpBootFile, 127);
|
||||||
|
+ if(pxe->Mode->PxeReplyReceived) {
|
||||||
|
+ /*
|
||||||
|
+ * If we have no bootinfo yet search for it in the PxeReply.
|
||||||
|
+ * Some mainboards run into this when the server uses boot menus
|
||||||
|
+ */
|
||||||
|
+ if(pkt_v4->BootpBootFile[0] == '\0' && pxe->Mode->PxeReply.Dhcpv4.BootpBootFile[0] != '\0')
|
||||||
|
+ pkt_v4 = &pxe->Mode->PxeReply.Dhcpv4;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ INTN dir_len = strnlena((CHAR8 *)pkt_v4->BootpBootFile, 127);
|
||||||
|
INTN i;
|
||||||
|
UINT8 *dir = pkt_v4->BootpBootFile;
|
||||||
|
|
||||||
|
@@ -289,7 +298,7 @@ static EFI_STATUS parseDhcp4()
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
|
if (dir_len > 0) {
|
||||||
|
- strncpya(full_path, dir, dir_len);
|
||||||
|
+ strncpya(full_path, (CHAR8 *)dir, dir_len);
|
||||||
|
if (full_path[dir_len-1] == '/' && template[0] == '/')
|
||||||
|
full_path[dir_len-1] = '\0';
|
||||||
|
}
|
||||||
|
@@ -340,7 +349,7 @@ EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *buf
|
||||||
|
|
||||||
|
try_again:
|
||||||
|
efi_status = pxe->Mtftp(pxe, read, *buffer, overwrite, bufsiz, &blksz,
|
||||||
|
- &tftp_addr, full_path, NULL, nobuffer);
|
||||||
|
+ &tftp_addr, (UINT8 *)full_path, NULL, nobuffer);
|
||||||
|
if (efi_status == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
/* try again, doubling buf size */
|
||||||
|
*bufsiz *= 2;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From e8a04c1d84d2ebd0dbdf7bda26d7a22017100586 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 9 Jul 2020 00:24:57 -0400
|
||||||
|
Subject: [PATCH 50/62] Remove a couple of incorrect license claims.
|
||||||
|
|
||||||
|
A certain someone's default editor template leaked in to a couple of
|
||||||
|
source files, and claims they're GPL licensed. They're not.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream-commit-id: 476cbff1110
|
||||||
|
---
|
||||||
|
errlog.c | 3 ---
|
||||||
|
mok.c | 2 --
|
||||||
|
2 files changed, 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/errlog.c b/errlog.c
|
||||||
|
index eebb266d396..6669c800233 100644
|
||||||
|
--- a/errlog.c
|
||||||
|
+++ b/errlog.c
|
||||||
|
@@ -1,10 +1,7 @@
|
||||||
|
/*
|
||||||
|
* errlog.c
|
||||||
|
* Copyright 2017 Peter Jones <pjones@redhat.com>
|
||||||
|
- *
|
||||||
|
- * Distributed under terms of the GPLv3 license.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
#include "shim.h"
|
||||||
|
|
||||||
|
static CHAR16 **errs = NULL;
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index 59630e74425..089ea6bfc9a 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -1,8 +1,6 @@
|
||||||
|
/*
|
||||||
|
* mok.c
|
||||||
|
* Copyright 2017 Peter Jones <pjones@redhat.com>
|
||||||
|
- *
|
||||||
|
- * Distributed under terms of the GPLv3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shim.h"
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
27
SOURCES/0051-MokManager-fix-uninitialized-value.patch
Normal file
27
SOURCES/0051-MokManager-fix-uninitialized-value.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 7b77bee7966a1aa5f00a9b34aeb7e550bfa47be1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Wed, 22 Jul 2020 23:53:09 -0400
|
||||||
|
Subject: [PATCH 51/62] MokManager: fix uninitialized value
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#212
|
||||||
|
---
|
||||||
|
MokManager.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index fa73e2fd865..654a115033c 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -1431,7 +1431,7 @@ static CHAR16 get_password_charater(CHAR16 * prompt)
|
||||||
|
SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
CHAR16 *message[2];
|
||||||
|
- CHAR16 character;
|
||||||
|
+ CHAR16 character = 0;
|
||||||
|
UINTN length;
|
||||||
|
UINT32 pw_length;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
41
SOURCES/0052-Fix-some-volatile-usage-gcc-whines-about.patch
Normal file
41
SOURCES/0052-Fix-some-volatile-usage-gcc-whines-about.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From d3b7dc54cdac474a57b67cf9bcdb15bcb131d06c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 16:18:52 -0400
|
||||||
|
Subject: [PATCH 52/62] Fix some volatile usage gcc whines about.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#212
|
||||||
|
---
|
||||||
|
fallback.c | 2 +-
|
||||||
|
shim.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fallback.c b/fallback.c
|
||||||
|
index c3f5583c626..5a4bfff0793 100644
|
||||||
|
--- a/fallback.c
|
||||||
|
+++ b/fallback.c
|
||||||
|
@@ -983,7 +983,7 @@ debug_hook(void)
|
||||||
|
UINT8 *data = NULL;
|
||||||
|
UINTN dataSize = 0;
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
- volatile register int x = 0;
|
||||||
|
+ register volatile int x = 0;
|
||||||
|
extern char _etext, _edata;
|
||||||
|
|
||||||
|
efi_status = get_variable(L"SHIM_DEBUG", &data, &dataSize,
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index b35b0ad90cc..0e7e784b4c8 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -2559,7 +2559,7 @@ debug_hook(void)
|
||||||
|
UINT8 *data = NULL;
|
||||||
|
UINTN dataSize = 0;
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
- volatile register UINTN x = 0;
|
||||||
|
+ register volatile UINTN x = 0;
|
||||||
|
extern char _text, _data;
|
||||||
|
|
||||||
|
if (x)
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 6df96cdb20b84b33027d2e40bc0dbe0676d31282 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 19:01:27 -0400
|
||||||
|
Subject: [PATCH 53/62] MokManager: fix a wrong allocation failure check.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#212
|
||||||
|
---
|
||||||
|
MokManager.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/MokManager.c b/MokManager.c
|
||||||
|
index 654a115033c..c9949e33bcf 100644
|
||||||
|
--- a/MokManager.c
|
||||||
|
+++ b/MokManager.c
|
||||||
|
@@ -1085,9 +1085,11 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||||
|
DataSize += sizeof(EFI_GUID);
|
||||||
|
DataSize += list[i].MokSize;
|
||||||
|
}
|
||||||
|
+ if (DataSize == 0)
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
|
||||||
|
Data = AllocatePool(DataSize);
|
||||||
|
- if (Data == NULL && DataSize != 0)
|
||||||
|
+ if (Data == NULL)
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
|
||||||
|
ptr = Data;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From c186bdddaa7b103aef9d4a164ac0a07499dba112 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Wed, 22 Jul 2020 23:55:44 -0400
|
||||||
|
Subject: [PATCH 54/62] simple_file: fix uninitialized variable/unchecked
|
||||||
|
return
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#212
|
||||||
|
---
|
||||||
|
lib/simple_file.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/simple_file.c b/lib/simple_file.c
|
||||||
|
index 3bf92ed8e0f..6ad31b4dc04 100644
|
||||||
|
--- a/lib/simple_file.c
|
||||||
|
+++ b/lib/simple_file.c
|
||||||
|
@@ -403,10 +403,10 @@ simple_file_selector(EFI_HANDLE * im, CHAR16 ** title, CHAR16 * name,
|
||||||
|
filter = L"";
|
||||||
|
if (!*im) {
|
||||||
|
EFI_HANDLE h;
|
||||||
|
- CHAR16 *volname;
|
||||||
|
+ CHAR16 *volname = NULL;
|
||||||
|
|
||||||
|
- simple_volume_selector(title, &volname, &h);
|
||||||
|
- if (!volname)
|
||||||
|
+ efi_status = simple_volume_selector(title, &volname, &h);
|
||||||
|
+ if (EFI_ERROR(efi_status) || !volname)
|
||||||
|
return;
|
||||||
|
FreePool(volname);
|
||||||
|
*im = h;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
27
SOURCES/0055-Fix-a-broken-tpm-type.patch
Normal file
27
SOURCES/0055-Fix-a-broken-tpm-type.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From a7f9911b776f3cdc12e42bf5990ddef0b08d3701 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 20:35:56 -0400
|
||||||
|
Subject: [PATCH 55/62] Fix a broken tpm type
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#212
|
||||||
|
---
|
||||||
|
tpm.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tpm.c b/tpm.c
|
||||||
|
index 22ad148b35a..03cf3a1f60e 100644
|
||||||
|
--- a/tpm.c
|
||||||
|
+++ b/tpm.c
|
||||||
|
@@ -239,7 +239,7 @@ EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size,
|
||||||
|
efi_status = tpm_log_event_raw(buf, size, pcr, (CHAR8 *)ImageLoad,
|
||||||
|
sizeof(*ImageLoad) + path_size,
|
||||||
|
EV_EFI_BOOT_SERVICES_APPLICATION,
|
||||||
|
- sha1hash);
|
||||||
|
+ (CHAR8 *)sha1hash);
|
||||||
|
FreePool(ImageLoad);
|
||||||
|
|
||||||
|
return efi_status;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
279
SOURCES/0056-Make-cert.S-not-impossible-to-read.patch
Normal file
279
SOURCES/0056-Make-cert.S-not-impossible-to-read.patch
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
From 7d542805ba5c48185128a2351bb315a5648fe3d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 00:08:30 -0400
|
||||||
|
Subject: [PATCH 56/62] Make cert.S not impossible to read.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#206
|
||||||
|
---
|
||||||
|
shim.c | 47 +++++++++++++++++--------------
|
||||||
|
shim.h | 28 +++++++++++++++---
|
||||||
|
cert.S | 89 ++++++++++++++++++++++------------------------------------
|
||||||
|
3 files changed, 84 insertions(+), 80 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 0e7e784b4c8..888ee6e8d7b 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -68,16 +68,18 @@ static UINT32 load_options_size;
|
||||||
|
* The vendor certificate used for validating the second stage loader
|
||||||
|
*/
|
||||||
|
extern struct {
|
||||||
|
- UINT32 vendor_cert_size;
|
||||||
|
- UINT32 vendor_dbx_size;
|
||||||
|
- UINT32 vendor_cert_offset;
|
||||||
|
- UINT32 vendor_dbx_offset;
|
||||||
|
+ UINT32 vendor_authorized_size;
|
||||||
|
+ UINT32 vendor_deauthorized_size;
|
||||||
|
+ UINT32 vendor_authorized_offset;
|
||||||
|
+ UINT32 vendor_deauthorized_offset;
|
||||||
|
} cert_table;
|
||||||
|
|
||||||
|
-UINT32 vendor_cert_size;
|
||||||
|
-UINT32 vendor_dbx_size;
|
||||||
|
-UINT8 *vendor_cert;
|
||||||
|
-UINT8 *vendor_dbx;
|
||||||
|
+UINT32 vendor_authorized_size = 0;
|
||||||
|
+UINT8 *vendor_authorized = NULL;
|
||||||
|
+
|
||||||
|
+UINT32 vendor_deauthorized_size = 0;
|
||||||
|
+UINT8 *vendor_deauthorized = NULL;
|
||||||
|
+
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
UINT32 build_cert_size;
|
||||||
|
UINT8 *build_cert;
|
||||||
|
@@ -554,22 +556,22 @@ static CHECK_STATUS check_db_hash(CHAR16 *dbname, EFI_GUID guid, UINT8 *data,
|
||||||
|
static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
UINT8 *sha256hash, UINT8 *sha1hash)
|
||||||
|
{
|
||||||
|
- EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_dbx;
|
||||||
|
+ EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_deauthorized;
|
||||||
|
|
||||||
|
- if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha256hash,
|
||||||
|
+ if (check_db_hash_in_ram(dbx, vendor_deauthorized_size, sha256hash,
|
||||||
|
SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID, L"dbx",
|
||||||
|
EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
|
||||||
|
LogError(L"binary sha256hash found in vendor dbx\n");
|
||||||
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
}
|
||||||
|
- if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha1hash,
|
||||||
|
+ if (check_db_hash_in_ram(dbx, vendor_deauthorized_size, sha1hash,
|
||||||
|
SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID, L"dbx",
|
||||||
|
EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
|
||||||
|
LogError(L"binary sha1hash found in vendor dbx\n");
|
||||||
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
}
|
||||||
|
if (cert &&
|
||||||
|
- check_db_cert_in_ram(dbx, vendor_dbx_size, cert, sha256hash, L"dbx",
|
||||||
|
+ check_db_cert_in_ram(dbx, vendor_deauthorized_size, cert, sha256hash, L"dbx",
|
||||||
|
EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
|
||||||
|
LogError(L"cert sha256hash found in vendor dbx\n");
|
||||||
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
@@ -1077,19 +1079,19 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
/*
|
||||||
|
* And finally, check against shim's built-in key
|
||||||
|
*/
|
||||||
|
- if (vendor_cert_size &&
|
||||||
|
+ if (vendor_authorized_size &&
|
||||||
|
AuthenticodeVerify(cert->CertData,
|
||||||
|
cert->Hdr.dwLength - sizeof(cert->Hdr),
|
||||||
|
- vendor_cert, vendor_cert_size,
|
||||||
|
+ vendor_authorized, vendor_authorized_size,
|
||||||
|
sha256hash, SHA256_DIGEST_SIZE)) {
|
||||||
|
update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
|
||||||
|
- vendor_cert_size, vendor_cert);
|
||||||
|
+ vendor_authorized_size, vendor_authorized);
|
||||||
|
efi_status = EFI_SUCCESS;
|
||||||
|
drain_openssl_errors();
|
||||||
|
return efi_status;
|
||||||
|
} else {
|
||||||
|
- LogError(L"AuthenticodeVerify(vendor_cert) failed\n");
|
||||||
|
+ LogError(L"AuthenticodeVerify(vendor_authorized) failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2501,7 +2503,7 @@ shim_init(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secure_mode()) {
|
||||||
|
- if (vendor_cert_size || vendor_dbx_size) {
|
||||||
|
+ if (vendor_authorized_size || vendor_deauthorized_size) {
|
||||||
|
/*
|
||||||
|
* If shim includes its own certificates then ensure
|
||||||
|
* that anything it boots has performed some
|
||||||
|
@@ -2606,14 +2608,17 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
|
||||||
|
verification_method = VERIFIED_BY_NOTHING;
|
||||||
|
|
||||||
|
- vendor_cert_size = cert_table.vendor_cert_size;
|
||||||
|
- vendor_dbx_size = cert_table.vendor_dbx_size;
|
||||||
|
- vendor_cert = (UINT8 *)&cert_table + cert_table.vendor_cert_offset;
|
||||||
|
- vendor_dbx = (UINT8 *)&cert_table + cert_table.vendor_dbx_offset;
|
||||||
|
+ vendor_authorized_size = cert_table.vendor_authorized_size;
|
||||||
|
+ vendor_authorized = (UINT8 *)&cert_table + cert_table.vendor_authorized_offset;
|
||||||
|
+
|
||||||
|
+ vendor_deauthorized_size = cert_table.vendor_deauthorized_size;
|
||||||
|
+ vendor_deauthorized = (UINT8 *)&cert_table + cert_table.vendor_deauthorized_offset;
|
||||||
|
+
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
build_cert_size = sizeof(shim_cert);
|
||||||
|
build_cert = shim_cert;
|
||||||
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
CHAR16 *msgs[] = {
|
||||||
|
L"import_mok_state() failed",
|
||||||
|
L"shim_init() failed",
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index a0fa5a75e7e..555498c6673 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -97,6 +97,24 @@
|
||||||
|
#define FALLBACK L"\\fb" EFI_ARCH L".efi"
|
||||||
|
#define MOK_MANAGER L"\\mm" EFI_ARCH L".efi"
|
||||||
|
|
||||||
|
+#if defined(VENDOR_CERT_FILE)
|
||||||
|
+# define vendor_authorized vendor_cert
|
||||||
|
+# define vendor_authorized_size vendor_cert_size
|
||||||
|
+# define vendor_authorized_category VENDOR_ADDEND_X509
|
||||||
|
+#else
|
||||||
|
+# define vendor_authorized vendor_null
|
||||||
|
+# define vendor_authorized_size vendor_null_size
|
||||||
|
+# define vendor_authorized_category VENDOR_ADDEND_NONE
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(VENDOR_DBX_FILE)
|
||||||
|
+# define vendor_deauthorized vendor_dbx
|
||||||
|
+# define vendor_deauthorized_size vendor_dbx_size
|
||||||
|
+#else
|
||||||
|
+# define vendor_deauthorized vendor_deauthorized_null
|
||||||
|
+# define vendor_deauthorized_size vendor_deauthorized_null_size
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include "include/asm.h"
|
||||||
|
#include "include/configtable.h"
|
||||||
|
#include "include/console.h"
|
||||||
|
@@ -166,10 +184,12 @@ extern VOID ClearErrors(VOID);
|
||||||
|
extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath);
|
||||||
|
extern EFI_STATUS import_mok_state(EFI_HANDLE image_handle);
|
||||||
|
|
||||||
|
-extern UINT32 vendor_cert_size;
|
||||||
|
-extern UINT32 vendor_dbx_size;
|
||||||
|
-extern UINT8 *vendor_cert;
|
||||||
|
-extern UINT8 *vendor_dbx;
|
||||||
|
+extern UINT32 vendor_authorized_size;
|
||||||
|
+extern UINT8 *vendor_authorized;
|
||||||
|
+
|
||||||
|
+extern UINT32 vendor_deauthorized_size;
|
||||||
|
+extern UINT8 *vendor_deauthorized;
|
||||||
|
+
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
extern UINT32 build_cert_size;
|
||||||
|
extern UINT8 *build_cert;
|
||||||
|
diff --git a/cert.S b/cert.S
|
||||||
|
index cfc4525b44c..520caaef3af 100644
|
||||||
|
--- a/cert.S
|
||||||
|
+++ b/cert.S
|
||||||
|
@@ -1,65 +1,44 @@
|
||||||
|
+
|
||||||
|
+#if defined(VENDOR_CERT_FILE)
|
||||||
|
+# define vendor_authorized vendor_cert
|
||||||
|
+# define vendor_authorized_end vendor_cert_end
|
||||||
|
+# define vendor_authorized_size vendor_cert_size
|
||||||
|
+# define vendor_authorized_size_end vendor_cert_size_end
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(VENDOR_DBX_FILE)
|
||||||
|
+# define vendor_deauthorized vendor_dbx
|
||||||
|
+# define vendor_deauthorized_end vendor_dbx_end
|
||||||
|
+# define vendor_deauthorized_size vendor_dbx_size
|
||||||
|
+# define vendor_deauthorized_size_end vendor_dbx_size_end
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
.globl cert_table
|
||||||
|
.type cert_table, %object
|
||||||
|
- .size cert_table, 4
|
||||||
|
+ .size cert_table, .Lcert_table_end - cert_table
|
||||||
|
.section .vendor_cert, "a", %progbits
|
||||||
|
+ .balignl 4, 0
|
||||||
|
cert_table:
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
- .long vendor_cert_priv_end - vendor_cert_priv
|
||||||
|
-#else
|
||||||
|
- .long 0
|
||||||
|
-#endif
|
||||||
|
-#if defined(VENDOR_DBX_FILE)
|
||||||
|
- .long vendor_dbx_priv_end - vendor_dbx_priv
|
||||||
|
-#else
|
||||||
|
- .long 0
|
||||||
|
-#endif
|
||||||
|
- .long vendor_cert_priv - cert_table
|
||||||
|
- .long vendor_dbx_priv - cert_table
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
- .data
|
||||||
|
- .align 1
|
||||||
|
- .type vendor_cert_priv, %object
|
||||||
|
- .size vendor_cert_priv, vendor_cert_priv_end-vendor_cert_priv
|
||||||
|
+ .4byte .Lvendor_authorized_end - vendor_authorized
|
||||||
|
+ .4byte .Lvendor_deauthorized_end - vendor_deauthorized
|
||||||
|
+ .4byte vendor_authorized - cert_table
|
||||||
|
+ .4byte vendor_deauthorized - cert_table
|
||||||
|
+ .balign 1, 0
|
||||||
|
+ .type vendor_authorized, %object
|
||||||
|
+ .size vendor_authorized, .Lvendor_authorized_end - vendor_authorized
|
||||||
|
.section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_cert_priv:
|
||||||
|
+vendor_authorized:
|
||||||
|
+#if defined(VENDOR_CERT_FILE)
|
||||||
|
.incbin VENDOR_CERT_FILE
|
||||||
|
-vendor_cert_priv_end:
|
||||||
|
-#else
|
||||||
|
- .bss
|
||||||
|
- .type vendor_cert_priv, %object
|
||||||
|
- .size vendor_cert_priv, 1
|
||||||
|
- .section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_cert_priv:
|
||||||
|
- .zero 1
|
||||||
|
-
|
||||||
|
- .data
|
||||||
|
- .align 4
|
||||||
|
- .type vendor_cert_size_priv, %object
|
||||||
|
- .size vendor_cert_size_priv, 4
|
||||||
|
- .section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_cert_priv_end:
|
||||||
|
#endif
|
||||||
|
+.Lvendor_authorized_end:
|
||||||
|
+ .balign 1, 0
|
||||||
|
+ .type vendor_deauthorized, %object
|
||||||
|
+ .size vendor_deauthorized, .Lvendor_deauthorized_end - vendor_deauthorized
|
||||||
|
+ .section .vendor_cert, "a", %progbits
|
||||||
|
+vendor_deauthorized:
|
||||||
|
#if defined(VENDOR_DBX_FILE)
|
||||||
|
- .data
|
||||||
|
- .align 1
|
||||||
|
- .type vendor_dbx_priv, %object
|
||||||
|
- .size vendor_dbx_priv, vendor_dbx_priv_end-vendor_dbx_priv
|
||||||
|
- .section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_dbx_priv:
|
||||||
|
.incbin VENDOR_DBX_FILE
|
||||||
|
-vendor_dbx_priv_end:
|
||||||
|
-#else
|
||||||
|
- .bss
|
||||||
|
- .type vendor_dbx_priv, %object
|
||||||
|
- .size vendor_dbx_priv, 1
|
||||||
|
- .section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_dbx_priv:
|
||||||
|
- .zero 1
|
||||||
|
-
|
||||||
|
- .data
|
||||||
|
- .align 4
|
||||||
|
- .type vendor_dbx_size_priv, %object
|
||||||
|
- .size vendor_dbx_size_priv, 4
|
||||||
|
- .section .vendor_cert, "a", %progbits
|
||||||
|
-vendor_dbx_priv_end:
|
||||||
|
#endif
|
||||||
|
+.Lvendor_deauthorized_end:
|
||||||
|
+.Lcert_table_end:
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,943 @@
|
|||||||
|
From dd3a5d71252a1f94e37f1a4c8841d253630b305a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 12:36:56 -0400
|
||||||
|
Subject: [PATCH 57/62] Add support for vendor_db built-in shim authorized
|
||||||
|
list.
|
||||||
|
|
||||||
|
Potential new signing strategies ( for example signing grub, fwupdate
|
||||||
|
and vmlinuz with separate certificates ) require shim to support a
|
||||||
|
vendor provided bundle of trusted certificates and hashes, which allows
|
||||||
|
shim to trust EFI binaries matching either certificate by signature or
|
||||||
|
hash in the vendor_db. Functionality is similar to vendor_dbx.
|
||||||
|
|
||||||
|
This also improves the mirroring quite a bit.
|
||||||
|
Upstream: pr#206
|
||||||
|
---
|
||||||
|
lib/variables.c | 55 +++--
|
||||||
|
mok.c | 502 ++++++++++++++++++++++++++++++--------------
|
||||||
|
shim.c | 27 +++
|
||||||
|
include/console.h | 3 +-
|
||||||
|
include/variables.h | 9 +-
|
||||||
|
shim.h | 7 +-
|
||||||
|
cert.S | 13 +-
|
||||||
|
Make.defaults | 3 +
|
||||||
|
README.tpm | 1 +
|
||||||
|
9 files changed, 437 insertions(+), 183 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/variables.c b/lib/variables.c
|
||||||
|
index 9c2e7d0ac2d..8123ae60fc9 100644
|
||||||
|
--- a/lib/variables.c
|
||||||
|
+++ b/lib/variables.c
|
||||||
|
@@ -25,32 +25,59 @@
|
||||||
|
#include "shim.h"
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
-variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
|
||||||
|
- void **out, int *outlen)
|
||||||
|
+fill_esl(const uint8_t *data, const size_t data_len,
|
||||||
|
+ const EFI_GUID *type, const EFI_GUID *owner,
|
||||||
|
+ uint8_t *out, size_t *outlen)
|
||||||
|
{
|
||||||
|
- *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
|
||||||
|
+ EFI_SIGNATURE_LIST *sl;
|
||||||
|
+ EFI_SIGNATURE_DATA *sd;
|
||||||
|
+ size_t needed = 0;
|
||||||
|
|
||||||
|
- *out = AllocateZeroPool(*outlen);
|
||||||
|
- if (!*out)
|
||||||
|
- return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ if (!data || !data_len || !type || !outlen)
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
- EFI_SIGNATURE_LIST *sl = *out;
|
||||||
|
+ needed = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) + data_len;
|
||||||
|
+ if (!out || *outlen < needed) {
|
||||||
|
+ *outlen = needed;
|
||||||
|
+ return EFI_BUFFER_TOO_SMALL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *outlen = needed;
|
||||||
|
+ sl = (EFI_SIGNATURE_LIST *)out;
|
||||||
|
|
||||||
|
sl->SignatureHeaderSize = 0;
|
||||||
|
sl->SignatureType = *type;
|
||||||
|
- sl->SignatureSize = cert_len + sizeof(EFI_GUID);
|
||||||
|
- sl->SignatureListSize = *outlen;
|
||||||
|
-
|
||||||
|
- EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST);
|
||||||
|
+ sl->SignatureSize = sizeof(EFI_GUID) + data_len;
|
||||||
|
+ sl->SignatureListSize = needed;
|
||||||
|
|
||||||
|
+ sd = (EFI_SIGNATURE_DATA *)(out + sizeof(EFI_SIGNATURE_LIST));
|
||||||
|
if (owner)
|
||||||
|
sd->SignatureOwner = *owner;
|
||||||
|
|
||||||
|
- CopyMem(sd->SignatureData, cert, cert_len);
|
||||||
|
+ CopyMem(sd->SignatureData, data, data_len);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+EFI_STATUS
|
||||||
|
+variable_create_esl(const uint8_t *data, const size_t data_len,
|
||||||
|
+ const EFI_GUID *type, const EFI_GUID *owner,
|
||||||
|
+ uint8_t **out, size_t *outlen)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+
|
||||||
|
+ *outlen = 0;
|
||||||
|
+ efi_status = fill_esl(data, data_len, type, owner, NULL, outlen);
|
||||||
|
+ if (efi_status != EFI_BUFFER_TOO_SMALL)
|
||||||
|
+ return efi_status;
|
||||||
|
+
|
||||||
|
+ *out = AllocateZeroPool(*outlen);
|
||||||
|
+ if (!*out)
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+
|
||||||
|
+ return fill_esl(data, data_len, type, owner, *out, outlen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
EFI_STATUS
|
||||||
|
CreateTimeBasedPayload(IN OUT UINTN * DataSize, IN OUT UINT8 ** Data)
|
||||||
|
{
|
||||||
|
@@ -137,9 +164,9 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
|
||||||
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
|
||||||
|
if (createtimebased) {
|
||||||
|
- int ds;
|
||||||
|
+ size_t ds;
|
||||||
|
efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
|
||||||
|
- (void **)&Cert, &ds);
|
||||||
|
+ (uint8_t **)&Cert, &ds);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
console_print(L"Failed to create %s certificate %d\n",
|
||||||
|
var, efi_status);
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index 089ea6bfc9a..e69857f3c37 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -5,6 +5,8 @@
|
||||||
|
|
||||||
|
#include "shim.h"
|
||||||
|
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Check if a variable exists
|
||||||
|
*/
|
||||||
|
@@ -47,6 +49,15 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef enum {
|
||||||
|
+ VENDOR_ADDEND_DB,
|
||||||
|
+ VENDOR_ADDEND_X509,
|
||||||
|
+ VENDOR_ADDEND_NONE,
|
||||||
|
+} vendor_addend_category_t;
|
||||||
|
+
|
||||||
|
+struct mok_state_variable;
|
||||||
|
+typedef vendor_addend_category_t (vendor_addend_categorizer_t)(struct mok_state_variable *);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* MoK variables that need to have their storage validated.
|
||||||
|
*
|
||||||
|
@@ -58,18 +69,20 @@ struct mok_state_variable {
|
||||||
|
char *name8;
|
||||||
|
CHAR16 *rtname;
|
||||||
|
EFI_GUID *guid;
|
||||||
|
+
|
||||||
|
UINT8 *data;
|
||||||
|
UINTN data_size;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
- * These two are indirect pointers just to make initialization
|
||||||
|
- * saner...
|
||||||
|
+ * These are indirect pointers just to make initialization saner...
|
||||||
|
*/
|
||||||
|
- UINT8 **addend_source;
|
||||||
|
+ vendor_addend_categorizer_t *categorize_addend;
|
||||||
|
+ UINT8 **addend;
|
||||||
|
UINT32 *addend_size;
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+
|
||||||
|
UINT8 **build_cert;
|
||||||
|
UINT32 *build_cert_size;
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
UINT32 yes_attr;
|
||||||
|
UINT32 no_attr;
|
||||||
|
UINT32 flags;
|
||||||
|
@@ -77,6 +90,28 @@ struct mok_state_variable {
|
||||||
|
UINT8 *state;
|
||||||
|
};
|
||||||
|
|
||||||
|
+static vendor_addend_category_t
|
||||||
|
+categorize_authorized(struct mok_state_variable *v)
|
||||||
|
+{
|
||||||
|
+ if (!(v->addend && v->addend_size &&
|
||||||
|
+ *v->addend && *v->addend_size)) {
|
||||||
|
+ return VENDOR_ADDEND_NONE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return vendor_authorized_category;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static vendor_addend_category_t
|
||||||
|
+categorize_deauthorized(struct mok_state_variable *v)
|
||||||
|
+{
|
||||||
|
+ if (!(v->addend && v->addend_size &&
|
||||||
|
+ *v->addend && *v->addend_size)) {
|
||||||
|
+ return VENDOR_ADDEND_NONE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return VENDOR_ADDEND_DB;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#define MOK_MIRROR_KEYDB 0x01
|
||||||
|
#define MOK_MIRROR_DELETE_FIRST 0x02
|
||||||
|
#define MOK_VARIABLE_MEASURE 0x04
|
||||||
|
@@ -90,8 +125,9 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
.no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
- .addend_source = &vendor_cert,
|
||||||
|
- .addend_size = &vendor_cert_size,
|
||||||
|
+ .categorize_addend = categorize_authorized,
|
||||||
|
+ .addend = &vendor_authorized,
|
||||||
|
+ .addend_size = &vendor_authorized_size,
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
.build_cert = &build_cert,
|
||||||
|
.build_cert_size = &build_cert_size,
|
||||||
|
@@ -107,6 +143,9 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
.no_attr = EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ .categorize_addend = categorize_deauthorized,
|
||||||
|
+ .addend = &vendor_deauthorized,
|
||||||
|
+ .addend_size = &vendor_deauthorized_size,
|
||||||
|
.flags = MOK_MIRROR_KEYDB |
|
||||||
|
MOK_VARIABLE_LOG,
|
||||||
|
.pcr = 14,
|
||||||
|
@@ -136,123 +175,253 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
{ NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
-static inline BOOLEAN nonnull(1)
|
||||||
|
-check_vendor_cert(struct mok_state_variable *v)
|
||||||
|
-{
|
||||||
|
- return (v->addend_source && v->addend_size &&
|
||||||
|
- *v->addend_source && *v->addend_size) ? TRUE : FALSE;
|
||||||
|
-}
|
||||||
|
+#define should_mirror_addend(v) (((v)->categorize_addend) && ((v)->categorize_addend(v) != VENDOR_ADDEND_NONE))
|
||||||
|
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
static inline BOOLEAN nonnull(1)
|
||||||
|
-check_build_cert(struct mok_state_variable *v)
|
||||||
|
+should_mirror_build_cert(struct mok_state_variable *v)
|
||||||
|
{
|
||||||
|
return (v->build_cert && v->build_cert_size &&
|
||||||
|
*v->build_cert && *v->build_cert_size) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
-#define check_addend(v) (check_vendor_cert(v) || check_build_cert(v))
|
||||||
|
-#else
|
||||||
|
-#define check_addend(v) check_vendor_cert(v)
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
+static const uint8_t null_sha256[32] = { 0, };
|
||||||
|
|
||||||
|
static EFI_STATUS nonnull(1)
|
||||||
|
mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status = EFI_SUCCESS;
|
||||||
|
- void *FullData = NULL;
|
||||||
|
- UINTN FullDataSize = 0;
|
||||||
|
+ uint8_t *FullData = NULL;
|
||||||
|
+ size_t FullDataSize = 0;
|
||||||
|
+ vendor_addend_category_t addend_category = VENDOR_ADDEND_NONE;
|
||||||
|
uint8_t *p = NULL;
|
||||||
|
|
||||||
|
- if ((v->flags & MOK_MIRROR_KEYDB) && check_addend(v)) {
|
||||||
|
- EFI_SIGNATURE_LIST *CertList = NULL;
|
||||||
|
- EFI_SIGNATURE_DATA *CertData = NULL;
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
- FullDataSize = v->data_size;
|
||||||
|
- if (check_build_cert(v)) {
|
||||||
|
- FullDataSize += sizeof (*CertList)
|
||||||
|
- + sizeof (EFI_GUID)
|
||||||
|
- + *v->build_cert_size;
|
||||||
|
- }
|
||||||
|
- if (check_vendor_cert(v)) {
|
||||||
|
- FullDataSize += sizeof (*CertList)
|
||||||
|
- + sizeof (EFI_GUID)
|
||||||
|
- + *v->addend_size;
|
||||||
|
- }
|
||||||
|
-#else
|
||||||
|
- FullDataSize = v->data_size
|
||||||
|
- + sizeof (*CertList)
|
||||||
|
- + sizeof (EFI_GUID)
|
||||||
|
- + *v->addend_size;
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
- FullData = AllocatePool(FullDataSize);
|
||||||
|
- if (!FullData) {
|
||||||
|
- perror(L"Failed to allocate space for MokListRT\n");
|
||||||
|
- return EFI_OUT_OF_RESOURCES;
|
||||||
|
- }
|
||||||
|
- p = FullData;
|
||||||
|
+ size_t build_cert_esl_sz = 0, addend_esl_sz = 0;
|
||||||
|
|
||||||
|
- if (!EFI_ERROR(efi_status) && v->data_size > 0) {
|
||||||
|
- CopyMem(p, v->data, v->data_size);
|
||||||
|
- p += v->data_size;
|
||||||
|
- }
|
||||||
|
+ if (v->categorize_addend)
|
||||||
|
+ addend_category = v->categorize_addend(v);
|
||||||
|
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
- if (check_build_cert(v) == FALSE)
|
||||||
|
- goto skip_build_cert;
|
||||||
|
+ /*
|
||||||
|
+ * we're always mirroring the original data, whether this is an efi
|
||||||
|
+ * security database or not
|
||||||
|
+ */
|
||||||
|
+ dprint(L"v->data_size:%lu v->data:0x%08llx\n", v->data_size, v->data);
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n", FullDataSize, FullData);
|
||||||
|
+ if (v->data_size) {
|
||||||
|
+ FullDataSize = v->data_size;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- CertList = (EFI_SIGNATURE_LIST *)p;
|
||||||
|
- p += sizeof (*CertList);
|
||||||
|
- CertData = (EFI_SIGNATURE_DATA *)p;
|
||||||
|
- p += sizeof (EFI_GUID);
|
||||||
|
+ /*
|
||||||
|
+ * if it is, there's more data
|
||||||
|
+ */
|
||||||
|
+ if (v->flags & MOK_MIRROR_KEYDB) {
|
||||||
|
|
||||||
|
- CertList->SignatureType = EFI_CERT_TYPE_X509_GUID;
|
||||||
|
- CertList->SignatureListSize = *v->build_cert_size
|
||||||
|
- + sizeof (*CertList)
|
||||||
|
- + sizeof (*CertData)
|
||||||
|
- -1;
|
||||||
|
- CertList->SignatureHeaderSize = 0;
|
||||||
|
- CertList->SignatureSize = *v->build_cert_size +
|
||||||
|
- sizeof (EFI_GUID);
|
||||||
|
+ /*
|
||||||
|
+ * We're mirroring (into) an efi security database, aka an
|
||||||
|
+ * array of efi_signature_list_t. Its layout goes like:
|
||||||
|
+ *
|
||||||
|
+ * existing_variable_data
|
||||||
|
+ * existing_variable_data_size
|
||||||
|
+ * if flags & MOK_MIRROR_KEYDB
|
||||||
|
+ * if build_cert
|
||||||
|
+ * build_cert_esl
|
||||||
|
+ * build_cert_header (always sz=0)
|
||||||
|
+ * build_cert_esd[0] { owner, data }
|
||||||
|
+ * if addend==vendor_db
|
||||||
|
+ * for n=[1..N]
|
||||||
|
+ * vendor_db_esl_n
|
||||||
|
+ * vendor_db_header_n (always sz=0)
|
||||||
|
+ * vendor_db_esd_n[m] {{ owner, data }, ... }
|
||||||
|
+ * elif addend==vendor_cert
|
||||||
|
+ * vendor_cert_esl
|
||||||
|
+ * vendor_cert_header (always sz=0)
|
||||||
|
+ * vendor_cert_esd[1] { owner, data }
|
||||||
|
+ *
|
||||||
|
+ * first we determine the size of the variable, then alloc
|
||||||
|
+ * and add the data.
|
||||||
|
+ */
|
||||||
|
|
||||||
|
- CertData->SignatureOwner = SHIM_LOCK_GUID;
|
||||||
|
- CopyMem(p, *v->build_cert, *v->build_cert_size);
|
||||||
|
+ /*
|
||||||
|
+ * first bit is existing data, but we added that above
|
||||||
|
+ */
|
||||||
|
|
||||||
|
- p += *v->build_cert_size;
|
||||||
|
+ /*
|
||||||
|
+ * then the build cert if it's there
|
||||||
|
+ */
|
||||||
|
+ if (should_mirror_build_cert(v)) {
|
||||||
|
+ efi_status = fill_esl(*v->build_cert,
|
||||||
|
+ *v->build_cert_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ NULL, &build_cert_esl_sz);
|
||||||
|
+ if (efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ FullDataSize += build_cert_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (check_vendor_cert(v) == FALSE)
|
||||||
|
- goto skip_vendor_cert;
|
||||||
|
-skip_build_cert:
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+ /*
|
||||||
|
+ * then the addend data
|
||||||
|
+ */
|
||||||
|
+ switch (addend_category) {
|
||||||
|
+ case VENDOR_ADDEND_DB:
|
||||||
|
+ /*
|
||||||
|
+ * if it's an ESL already, we use it wholesale
|
||||||
|
+ */
|
||||||
|
+ FullDataSize += *v->addend_size;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ break;
|
||||||
|
+ case VENDOR_ADDEND_X509:
|
||||||
|
+ efi_status = fill_esl(*v->addend, *v->addend_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ NULL, &addend_esl_sz);
|
||||||
|
+ if (efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ FullDataSize += addend_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ case VENDOR_ADDEND_NONE:
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- CertList = (EFI_SIGNATURE_LIST *)p;
|
||||||
|
- p += sizeof (*CertList);
|
||||||
|
- CertData = (EFI_SIGNATURE_DATA *)p;
|
||||||
|
- p += sizeof (EFI_GUID);
|
||||||
|
+ /*
|
||||||
|
+ * Now we have the full size
|
||||||
|
+ */
|
||||||
|
+ if (FullDataSize) {
|
||||||
|
+ /*
|
||||||
|
+ * allocate the buffer, or use the old one if it's just the
|
||||||
|
+ * existing data.
|
||||||
|
+ */
|
||||||
|
+ if (FullDataSize != v->data_size) {
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx allocating FullData\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ FullData = AllocatePool(FullDataSize);
|
||||||
|
+ if (!FullData) {
|
||||||
|
+ FreePool(v->data);
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ perror(L"Failed to allocate %lu bytes for %s\n",
|
||||||
|
+ FullDataSize, v->name);
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ }
|
||||||
|
+ p = FullData;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ if (v->data && v->data_size) {
|
||||||
|
+ CopyMem(p, v->data, v->data_size);
|
||||||
|
+ p += v->data_size;
|
||||||
|
+ }
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ } else {
|
||||||
|
+ FullData = v->data;
|
||||||
|
+ FullDataSize = v->data_size;
|
||||||
|
+ p = FullData + FullDataSize;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
|
||||||
|
- CertList->SignatureType = EFI_CERT_TYPE_X509_GUID;
|
||||||
|
- CertList->SignatureListSize = *v->addend_size
|
||||||
|
- + sizeof (*CertList)
|
||||||
|
- + sizeof (*CertData)
|
||||||
|
- -1;
|
||||||
|
- CertList->SignatureHeaderSize = 0;
|
||||||
|
- CertList->SignatureSize = *v->addend_size + sizeof (EFI_GUID);
|
||||||
|
+ /*
|
||||||
|
+ * Now fill it.
|
||||||
|
+ */
|
||||||
|
+ if (v->flags & MOK_MIRROR_KEYDB) {
|
||||||
|
+ /*
|
||||||
|
+ * first bit is existing data, but again, we added that above
|
||||||
|
+ */
|
||||||
|
|
||||||
|
- CertData->SignatureOwner = SHIM_LOCK_GUID;
|
||||||
|
- CopyMem(p, *v->addend_source, *v->addend_size);
|
||||||
|
+ /*
|
||||||
|
+ * second is the build cert
|
||||||
|
+ */
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ if (should_mirror_build_cert(v)) {
|
||||||
|
+ efi_status = fill_esl(*v->build_cert,
|
||||||
|
+ *v->build_cert_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ p, &build_cert_esl_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ p += build_cert_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
-skip_vendor_cert:
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
- if (v->data && v->data_size)
|
||||||
|
- FreePool(v->data);
|
||||||
|
- v->data = FullData;
|
||||||
|
- v->data_size = FullDataSize;
|
||||||
|
- } else {
|
||||||
|
- FullDataSize = v->data_size;
|
||||||
|
- FullData = v->data;
|
||||||
|
+ switch (addend_category) {
|
||||||
|
+ case VENDOR_ADDEND_DB:
|
||||||
|
+ CopyMem(p, *v->addend, *v->addend_size);
|
||||||
|
+ p += *v->addend_size;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ break;
|
||||||
|
+ case VENDOR_ADDEND_X509:
|
||||||
|
+ efi_status = fill_esl(*v->addend, *v->addend_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ p, &addend_esl_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ p += addend_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ case VENDOR_ADDEND_NONE:
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ /*
|
||||||
|
+ * We always want to create our key databases, so in this case we
|
||||||
|
+ * need a dummy entry
|
||||||
|
+ */
|
||||||
|
+ if ((v->flags & MOK_MIRROR_KEYDB) && FullDataSize == 0) {
|
||||||
|
+ efi_status = variable_create_esl(
|
||||||
|
+ null_sha256, sizeof(null_sha256),
|
||||||
|
+ &EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
|
||||||
|
+ &FullData, &FullDataSize);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to allocate %lu bytes for %s\n",
|
||||||
|
+ FullDataSize, v->name);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ p = FullData + FullDataSize;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
if (FullDataSize) {
|
||||||
|
+ dprint(L"Setting %s with %lu bytes of data\n",
|
||||||
|
+ v->rtname, FullDataSize);
|
||||||
|
efi_status = gRT->SetVariable(v->rtname, v->guid,
|
||||||
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
@@ -262,7 +431,15 @@ skip_vendor_cert:
|
||||||
|
v->rtname, efi_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ if (v->data && v->data_size) {
|
||||||
|
+ FreePool(v->data);
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ }
|
||||||
|
+ if (FullData && FullDataSize) {
|
||||||
|
+ FreePool(FullData);
|
||||||
|
+ }
|
||||||
|
+ dprint(L"returning %r\n", efi_status);
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -274,6 +451,8 @@ static EFI_STATUS nonnull(1)
|
||||||
|
maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
+ BOOLEAN present = FALSE;
|
||||||
|
+
|
||||||
|
if (v->rtname) {
|
||||||
|
if (v->flags & MOK_MIRROR_DELETE_FIRST)
|
||||||
|
LibDeleteVariable(v->rtname, v->guid);
|
||||||
|
@@ -286,6 +465,43 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
efi_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ present = (v->data && v->data_size) ? TRUE : FALSE;
|
||||||
|
+ if (!present)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ if (v->data_size == sizeof(UINT8) && v->state) {
|
||||||
|
+ *v->state = v->data[0];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (v->flags & MOK_VARIABLE_MEASURE) {
|
||||||
|
+ /*
|
||||||
|
+ * Measure this into PCR 7 in the Microsoft format
|
||||||
|
+ */
|
||||||
|
+ efi_status = tpm_measure_variable(v->name, *v->guid,
|
||||||
|
+ v->data_size,
|
||||||
|
+ v->data);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
+ ret = efi_status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (v->flags & MOK_VARIABLE_LOG) {
|
||||||
|
+ /*
|
||||||
|
+ * Log this variable into whichever PCR the table
|
||||||
|
+ * says.
|
||||||
|
+ */
|
||||||
|
+ EFI_PHYSICAL_ADDRESS datap =
|
||||||
|
+ (EFI_PHYSICAL_ADDRESS)(UINTN)v->data,
|
||||||
|
+ efi_status = tpm_log_event(datap, v->data_size,
|
||||||
|
+ v->pcr, (CHAR8 *)v->name8);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
+ ret = efi_status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -311,26 +527,20 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
user_insecure_mode = 0;
|
||||||
|
ignore_db = 0;
|
||||||
|
|
||||||
|
+ dprint(L"importing mok state\n");
|
||||||
|
for (i = 0; mok_state_variables[i].name != NULL; i++) {
|
||||||
|
struct mok_state_variable *v = &mok_state_variables[i];
|
||||||
|
UINT32 attrs = 0;
|
||||||
|
- BOOLEAN delete = FALSE, present, addend;
|
||||||
|
-
|
||||||
|
- addend = check_addend(v);
|
||||||
|
+ BOOLEAN delete = FALSE;
|
||||||
|
|
||||||
|
efi_status = get_variable_attr(v->name,
|
||||||
|
&v->data, &v->data_size,
|
||||||
|
*v->guid, &attrs);
|
||||||
|
+ dprint(L"maybe mirroring %s\n", v->name);
|
||||||
|
if (efi_status == EFI_NOT_FOUND) {
|
||||||
|
- if (addend)
|
||||||
|
- ret = maybe_mirror_one_mok_variable(v, ret);
|
||||||
|
- /*
|
||||||
|
- * after possibly adding, we can continue, no
|
||||||
|
- * further checks to be done.
|
||||||
|
- */
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ } else if (EFI_ERROR(efi_status)) {
|
||||||
|
perror(L"Could not verify %s: %r\n", v->name,
|
||||||
|
efi_status);
|
||||||
|
/*
|
||||||
|
@@ -339,22 +549,22 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
*/
|
||||||
|
if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
ret = efi_status;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!(attrs & v->yes_attr)) {
|
||||||
|
- perror(L"Variable %s is missing attributes:\n",
|
||||||
|
- v->name);
|
||||||
|
- perror(L" 0x%08x should have 0x%08x set.\n",
|
||||||
|
- attrs, v->yes_attr);
|
||||||
|
- delete = TRUE;
|
||||||
|
- }
|
||||||
|
- if (attrs & v->no_attr) {
|
||||||
|
- perror(L"Variable %s has incorrect attribute:\n",
|
||||||
|
- v->name);
|
||||||
|
- perror(L" 0x%08x should not have 0x%08x set.\n",
|
||||||
|
- attrs, v->no_attr);
|
||||||
|
delete = TRUE;
|
||||||
|
+ } else {
|
||||||
|
+ if (!(attrs & v->yes_attr)) {
|
||||||
|
+ perror(L"Variable %s is missing attributes:\n",
|
||||||
|
+ v->name);
|
||||||
|
+ perror(L" 0x%08x should have 0x%08x set.\n",
|
||||||
|
+ attrs, v->yes_attr);
|
||||||
|
+ delete = TRUE;
|
||||||
|
+ }
|
||||||
|
+ if (attrs & v->no_attr) {
|
||||||
|
+ perror(L"Variable %s has incorrect attribute:\n",
|
||||||
|
+ v->name);
|
||||||
|
+ perror(L" 0x%08x should not have 0x%08x set.\n",
|
||||||
|
+ attrs, v->no_attr);
|
||||||
|
+ delete = TRUE;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (delete == TRUE) {
|
||||||
|
perror(L"Deleting bad variable %s\n", v->name);
|
||||||
|
@@ -366,45 +576,9 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
FreePool(v->data);
|
||||||
|
v->data = NULL;
|
||||||
|
v->data_size = 0;
|
||||||
|
- continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (v->data && v->data_size == sizeof(UINT8) && v->state) {
|
||||||
|
- *v->state = v->data[0];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- present = (v->data && v->data_size) ? TRUE : FALSE;
|
||||||
|
-
|
||||||
|
- if (v->flags & MOK_VARIABLE_MEASURE && present) {
|
||||||
|
- /*
|
||||||
|
- * Measure this into PCR 7 in the Microsoft format
|
||||||
|
- */
|
||||||
|
- efi_status = tpm_measure_variable(v->name, *v->guid,
|
||||||
|
- v->data_size,
|
||||||
|
- v->data);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
- ret = efi_status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (v->flags & MOK_VARIABLE_LOG && present) {
|
||||||
|
- /*
|
||||||
|
- * Log this variable into whichever PCR the table
|
||||||
|
- * says.
|
||||||
|
- */
|
||||||
|
- EFI_PHYSICAL_ADDRESS datap =
|
||||||
|
- (EFI_PHYSICAL_ADDRESS)(UINTN)v->data,
|
||||||
|
- efi_status = tpm_log_event(datap, v->data_size,
|
||||||
|
- v->pcr, (CHAR8 *)v->name8);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
- ret = efi_status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (present)
|
||||||
|
- ret = maybe_mirror_one_mok_variable(v, ret);
|
||||||
|
+ ret = maybe_mirror_one_mok_variable(v, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -412,14 +586,16 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
* cause MokManager to demand a machine reboot, so this is safe to
|
||||||
|
* have after the entire loop.
|
||||||
|
*/
|
||||||
|
+ dprint(L"checking mok request\n");
|
||||||
|
efi_status = check_mok_request(image_handle);
|
||||||
|
+ dprint(L"mok returned %r\n", efi_status);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
ret = efi_status;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
+ dprint(L"returning %r\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 888ee6e8d7b..ee62248ca4e 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -646,6 +646,31 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if defined(VENDOR_DB_FILE)
|
||||||
|
+ EFI_SIGNATURE_LIST *db = (EFI_SIGNATURE_LIST *)vendor_db;
|
||||||
|
+
|
||||||
|
+ if (check_db_hash_in_ram(db, vendor_db_size,
|
||||||
|
+ sha256hash, SHA256_DIGEST_SIZE,
|
||||||
|
+ EFI_CERT_SHA256_GUID, L"vendor_db",
|
||||||
|
+ EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
|
||||||
|
+ verification_method = VERIFIED_BY_HASH;
|
||||||
|
+ update_verification_method(VERIFIED_BY_HASH);
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+ } else {
|
||||||
|
+ LogError(L"check_db_hash(vendor_db, sha256hash) != DATA_FOUND\n");
|
||||||
|
+ }
|
||||||
|
+ if (cert &&
|
||||||
|
+ check_db_cert_in_ram(db, vendor_db_size,
|
||||||
|
+ cert, sha256hash, L"vendor_db",
|
||||||
|
+ EFI_SECURE_BOOT_DB_GUID) == DATA_FOUND) {
|
||||||
|
+ verification_method = VERIFIED_BY_CERT;
|
||||||
|
+ update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+ } else {
|
||||||
|
+ LogError(L"check_db_cert(vendor_db, sha256hash) != DATA_FOUND\n");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (check_db_hash(L"MokList", SHIM_LOCK_GUID, sha256hash,
|
||||||
|
SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID)
|
||||||
|
== DATA_FOUND) {
|
||||||
|
@@ -1076,6 +1101,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
}
|
||||||
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
|
||||||
|
+#if defined(VENDOR_CERT_FILE)
|
||||||
|
/*
|
||||||
|
* And finally, check against shim's built-in key
|
||||||
|
*/
|
||||||
|
@@ -1093,6 +1119,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
} else {
|
||||||
|
LogError(L"AuthenticodeVerify(vendor_authorized) failed\n");
|
||||||
|
}
|
||||||
|
+#endif /* defined(VENDOR_CERT_FILE) */
|
||||||
|
}
|
||||||
|
|
||||||
|
LogError(L"Binary is not whitelisted\n");
|
||||||
|
diff --git a/include/console.h b/include/console.h
|
||||||
|
index 9f259c71b72..810bf13a1f1 100644
|
||||||
|
--- a/include/console.h
|
||||||
|
+++ b/include/console.h
|
||||||
|
@@ -78,12 +78,13 @@ struct _EFI_CONSOLE_CONTROL_PROTOCOL {
|
||||||
|
extern VOID console_fini(VOID);
|
||||||
|
extern VOID setup_verbosity(VOID);
|
||||||
|
extern UINT32 verbose;
|
||||||
|
-#define dprint(fmt, ...) ({ \
|
||||||
|
+#define dprint_(fmt, ...) ({ \
|
||||||
|
UINTN __dprint_ret = 0; \
|
||||||
|
if (verbose) \
|
||||||
|
__dprint_ret = console_print((fmt), ##__VA_ARGS__); \
|
||||||
|
__dprint_ret; \
|
||||||
|
})
|
||||||
|
+#define dprint(fmt, ...) dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
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__)
|
||||||
|
diff --git a/include/variables.h b/include/variables.h
|
||||||
|
index 8566a1a4746..436adb46e16 100644
|
||||||
|
--- a/include/variables.h
|
||||||
|
+++ b/include/variables.h
|
||||||
|
@@ -57,7 +57,12 @@ EFI_STATUS
|
||||||
|
variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
|
||||||
|
UINT8 hash[SHA256_DIGEST_SIZE]);
|
||||||
|
EFI_STATUS
|
||||||
|
-variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
|
||||||
|
- void **out, int *outlen);
|
||||||
|
+variable_create_esl(const uint8_t *cert, const size_t cert_len,
|
||||||
|
+ const EFI_GUID *type, const EFI_GUID *owner,
|
||||||
|
+ uint8_t **out, size_t *outlen);
|
||||||
|
+EFI_STATUS
|
||||||
|
+fill_esl(const uint8_t *data, const size_t data_len,
|
||||||
|
+ const EFI_GUID *type, const EFI_GUID *owner,
|
||||||
|
+ uint8_t *out, size_t *outlen);
|
||||||
|
|
||||||
|
#endif /* SHIM_VARIABLES_H */
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index 555498c6673..c1d7e7c7197 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -97,7 +97,11 @@
|
||||||
|
#define FALLBACK L"\\fb" EFI_ARCH L".efi"
|
||||||
|
#define MOK_MANAGER L"\\mm" EFI_ARCH L".efi"
|
||||||
|
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
+#if defined(VENDOR_DB_FILE)
|
||||||
|
+# define vendor_authorized vendor_db
|
||||||
|
+# define vendor_authorized_size vendor_db_size
|
||||||
|
+# define vendor_authorized_category VENDOR_ADDEND_DB
|
||||||
|
+#elif defined(VENDOR_CERT_FILE)
|
||||||
|
# define vendor_authorized vendor_cert
|
||||||
|
# define vendor_authorized_size vendor_cert_size
|
||||||
|
# define vendor_authorized_category VENDOR_ADDEND_X509
|
||||||
|
@@ -116,6 +120,7 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/asm.h"
|
||||||
|
+#include "include/compiler.h"
|
||||||
|
#include "include/configtable.h"
|
||||||
|
#include "include/console.h"
|
||||||
|
#include "include/crypt_blowfish.h"
|
||||||
|
diff --git a/cert.S b/cert.S
|
||||||
|
index 520caaef3af..e636fcbbf2d 100644
|
||||||
|
--- a/cert.S
|
||||||
|
+++ b/cert.S
|
||||||
|
@@ -1,5 +1,12 @@
|
||||||
|
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
+#if defined(VENDOR_DB_FILE) && defined(VENDOR_CERT_FILE)
|
||||||
|
+# error both VENDOR_DB_FILE and VENDOR_CERT_FILE have been configured
|
||||||
|
+#elif defined(VENDOR_DB_FILE)
|
||||||
|
+# define vendor_authorized vendor_db
|
||||||
|
+# define vendor_authorized_end vendor_db_end
|
||||||
|
+# define vendor_authorized_size vendor_db_size
|
||||||
|
+# define vendor_authorized_size_end vendor_db_size_end
|
||||||
|
+#elif defined(VENDOR_CERT_FILE)
|
||||||
|
# define vendor_authorized vendor_cert
|
||||||
|
# define vendor_authorized_end vendor_cert_end
|
||||||
|
# define vendor_authorized_size vendor_cert_size
|
||||||
|
@@ -28,7 +35,9 @@ cert_table:
|
||||||
|
.size vendor_authorized, .Lvendor_authorized_end - vendor_authorized
|
||||||
|
.section .vendor_cert, "a", %progbits
|
||||||
|
vendor_authorized:
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
+#if defined(VENDOR_DB_FILE)
|
||||||
|
+.incbin VENDOR_DB_FILE
|
||||||
|
+#elif defined(VENDOR_CERT_FILE)
|
||||||
|
.incbin VENDOR_CERT_FILE
|
||||||
|
#endif
|
||||||
|
.Lvendor_authorized_end:
|
||||||
|
diff --git a/Make.defaults b/Make.defaults
|
||||||
|
index f0bfa9fd573..2e01646a35d 100644
|
||||||
|
--- a/Make.defaults
|
||||||
|
+++ b/Make.defaults
|
||||||
|
@@ -125,6 +125,9 @@ BOOTCSVNAME ?= BOOT$(ARCH_SUFFIX_UPPER).CSV
|
||||||
|
|
||||||
|
CFLAGS += "-DEFI_ARCH=L\"$(ARCH_SUFFIX)\"" "-DDEBUGDIR=L\"/usr/lib/debug/usr/share/shim/$(ARCH_SUFFIX)-$(VERSION)$(DASHRELEASE)/\""
|
||||||
|
|
||||||
|
+ifneq ($(origin VENDOR_DB_FILE), undefined)
|
||||||
|
+ CFLAGS += -DVENDOR_DB_FILE=\"$(VENDOR_DB_FILE)\"
|
||||||
|
+endif
|
||||||
|
ifneq ($(origin VENDOR_CERT_FILE), undefined)
|
||||||
|
CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\"
|
||||||
|
endif
|
||||||
|
diff --git a/README.tpm b/README.tpm
|
||||||
|
index c060dbe22db..62308d5c71a 100644
|
||||||
|
--- a/README.tpm
|
||||||
|
+++ b/README.tpm
|
||||||
|
@@ -13,6 +13,7 @@ PCR7:
|
||||||
|
- MokListX - the Mok blacklist, logged as "MokListX"
|
||||||
|
- vendor_dbx - shim's built-in vendor blacklist, logged as "dbx"
|
||||||
|
- DB - the system whitelist, logged as "db"
|
||||||
|
+ - vendor_db - shim's built-in vendor whitelist, logged as "db"
|
||||||
|
- MokList the Mok whitelist, logged as "MokList"
|
||||||
|
- vendor_cert - shim's built-in vendor whitelist, logged as "Shim"
|
||||||
|
- shim_cert - shim's build-time generated whitelist, logged as "Shim"
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
366
SOURCES/0058-Handle-binaries-with-multiple-signatures.patch
Normal file
366
SOURCES/0058-Handle-binaries-with-multiple-signatures.patch
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
From 76c0447e204c7e4ce918c4887ce8aae0e0816271 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 16:32:05 -0400
|
||||||
|
Subject: [PATCH 58/62] Handle binaries with multiple signatures.
|
||||||
|
|
||||||
|
This adds support for multiple signatures. It first tries validating
|
||||||
|
the binary by hash, first against our dbx lists, then against our db
|
||||||
|
lists. If it isn't allowed or rejected at that step, it continues to
|
||||||
|
the normal routine of checking all the signatures.
|
||||||
|
|
||||||
|
At this point it does *not* reject a binary just because a signature is
|
||||||
|
by a cert on a dbx list, though that will override any db list that
|
||||||
|
certificate is listed on. If at any point any assertion about the
|
||||||
|
binary or signature list being well-formed fails, the binary is
|
||||||
|
immediately rejected, though we do allow skipping over signatures
|
||||||
|
which have an unsupported sig->Hdr.wCertificateType.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#210
|
||||||
|
---
|
||||||
|
shim.c | 287 +++++++++++++++++++++++++++++++++++++++------------------
|
||||||
|
1 file changed, 198 insertions(+), 89 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index ee62248ca4e..d10a1ba1cac 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -690,7 +690,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
}
|
||||||
|
|
||||||
|
update_verification_method(VERIFIED_BY_NOTHING);
|
||||||
|
- return EFI_SECURITY_VIOLATION;
|
||||||
|
+ return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1004,6 +1004,103 @@ done:
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static EFI_STATUS
|
||||||
|
+verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
|
||||||
|
+ UINT8 *sha256hash, UINT8 *sha1hash)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Ensure that the binary isn't blacklisted
|
||||||
|
+ */
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ efi_status = check_blacklist(sig, sha256hash, sha1hash);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Binary is blacklisted: %r\n", efi_status);
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Check whether the binary is whitelisted in any of the firmware
|
||||||
|
+ * databases
|
||||||
|
+ */
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ efi_status = check_whitelist(sig, sha256hash, sha1hash);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ if (efi_status != EFI_NOT_FOUND) {
|
||||||
|
+ dprint(L"check_whitelist(): %r\n", efi_status);
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(efi_status);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ efi_status = EFI_NOT_FOUND;
|
||||||
|
+#if defined(ENABLE_SHIM_CERT)
|
||||||
|
+ /*
|
||||||
|
+ * Check against the shim build key
|
||||||
|
+ */
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ if (build_cert && build_cert_size) {
|
||||||
|
+ dprint("verifying against shim cert\n");
|
||||||
|
+ }
|
||||||
|
+ if (build_cert && build_cert_size &&
|
||||||
|
+ AuthenticodeVerify(sig->CertData,
|
||||||
|
+ sig->Hdr.dwLength - sizeof(sig->Hdr),
|
||||||
|
+ build_cert, build_cert_size, sha256hash,
|
||||||
|
+ SHA256_DIGEST_SIZE)) {
|
||||||
|
+ dprint(L"AuthenticodeVerify(shim_cert) succeeded\n");
|
||||||
|
+ update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
+ tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
|
||||||
|
+ build_cert_size, build_cert);
|
||||||
|
+ efi_status = EFI_SUCCESS;
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ return efi_status;
|
||||||
|
+ } else {
|
||||||
|
+ dprint(L"AuthenticodeVerify(shim_cert) failed\n");
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(EFI_NOT_FOUND);
|
||||||
|
+ }
|
||||||
|
+#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
+
|
||||||
|
+#if defined(VENDOR_CERT_FILE)
|
||||||
|
+ /*
|
||||||
|
+ * And finally, check against shim's built-in key
|
||||||
|
+ */
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ if (vendor_cert_size) {
|
||||||
|
+ dprint("verifying against vendor_cert\n");
|
||||||
|
+ }
|
||||||
|
+ if (vendor_cert_size &&
|
||||||
|
+ AuthenticodeVerify(sig->CertData,
|
||||||
|
+ sig->Hdr.dwLength - sizeof(sig->Hdr),
|
||||||
|
+ vendor_cert, vendor_cert_size,
|
||||||
|
+ sha256hash, SHA256_DIGEST_SIZE)) {
|
||||||
|
+ dprint(L"AuthenticodeVerify(vendor_cert) succeeded\n");
|
||||||
|
+ update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
+ tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
|
||||||
|
+ vendor_cert_size, vendor_cert);
|
||||||
|
+ efi_status = EFI_SUCCESS;
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ return efi_status;
|
||||||
|
+ } else {
|
||||||
|
+ dprint(L"AuthenticodeVerify(vendor_cert) failed\n");
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(EFI_NOT_FOUND);
|
||||||
|
+ }
|
||||||
|
+#endif /* defined(VENDOR_CERT_FILE) */
|
||||||
|
+
|
||||||
|
+ return efi_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Check that the signature is valid and matches the binary
|
||||||
|
*/
|
||||||
|
@@ -1011,40 +1108,14 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
||||||
|
UINT8 *sha256hash, UINT8 *sha1hash)
|
||||||
|
{
|
||||||
|
- EFI_STATUS efi_status = EFI_SECURITY_VIOLATION;
|
||||||
|
- WIN_CERTIFICATE_EFI_PKCS *cert = NULL;
|
||||||
|
- unsigned int size = datasize;
|
||||||
|
+ EFI_STATUS ret_efi_status;
|
||||||
|
+ size_t size = datasize;
|
||||||
|
+ size_t offset = 0;
|
||||||
|
+ unsigned int i = 0;
|
||||||
|
|
||||||
|
if (datasize < 0)
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
- if (context->SecDir->Size != 0) {
|
||||||
|
- if (context->SecDir->Size >= size) {
|
||||||
|
- perror(L"Certificate Database size is too large\n");
|
||||||
|
- return EFI_INVALID_PARAMETER;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- cert = ImageAddress (data, size,
|
||||||
|
- context->SecDir->VirtualAddress);
|
||||||
|
-
|
||||||
|
- if (!cert) {
|
||||||
|
- perror(L"Certificate located outside the image\n");
|
||||||
|
- return EFI_INVALID_PARAMETER;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (cert->Hdr.dwLength > context->SecDir->Size) {
|
||||||
|
- perror(L"Certificate list size is inconsistent with PE headers");
|
||||||
|
- return EFI_INVALID_PARAMETER;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (cert->Hdr.wCertificateType !=
|
||||||
|
- WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
|
||||||
|
- perror(L"Unsupported certificate type %x\n",
|
||||||
|
- cert->Hdr.wCertificateType);
|
||||||
|
- return EFI_UNSUPPORTED;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Clear OpenSSL's error log, because we get some DSO unimplemented
|
||||||
|
* errors during its intialization, and we don't want those to look
|
||||||
|
@@ -1052,81 +1123,119 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
*/
|
||||||
|
drain_openssl_errors();
|
||||||
|
|
||||||
|
- efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- LogError(L"generate_hash: %r\n", efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
+ ret_efi_status = generate_hash(data, datasize, context, sha256hash, sha1hash);
|
||||||
|
+ if (EFI_ERROR(ret_efi_status)) {
|
||||||
|
+ dprint(L"generate_hash: %r\n", ret_efi_status);
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(ret_efi_status);
|
||||||
|
+ return ret_efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Ensure that the binary isn't blacklisted
|
||||||
|
+ * Ensure that the binary isn't blacklisted by hash
|
||||||
|
*/
|
||||||
|
- efi_status = check_blacklist(cert, sha256hash, sha1hash);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ ret_efi_status = check_blacklist(NULL, sha256hash, sha1hash);
|
||||||
|
+ if (EFI_ERROR(ret_efi_status)) {
|
||||||
|
perror(L"Binary is blacklisted\n");
|
||||||
|
- LogError(L"Binary is blacklisted: %r\n", efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
+ dprint(L"Binary is blacklisted: %r\n", ret_efi_status);
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(ret_efi_status);
|
||||||
|
+ return ret_efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Check whether the binary is whitelisted in any of the firmware
|
||||||
|
- * databases
|
||||||
|
+ * Check whether the binary is whitelisted by hash in any of the
|
||||||
|
+ * firmware databases
|
||||||
|
*/
|
||||||
|
- efi_status = check_whitelist(cert, sha256hash, sha1hash);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- LogError(L"check_whitelist(): %r\n", efi_status);
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ ret_efi_status = check_whitelist(NULL, sha256hash, sha1hash);
|
||||||
|
+ if (EFI_ERROR(ret_efi_status)) {
|
||||||
|
+ dprint(L"check_whitelist: %r\n", ret_efi_status);
|
||||||
|
+ if (ret_efi_status != EFI_NOT_FOUND) {
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(ret_efi_status);
|
||||||
|
+ return ret_efi_status;
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
drain_openssl_errors();
|
||||||
|
- return efi_status;
|
||||||
|
+ return ret_efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cert) {
|
||||||
|
-#if defined(ENABLE_SHIM_CERT)
|
||||||
|
- /*
|
||||||
|
- * Check against the shim build key
|
||||||
|
- */
|
||||||
|
- if (sizeof(shim_cert) &&
|
||||||
|
- AuthenticodeVerify(cert->CertData,
|
||||||
|
- cert->Hdr.dwLength - sizeof(cert->Hdr),
|
||||||
|
- shim_cert, sizeof(shim_cert), sha256hash,
|
||||||
|
- SHA256_DIGEST_SIZE)) {
|
||||||
|
- update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
- tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
|
||||||
|
- sizeof(shim_cert), shim_cert);
|
||||||
|
- efi_status = EFI_SUCCESS;
|
||||||
|
- drain_openssl_errors();
|
||||||
|
- return efi_status;
|
||||||
|
- } else {
|
||||||
|
- LogError(L"AuthenticodeVerify(shim_cert) failed\n");
|
||||||
|
+ if (context->SecDir->Size == 0) {
|
||||||
|
+ dprint(L"No signatures found\n");
|
||||||
|
+ return EFI_SECURITY_VIOLATION;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (context->SecDir->Size >= size) {
|
||||||
|
+ perror(L"Certificate Database size is too large\n");
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret_efi_status = EFI_NOT_FOUND;
|
||||||
|
+ do {
|
||||||
|
+ WIN_CERTIFICATE_EFI_PKCS *sig = NULL;
|
||||||
|
+ size_t sz;
|
||||||
|
+
|
||||||
|
+ sig = ImageAddress(data, size,
|
||||||
|
+ context->SecDir->VirtualAddress + offset);
|
||||||
|
+ if (!sig)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ sz = offset + offsetof(WIN_CERTIFICATE_EFI_PKCS, Hdr.dwLength)
|
||||||
|
+ + sizeof(sig->Hdr.dwLength);
|
||||||
|
+ if (sz > context->SecDir->Size) {
|
||||||
|
+ perror(L"Certificate size is too large for secruity database");
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sz = sig->Hdr.dwLength;
|
||||||
|
+ if (sz > context->SecDir->Size - offset) {
|
||||||
|
+ perror(L"Certificate size is too large for secruity database");
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
-#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
-
|
||||||
|
-#if defined(VENDOR_CERT_FILE)
|
||||||
|
- /*
|
||||||
|
- * And finally, check against shim's built-in key
|
||||||
|
- */
|
||||||
|
- if (vendor_authorized_size &&
|
||||||
|
- AuthenticodeVerify(cert->CertData,
|
||||||
|
- cert->Hdr.dwLength - sizeof(cert->Hdr),
|
||||||
|
- vendor_authorized, vendor_authorized_size,
|
||||||
|
- sha256hash, SHA256_DIGEST_SIZE)) {
|
||||||
|
- update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
- tpm_measure_variable(L"Shim", SHIM_LOCK_GUID,
|
||||||
|
- vendor_authorized_size, vendor_authorized);
|
||||||
|
- efi_status = EFI_SUCCESS;
|
||||||
|
- drain_openssl_errors();
|
||||||
|
- return efi_status;
|
||||||
|
+
|
||||||
|
+ if (sz < sizeof(sig->Hdr)) {
|
||||||
|
+ perror(L"Certificate size is too small for certificate data");
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (sig->Hdr.wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+
|
||||||
|
+ dprint(L"Attempting to verify signature %d:\n", i++);
|
||||||
|
+
|
||||||
|
+ efi_status = verify_one_signature(sig, sha256hash, sha1hash);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If we didn't get EFI_SECURITY_VIOLATION from
|
||||||
|
+ * checking the hashes above, then any dbx entries are
|
||||||
|
+ * for a certificate, not this individual binary.
|
||||||
|
+ *
|
||||||
|
+ * So don't clobber successes with security violation
|
||||||
|
+ * here; that just means it isn't a success.
|
||||||
|
+ */
|
||||||
|
+ if (ret_efi_status != EFI_SUCCESS)
|
||||||
|
+ ret_efi_status = efi_status;
|
||||||
|
} else {
|
||||||
|
- LogError(L"AuthenticodeVerify(vendor_authorized) failed\n");
|
||||||
|
+ perror(L"Unsupported certificate type %x\n",
|
||||||
|
+ sig->Hdr.wCertificateType);
|
||||||
|
}
|
||||||
|
-#endif /* defined(VENDOR_CERT_FILE) */
|
||||||
|
- }
|
||||||
|
+ offset = ALIGN_VALUE(offset + sz, 8);
|
||||||
|
+ } while (offset < context->SecDir->Size);
|
||||||
|
|
||||||
|
- LogError(L"Binary is not whitelisted\n");
|
||||||
|
- crypterr(EFI_SECURITY_VIOLATION);
|
||||||
|
- PrintErrors();
|
||||||
|
- efi_status = EFI_SECURITY_VIOLATION;
|
||||||
|
- return efi_status;
|
||||||
|
+ if (ret_efi_status != EFI_SUCCESS) {
|
||||||
|
+ dprint(L"Binary is not whitelisted\n");
|
||||||
|
+ PrintErrors();
|
||||||
|
+ ClearErrors();
|
||||||
|
+ crypterr(EFI_SECURITY_VIOLATION);
|
||||||
|
+ ret_efi_status = EFI_SECURITY_VIOLATION;
|
||||||
|
+ }
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
+ return ret_efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
119
SOURCES/0059-Make-openssl-accept-the-right-set-of-KU-EKUs.patch
Normal file
119
SOURCES/0059-Make-openssl-accept-the-right-set-of-KU-EKUs.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
From 705d47ac2c90b8de07a4ef3e1930de6c4b8fece0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Wed, 22 Jul 2020 19:54:58 -0400
|
||||||
|
Subject: [PATCH 59/62] Make openssl accept the right set of KU/EKUs
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#211
|
||||||
|
---
|
||||||
|
Cryptlib/Pk/CryptPkcs7Verify.c | 87 ++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 87 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c
|
||||||
|
index dcaba436797..09895d8c66a 100644
|
||||||
|
--- a/Cryptlib/Pk/CryptPkcs7Verify.c
|
||||||
|
+++ b/Cryptlib/Pk/CryptPkcs7Verify.c
|
||||||
|
@@ -30,6 +30,91 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
|
||||||
|
|
||||||
|
+#if 1
|
||||||
|
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
+#define X509_OBJECT_get0_X509(obj) ((obj)->data.x509)
|
||||||
|
+#define X509_OBJECT_get_type(obj) ((obj)->type)
|
||||||
|
+#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
|
||||||
|
+#define X509_STORE_get0_objects(certs) ((certs)->objs)
|
||||||
|
+#define X509_get_extended_key_usage(cert) ((cert)->ex_xkusage)
|
||||||
|
+#if OPENSSL_VERSION_NUMBER < 0x10020000L
|
||||||
|
+#define X509_STORE_CTX_get0_store(ctx) ((ctx)->ctx)
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
|
||||||
|
+{
|
||||||
|
+ X509_OBJECT obj;
|
||||||
|
+ obj.type = X509_LU_X509;
|
||||||
|
+ obj.data.x509 = cert;
|
||||||
|
+ return X509_OBJECT_retrieve_match(ctx->ctx->objs, &obj) != NULL;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+/*
|
||||||
|
+ * Later versions of openssl will need this instead.
|
||||||
|
+ */
|
||||||
|
+static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
|
||||||
|
+{
|
||||||
|
+ STACK_OF(X509_OBJECT) *objs;
|
||||||
|
+ X509_OBJECT *obj;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ objs = X509_STORE_get0_objects(X509_STORE_CTX_get0_store(ctx));
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
||||||
|
+ obj = sk_X509_OBJECT_value(objs, i);
|
||||||
|
+
|
||||||
|
+ if (X509_OBJECT_get_type(obj) == X509_LU_X509 &&
|
||||||
|
+ !X509_cmp(X509_OBJECT_get0_X509(obj), cert))
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+X509VerifyCb (
|
||||||
|
+ IN int Status,
|
||||||
|
+ IN X509_STORE_CTX *Context
|
||||||
|
+ )
|
||||||
|
+{
|
||||||
|
+ INTN Error;
|
||||||
|
+
|
||||||
|
+ Error = (INTN) X509_STORE_CTX_get_error (Context);
|
||||||
|
+
|
||||||
|
+ /* Accept code-signing keys */
|
||||||
|
+ if (Error == X509_V_ERR_INVALID_PURPOSE &&
|
||||||
|
+ X509_get_extended_key_usage(X509_STORE_CTX_get0_cert(Context)) == XKU_CODE_SIGN) {
|
||||||
|
+ Status = 1;
|
||||||
|
+ } else if (Error == X509_V_ERR_CERT_UNTRUSTED ||
|
||||||
|
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
|
||||||
|
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
||||||
|
+ Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
|
||||||
|
+ /* all certs in our cert database are explicitly trusted */
|
||||||
|
+
|
||||||
|
+ if (cert_in_store(X509_STORE_CTX_get_current_cert(Context), Context))
|
||||||
|
+ Status = 1;
|
||||||
|
+ } else if (Error == X509_V_ERR_CERT_HAS_EXPIRED ||
|
||||||
|
+ Error == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||
|
||||||
|
+ Error == X509_V_ERR_CERT_NOT_YET_VALID ||
|
||||||
|
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
||||||
|
+ Error == X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD) {
|
||||||
|
+ /* UEFI explicitly allows expired certificates */
|
||||||
|
+ Status = 1;
|
||||||
|
+#if 0
|
||||||
|
+ } else if (Error == X509_V_ERR_INVALID_CA) {
|
||||||
|
+ /* Due to the historical reason, we have to relax the the x509 v3 extension
|
||||||
|
+ * check to allow the CA certificates without the CA flag in the basic
|
||||||
|
+ * constraints or KeyCertSign in the key usage to be loaded. In the future,
|
||||||
|
+ * this callback should be removed to enforce the proper check. */
|
||||||
|
+ Status = 1;
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return Status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
|
||||||
|
a new structure to wrap P7Data.
|
||||||
|
@@ -844,6 +929,8 @@ Pkcs7Verify (
|
||||||
|
goto _Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ X509_STORE_set_verify_cb (CertStore, X509VerifyCb);
|
||||||
|
+
|
||||||
|
//
|
||||||
|
// For generic PKCS#7 handling, InData may be NULL if the content is present
|
||||||
|
// in PKCS#7 structure. So ignore NULL checking here.
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
451
SOURCES/0060-Improve-debug-output-some.patch
Normal file
451
SOURCES/0060-Improve-debug-output-some.patch
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
From fc4368fed53837e00d303600d8b628cb0392b629 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 20:29:52 -0400
|
||||||
|
Subject: [PATCH 60/62] Improve debug output some
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: pr#213
|
||||||
|
---
|
||||||
|
errlog.c | 26 ++++++-
|
||||||
|
shim.c | 36 ++++++++--
|
||||||
|
include/console.h | 3 +
|
||||||
|
include/hexdump.h | 172 ++++++++++++++++++++++++++++------------------
|
||||||
|
shim.h | 5 +-
|
||||||
|
5 files changed, 164 insertions(+), 78 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/errlog.c b/errlog.c
|
||||||
|
index 6669c800233..08f7a82a6b2 100644
|
||||||
|
--- a/errlog.c
|
||||||
|
+++ b/errlog.c
|
||||||
|
@@ -3,12 +3,28 @@
|
||||||
|
* Copyright 2017 Peter Jones <pjones@redhat.com>
|
||||||
|
*/
|
||||||
|
#include "shim.h"
|
||||||
|
+#include "hexdump.h"
|
||||||
|
|
||||||
|
static CHAR16 **errs = NULL;
|
||||||
|
static UINTN nerrs = 0;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
-VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args)
|
||||||
|
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args)
|
||||||
|
+{
|
||||||
|
+ va_list args2;
|
||||||
|
+ EFI_STATUS efi_status = EFI_SUCCESS;
|
||||||
|
+
|
||||||
|
+ if (verbose) {
|
||||||
|
+ va_copy(args2, args);
|
||||||
|
+ console_print(L"%a:%d:%a() ", file, line, func);
|
||||||
|
+ efi_status = VPrint(fmt, args2);
|
||||||
|
+ va_end(args2);
|
||||||
|
+ }
|
||||||
|
+ return efi_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+EFI_STATUS
|
||||||
|
+VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args)
|
||||||
|
{
|
||||||
|
va_list args2;
|
||||||
|
CHAR16 **newerrs;
|
||||||
|
@@ -35,7 +51,7 @@ VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list arg
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
-LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
|
||||||
|
+LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
@@ -47,6 +63,12 @@ LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
+VOID
|
||||||
|
+LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz)
|
||||||
|
+{
|
||||||
|
+ hexdumpat(file, line, func, data, sz, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
VOID
|
||||||
|
PrintErrors(VOID)
|
||||||
|
{
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index d10a1ba1cac..9248642bd57 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shim.h"
|
||||||
|
+#include "hexdump.h"
|
||||||
|
#if defined(ENABLE_SHIM_CERT)
|
||||||
|
#include "shim_cert.h"
|
||||||
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
@@ -373,12 +374,18 @@ static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
|
||||||
|
* and 64KB. For convenience, assume the number of value bytes
|
||||||
|
* is 2, i.e. the second byte is 0x82.
|
||||||
|
*/
|
||||||
|
- if (Cert[0] != 0x30 || Cert[1] != 0x82)
|
||||||
|
+ if (Cert[0] != 0x30 || Cert[1] != 0x82) {
|
||||||
|
+ dprint(L"cert[0:1] is [%02x%02x], should be [%02x%02x]\n",
|
||||||
|
+ Cert[0], Cert[1], 0x30, 0x82);
|
||||||
|
return FALSE;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
length = Cert[2]<<8 | Cert[3];
|
||||||
|
- if (length != (CertSize - 4))
|
||||||
|
+ if (length != (CertSize - 4)) {
|
||||||
|
+ dprint(L"Cert length is %ld, expecting %ld\n",
|
||||||
|
+ length, CertSize);
|
||||||
|
return FALSE;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@@ -426,19 +433,23 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
|
||||||
|
EFI_SIGNATURE_DATA *Cert;
|
||||||
|
UINTN CertSize;
|
||||||
|
BOOLEAN IsFound = FALSE;
|
||||||
|
+ int i = 0;
|
||||||
|
|
||||||
|
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
|
||||||
|
if (CompareGuid (&CertList->SignatureType, &EFI_CERT_TYPE_X509_GUID) == 0) {
|
||||||
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
||||||
|
CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
|
||||||
|
+ dprint(L"trying to verify cert %d (%s)\n", i++, dbname);
|
||||||
|
if (verify_x509(Cert->SignatureData, CertSize)) {
|
||||||
|
if (verify_eku(Cert->SignatureData, CertSize)) {
|
||||||
|
+ drain_openssl_errors();
|
||||||
|
IsFound = AuthenticodeVerify (data->CertData,
|
||||||
|
data->Hdr.dwLength - sizeof(data->Hdr),
|
||||||
|
Cert->SignatureData,
|
||||||
|
CertSize,
|
||||||
|
hash, SHA256_DIGEST_SIZE);
|
||||||
|
if (IsFound) {
|
||||||
|
+ dprint(L"AuthenticodeVerify() succeeded: %d\n", IsFound);
|
||||||
|
tpm_measure_variable(dbname, guid, CertSize, Cert->SignatureData);
|
||||||
|
drain_openssl_errors();
|
||||||
|
return DATA_FOUND;
|
||||||
|
@@ -447,7 +458,9 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (verbose) {
|
||||||
|
- console_notify(L"Not a DER encoding x.509 Certificate");
|
||||||
|
+ console_print(L"Not a DER encoded x.509 Certificate");
|
||||||
|
+ dprint(L"cert:\n");
|
||||||
|
+ dhexdumpat(Cert->SignatureData, CertSize, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -641,7 +654,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
verification_method = VERIFIED_BY_CERT;
|
||||||
|
update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
- } else {
|
||||||
|
+ } else if (cert) {
|
||||||
|
LogError(L"check_db_cert(db, sha256hash) != DATA_FOUND\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -666,7 +679,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
verification_method = VERIFIED_BY_CERT;
|
||||||
|
update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
- } else {
|
||||||
|
+ } else if (cert) {
|
||||||
|
LogError(L"check_db_cert(vendor_db, sha256hash) != DATA_FOUND\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -685,7 +698,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
||||||
|
verification_method = VERIFIED_BY_CERT;
|
||||||
|
update_verification_method(VERIFIED_BY_CERT);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
- } else {
|
||||||
|
+ } else if (cert) {
|
||||||
|
LogError(L"check_db_cert(MokList, sha256hash) != DATA_FOUND\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -993,6 +1006,11 @@ static EFI_STATUS generate_hash (char *data, unsigned int datasize_in,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ dprint(L"sha1 authenticode hash:\n");
|
||||||
|
+ dhexdumpat(sha1hash, SHA1_DIGEST_SIZE, 0);
|
||||||
|
+ dprint(L"sha256 authenticode hash:\n");
|
||||||
|
+ dhexdumpat(sha256hash, SHA256_DIGEST_SIZE, 0);
|
||||||
|
+
|
||||||
|
done:
|
||||||
|
if (SectionHeader)
|
||||||
|
FreePool(SectionHeader);
|
||||||
|
@@ -1155,6 +1173,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||||||
|
if (EFI_ERROR(ret_efi_status)) {
|
||||||
|
dprint(L"check_whitelist: %r\n", ret_efi_status);
|
||||||
|
if (ret_efi_status != EFI_NOT_FOUND) {
|
||||||
|
+ dprint(L"check_whitelist(): %r\n", ret_efi_status);
|
||||||
|
PrintErrors();
|
||||||
|
ClearErrors();
|
||||||
|
crypterr(ret_efi_status);
|
||||||
|
@@ -1803,6 +1822,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
|
||||||
|
|
||||||
|
device = li->DeviceHandle;
|
||||||
|
|
||||||
|
+ dprint(L"attempting to load %s\n", PathName);
|
||||||
|
/*
|
||||||
|
* Open the device
|
||||||
|
*/
|
||||||
|
@@ -2778,6 +2798,10 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
*/
|
||||||
|
InitializeLib(image_handle, systab);
|
||||||
|
|
||||||
|
+ dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
|
||||||
|
+ __FILE__, __LINE__, __func__, vendor_authorized, vendor_authorized_size);
|
||||||
|
+ dprint(L"vendor_deauthorized:0x%08lx vendor_deauthorized_size:%lu\n",
|
||||||
|
+ __FILE__, __LINE__, __func__, vendor_deauthorized, vendor_deauthorized_size);
|
||||||
|
init_openssl();
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/include/console.h b/include/console.h
|
||||||
|
index 810bf13a1f1..ac6fdf61d18 100644
|
||||||
|
--- a/include/console.h
|
||||||
|
+++ b/include/console.h
|
||||||
|
@@ -85,6 +85,9 @@ extern UINT32 verbose;
|
||||||
|
__dprint_ret; \
|
||||||
|
})
|
||||||
|
#define dprint(fmt, ...) dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
+extern EFI_STATUS
|
||||||
|
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args);
|
||||||
|
+#define vdprint(fmt, ...) vdprint_(fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
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__)
|
||||||
|
diff --git a/include/hexdump.h b/include/hexdump.h
|
||||||
|
index d337b571d8d..f3f3ac284a3 100644
|
||||||
|
--- a/include/hexdump.h
|
||||||
|
+++ b/include/hexdump.h
|
||||||
|
@@ -1,104 +1,140 @@
|
||||||
|
#ifndef STATIC_HEXDUMP_H
|
||||||
|
#define STATIC_HEXDUMP_H
|
||||||
|
|
||||||
|
-static int
|
||||||
|
-__attribute__((__unused__))
|
||||||
|
-isprint(char c)
|
||||||
|
-{
|
||||||
|
- if (c < 0x20)
|
||||||
|
- return 0;
|
||||||
|
- if (c > 0x7e)
|
||||||
|
- return 0;
|
||||||
|
- return 1;
|
||||||
|
-}
|
||||||
|
+#include <stdint.h>
|
||||||
|
|
||||||
|
-static UINTN
|
||||||
|
-__attribute__((__unused__))
|
||||||
|
-format_hex(UINT8 *data, UINTN size, CHAR16 *buf)
|
||||||
|
+static inline unsigned long UNUSED
|
||||||
|
+prepare_hex(const void *data, size_t size, char *buf, int position)
|
||||||
|
{
|
||||||
|
- UINTN sz = (UINTN)data % 16;
|
||||||
|
- CHAR16 hexchars[] = L"0123456789abcdef";
|
||||||
|
+ char hexchars[] = "0123456789abcdef";
|
||||||
|
int offset = 0;
|
||||||
|
- UINTN i;
|
||||||
|
- UINTN j;
|
||||||
|
+ unsigned long i;
|
||||||
|
+ unsigned long j;
|
||||||
|
+ unsigned long ret;
|
||||||
|
|
||||||
|
- for (i = 0; i < sz; i++) {
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
+ unsigned long before = (position % 16);
|
||||||
|
+ unsigned long after = (before+size >= 16) ? 0 : 16 - (before+size);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < before; i++) {
|
||||||
|
+ buf[offset++] = 'X';
|
||||||
|
+ buf[offset++] = 'X';
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
if (i == 7)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
}
|
||||||
|
- for (j = sz; j < 16 && j < size; j++) {
|
||||||
|
- UINT8 d = data[j-sz];
|
||||||
|
+ for (j = 0; j < 16 - after - before; j++) {
|
||||||
|
+ uint8_t d = ((uint8_t *)data)[j];
|
||||||
|
buf[offset++] = hexchars[(d & 0xf0) >> 4];
|
||||||
|
buf[offset++] = hexchars[(d & 0x0f)];
|
||||||
|
- if (j != 15)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- if (j == 7)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
+ if (i+j != 15)
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
+ if (i+j == 7)
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
}
|
||||||
|
- for (i = j; i < 16; i++) {
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- if (i != 15)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- if (i == 7)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
+ ret = 16 - after - before;
|
||||||
|
+ j += i;
|
||||||
|
+ for (i = 0; i < after; i++) {
|
||||||
|
+ buf[offset++] = 'X';
|
||||||
|
+ buf[offset++] = 'X';
|
||||||
|
+ if (i+j != 15)
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
+ if (i+j == 7)
|
||||||
|
+ buf[offset++] = ' ';
|
||||||
|
}
|
||||||
|
- buf[offset] = L'\0';
|
||||||
|
- return j - sz;
|
||||||
|
+ buf[offset] = '\0';
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-__attribute__((__unused__))
|
||||||
|
-format_text(UINT8 *data, UINTN size, CHAR16 *buf)
|
||||||
|
+#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
|
||||||
|
+
|
||||||
|
+static inline void UNUSED
|
||||||
|
+prepare_text(const void *data, size_t size, char *buf, int position)
|
||||||
|
{
|
||||||
|
- UINTN sz = (UINTN)data % 16;
|
||||||
|
int offset = 0;
|
||||||
|
- UINTN i;
|
||||||
|
- UINTN j;
|
||||||
|
+ unsigned long i;
|
||||||
|
+ unsigned long j;
|
||||||
|
|
||||||
|
- for (i = 0; i < sz; i++)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- buf[offset++] = L'|';
|
||||||
|
- for (j = sz; j < 16 && j < size; j++) {
|
||||||
|
- if (isprint(data[j-sz]))
|
||||||
|
- buf[offset++] = data[j-sz];
|
||||||
|
+ unsigned long before = position % 16;
|
||||||
|
+ unsigned long after = (before+size > 16) ? 0 : 16 - (before+size);
|
||||||
|
+
|
||||||
|
+ if (size == 0) {
|
||||||
|
+ buf[0] = '\0';
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ for (i = 0; i < before; i++)
|
||||||
|
+ buf[offset++] = 'X';
|
||||||
|
+ buf[offset++] = '|';
|
||||||
|
+ for (j = 0; j < 16 - after - before; j++) {
|
||||||
|
+ if (isprint(((uint8_t *)data)[j]))
|
||||||
|
+ buf[offset++] = ((uint8_t *)data)[j];
|
||||||
|
else
|
||||||
|
- buf[offset++] = L'.';
|
||||||
|
+ buf[offset++] = '.';
|
||||||
|
}
|
||||||
|
- buf[offset++] = L'|';
|
||||||
|
- for (i = j; i < 16; i++)
|
||||||
|
- buf[offset++] = L' ';
|
||||||
|
- buf[offset] = L'\0';
|
||||||
|
+ buf[offset++] = size > 0 ? '|' : 'X';
|
||||||
|
+ buf[offset] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-__attribute__((__unused__))
|
||||||
|
-hexdump(UINT8 *data, UINTN size)
|
||||||
|
+/*
|
||||||
|
+ * variadic hexdump formatted
|
||||||
|
+ * think of it as: printf("%s%s\n", vformat(fmt, ap), hexdump(data,size));
|
||||||
|
+ */
|
||||||
|
+static inline void UNUSED
|
||||||
|
+vhexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, va_list ap)
|
||||||
|
{
|
||||||
|
- UINTN display_offset = (UINTN)data & 0xffffffff;
|
||||||
|
- UINTN offset = 0;
|
||||||
|
- //console_print(L"hexdump: data=0x%016x size=0x%x\n", data, size);
|
||||||
|
+ unsigned long display_offset = at;
|
||||||
|
+ unsigned long offset = 0;
|
||||||
|
|
||||||
|
while (offset < size) {
|
||||||
|
- CHAR16 hexbuf[49];
|
||||||
|
- CHAR16 txtbuf[19];
|
||||||
|
- UINTN sz;
|
||||||
|
+ char hexbuf[49];
|
||||||
|
+ char txtbuf[19];
|
||||||
|
+ unsigned long sz;
|
||||||
|
|
||||||
|
- sz = format_hex(data+offset, size-offset, hexbuf);
|
||||||
|
+ sz = prepare_hex(data+offset, size-offset, hexbuf,
|
||||||
|
+ (unsigned long)data+offset);
|
||||||
|
if (sz == 0)
|
||||||
|
return;
|
||||||
|
- msleep(200000);
|
||||||
|
|
||||||
|
- format_text(data+offset, size-offset, txtbuf);
|
||||||
|
- console_print(L"%08x %s %s\n", display_offset, hexbuf, txtbuf);
|
||||||
|
- msleep(200000);
|
||||||
|
+ prepare_text(data+offset, size-offset, txtbuf,
|
||||||
|
+ (unsigned long)data+offset);
|
||||||
|
+ if (fmt && fmt[0] != 0)
|
||||||
|
+ vdprint_(fmt, file, line, func, ap);
|
||||||
|
+ dprint_(L"%a:%d:%a() %08lx %a %a\n", file, line, func, display_offset, hexbuf, txtbuf);
|
||||||
|
|
||||||
|
display_offset += sz;
|
||||||
|
offset += sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * hexdump formatted
|
||||||
|
+ * think of it as: printf("%s%s", format(fmt, ...), hexdump(data,size)[lineN]);
|
||||||
|
+ */
|
||||||
|
+static inline void UNUSED
|
||||||
|
+hexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, ...)
|
||||||
|
+{
|
||||||
|
+ va_list ap;
|
||||||
|
+
|
||||||
|
+ va_start(ap, at);
|
||||||
|
+ vhexdumpf(file, line, func, fmt, data, size, at, ap);
|
||||||
|
+ va_end(ap);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void UNUSED
|
||||||
|
+hexdump(const char *file, int line, const char *func, const void *data, unsigned long size)
|
||||||
|
+{
|
||||||
|
+ hexdumpf(file, line, func, L"", data, size, (intptr_t)data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void UNUSED
|
||||||
|
+hexdumpat(const char *file, int line, const char *func, const void *data, unsigned long size, size_t at)
|
||||||
|
+{
|
||||||
|
+ hexdumpf(file, line, func, L"", data, size, at);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define LogHexdump(data, sz) LogHexdump_(__FILE__, __LINE__, __func__, data, sz)
|
||||||
|
+#define dhexdump(data, sz) hexdump(__FILE__, __LINE__, __func__, data, sz)
|
||||||
|
+#define dhexdumpat(data, sz, at) hexdumpat(__FILE__, __LINE__, __func__, data, sz, at)
|
||||||
|
+#define dhexdumpf(fmt, data, sz, at, ...) hexdumpf(__FILE__, __LINE__, __func__, fmt, data, sz, at, ##__VA_ARGS__)
|
||||||
|
+
|
||||||
|
#endif /* STATIC_HEXDUMP_H */
|
||||||
|
+// vim:fenc=utf-8:tw=75:noet
|
||||||
|
diff --git a/shim.h b/shim.h
|
||||||
|
index c1d7e7c7197..0b3ad4f2d20 100644
|
||||||
|
--- a/shim.h
|
||||||
|
+++ b/shim.h
|
||||||
|
@@ -182,8 +182,9 @@ typedef struct _SHIM_LOCK {
|
||||||
|
|
||||||
|
extern EFI_STATUS shim_init(void);
|
||||||
|
extern void shim_fini(void);
|
||||||
|
-extern EFI_STATUS LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...);
|
||||||
|
-extern EFI_STATUS VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args);
|
||||||
|
+extern EFI_STATUS LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...);
|
||||||
|
+extern EFI_STATUS VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args);
|
||||||
|
+extern VOID LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz);
|
||||||
|
extern VOID PrintErrors(VOID);
|
||||||
|
extern VOID ClearErrors(VOID);
|
||||||
|
extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,352 @@
|
|||||||
|
From fecc2dfb8e408526221091923d9345796b8e294e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 23 Jul 2020 22:09:03 -0400
|
||||||
|
Subject: [PATCH 61/62] Also use a config table to mirror mok variables.
|
||||||
|
|
||||||
|
Everything was going just fine until I made a vendor_db with 17kB of
|
||||||
|
sha256 sums in it. And then the same source tree that had worked fine
|
||||||
|
without that threw errors and failed all over the place. I wrote some
|
||||||
|
code to diagnose the problem, and of course it was a failure in
|
||||||
|
mirroring MokList to MokListRT.
|
||||||
|
|
||||||
|
As Patrick noted in 741c61abba7, some systems have obnoxiously low
|
||||||
|
amounts of variable storage available:
|
||||||
|
|
||||||
|
mok.c:550:import_mok_state() BS+RT variable info:
|
||||||
|
MaximumVariableStorageSize:0x000000000000DFE4
|
||||||
|
RemainingVariableStorageSize:0x000000000000D21C
|
||||||
|
MaximumVariableSize:0x0000000000001FC4
|
||||||
|
|
||||||
|
The most annoying part is that on at least this edk2 build,
|
||||||
|
SetVariable() /does actually appear to set the variable/, but it returns
|
||||||
|
EFI_INVALID_PARAMETER. I'm not planning on relying on that behavior.
|
||||||
|
|
||||||
|
So... yeah, the largest *volatile* (i.e. RAM only) variable this edk2
|
||||||
|
build will let you create is less than two pages. It's only got 7.9G
|
||||||
|
free, so I guess it's feeling like space is a little tight.
|
||||||
|
|
||||||
|
We're also not quite preserving that return code well enough for his
|
||||||
|
workaround to work.
|
||||||
|
|
||||||
|
New plan. We try to create variables the normal way, but we don't
|
||||||
|
consider not having enough space to be fatal. In that case, we create
|
||||||
|
an EFI_SECURITY_LIST with one sha256sum in it, with a value of all 0,
|
||||||
|
and try to add that so we're sure there's /something/ there that's
|
||||||
|
innocuous. On systems where the first SetVariable() /
|
||||||
|
QueryVariableInfo() lied to us, the correct variable should be there,
|
||||||
|
otherwise the one with the zero-hash will be.
|
||||||
|
|
||||||
|
We then also build a config table to hold this info and install that.
|
||||||
|
|
||||||
|
The config table is a packed array of this struct:
|
||||||
|
|
||||||
|
struct mok_variable_config_entry {
|
||||||
|
CHAR8 name[256];
|
||||||
|
UINT64 data_size;
|
||||||
|
UINT8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
There will be N+1 entries, and the last entry is all 0 for name and
|
||||||
|
data_size. The total allocation size will always be a multiple of 4096.
|
||||||
|
In the typical RHEL 7.9 case that means it'll be around 5 pages.
|
||||||
|
|
||||||
|
It's installed with this guid:
|
||||||
|
|
||||||
|
c451ed2b-9694-45d3-baba-ed9f8988a389
|
||||||
|
|
||||||
|
Anything that can go wrong will.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
Upstream: not yet, I don't want people to read this before Wednesday.
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
lib/guid.c | 2 +
|
||||||
|
mok.c | 150 ++++++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
include/guid.h | 2 +
|
||||||
|
3 files changed, 140 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/guid.c b/lib/guid.c
|
||||||
|
index 57c02fbeecd..99ff400a0ab 100644
|
||||||
|
--- a/lib/guid.c
|
||||||
|
+++ b/lib/guid.c
|
||||||
|
@@ -36,4 +36,6 @@ EFI_GUID EFI_SECURE_BOOT_DB_GUID = { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc,
|
||||||
|
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 } };
|
||||||
|
EFI_GUID SECURITY2_PROTOCOL_GUID = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
|
||||||
|
+
|
||||||
|
EFI_GUID SHIM_LOCK_GUID = {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } };
|
||||||
|
+EFI_GUID MOK_VARIABLE_STORE = {0xc451ed2b, 0x9694, 0x45d3, {0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89} };
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index e69857f3c37..4e141fb21fc 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -68,6 +68,7 @@ struct mok_state_variable {
|
||||||
|
CHAR16 *name;
|
||||||
|
char *name8;
|
||||||
|
CHAR16 *rtname;
|
||||||
|
+ char *rtname8;
|
||||||
|
EFI_GUID *guid;
|
||||||
|
|
||||||
|
UINT8 *data;
|
||||||
|
@@ -121,6 +122,7 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
{.name = L"MokList",
|
||||||
|
.name8 = "MokList",
|
||||||
|
.rtname = L"MokListRT",
|
||||||
|
+ .rtname8 = "MokListRT",
|
||||||
|
.guid = &SHIM_LOCK_GUID,
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
@@ -133,12 +135,14 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
.build_cert_size = &build_cert_size,
|
||||||
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
||||||
|
.flags = MOK_MIRROR_KEYDB |
|
||||||
|
+ MOK_MIRROR_DELETE_FIRST |
|
||||||
|
MOK_VARIABLE_LOG,
|
||||||
|
.pcr = 14,
|
||||||
|
},
|
||||||
|
{.name = L"MokListX",
|
||||||
|
.name8 = "MokListX",
|
||||||
|
.rtname = L"MokListXRT",
|
||||||
|
+ .rtname8 = "MokListXRT",
|
||||||
|
.guid = &SHIM_LOCK_GUID,
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
@@ -147,12 +151,14 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
.addend = &vendor_deauthorized,
|
||||||
|
.addend_size = &vendor_deauthorized_size,
|
||||||
|
.flags = MOK_MIRROR_KEYDB |
|
||||||
|
+ MOK_MIRROR_DELETE_FIRST |
|
||||||
|
MOK_VARIABLE_LOG,
|
||||||
|
.pcr = 14,
|
||||||
|
},
|
||||||
|
{.name = L"MokSBState",
|
||||||
|
.name8 = "MokSBState",
|
||||||
|
.rtname = L"MokSBStateRT",
|
||||||
|
+ .rtname8 = "MokSBStateRT",
|
||||||
|
.guid = &SHIM_LOCK_GUID,
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
@@ -166,6 +172,7 @@ struct mok_state_variable mok_state_variables[] = {
|
||||||
|
{.name = L"MokDBState",
|
||||||
|
.name8 = "MokDBState",
|
||||||
|
.rtname = L"MokIgnoreDB",
|
||||||
|
+ .rtname8 = "MokIgnoreDB",
|
||||||
|
.guid = &SHIM_LOCK_GUID,
|
||||||
|
.yes_attr = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE,
|
||||||
|
@@ -204,6 +211,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
* we're always mirroring the original data, whether this is an efi
|
||||||
|
* security database or not
|
||||||
|
*/
|
||||||
|
+ dprint(L"v->name:\"%s\" v->rtname:\"%s\"\n", v->name, v->rtname);
|
||||||
|
dprint(L"v->data_size:%lu v->data:0x%08llx\n", v->data_size, v->data);
|
||||||
|
dprint(L"FullDataSize:%lu FullData:0x%08llx\n", FullDataSize, FullData);
|
||||||
|
if (v->data_size) {
|
||||||
|
@@ -299,6 +307,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Now we have the full size
|
||||||
|
*/
|
||||||
|
@@ -417,28 +426,72 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
}
|
||||||
|
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%016llx p:0x%016llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
if (FullDataSize) {
|
||||||
|
- dprint(L"Setting %s with %lu bytes of data\n",
|
||||||
|
- v->rtname, FullDataSize);
|
||||||
|
+ uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
+ EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
+ uint64_t max_storage_sz = 0;
|
||||||
|
+ uint64_t remaining_sz = 0;
|
||||||
|
+ uint64_t max_var_sz = 0;
|
||||||
|
+ UINT8 *tmp = NULL;
|
||||||
|
+ UINTN tmpsz = 0;
|
||||||
|
+
|
||||||
|
+ efi_status = gRT->QueryVariableInfo(attrs, &max_storage_sz,
|
||||||
|
+ &remaining_sz, &max_var_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not get variable storage info: %r\n", efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ dprint(L"calling SetVariable(\"%s\", 0x%016llx, 0x%08lx, %lu, 0x%016llx)\n",
|
||||||
|
+ v->rtname, v->guid,
|
||||||
|
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
+ | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
efi_status = gRT->SetVariable(v->rtname, v->guid,
|
||||||
|
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
- EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
+ | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
FullDataSize, FullData);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Failed to set %s: %r\n",
|
||||||
|
- v->rtname, efi_status);
|
||||||
|
+ if (efi_status == EFI_INVALID_PARAMETER && max_var_sz < FullDataSize) {
|
||||||
|
+ /*
|
||||||
|
+ * In this case we're going to try to create a
|
||||||
|
+ * dummy variable so that there's one there. It
|
||||||
|
+ * may or may not work, because on some firmware
|
||||||
|
+ * builds when the SetVariable call above fails it
|
||||||
|
+ * does actually set the variable(!), so aside from
|
||||||
|
+ * not using the allocation if it doesn't work, we
|
||||||
|
+ * don't care about failures here.
|
||||||
|
+ */
|
||||||
|
+ console_print(L"WARNING: Maximum volatile variable size is %lu.\n", max_var_sz);
|
||||||
|
+ console_print(L"WARNING: Cannot set %s (%lu bytes)\n", v->rtname, FullDataSize);
|
||||||
|
+ perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
|
||||||
|
+ efi_status = variable_create_esl(
|
||||||
|
+ null_sha256, sizeof(null_sha256),
|
||||||
|
+ &EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
|
||||||
|
+ &tmp, &tmpsz);
|
||||||
|
+ /*
|
||||||
|
+ * from here we don't really care if it works or
|
||||||
|
+ * doens't.
|
||||||
|
+ */
|
||||||
|
+ if (!EFI_ERROR(efi_status) && tmp && tmpsz) {
|
||||||
|
+ gRT->SetVariable(v->rtname, v->guid,
|
||||||
|
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
+ | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ tmpsz, tmp);
|
||||||
|
+ FreePool(tmp);
|
||||||
|
+ }
|
||||||
|
+ efi_status = EFI_INVALID_PARAMETER;
|
||||||
|
+ } else if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (v->data && v->data_size) {
|
||||||
|
+ if (v->data && v->data_size && v->data != FullData) {
|
||||||
|
FreePool(v->data);
|
||||||
|
v->data = NULL;
|
||||||
|
v->data_size = 0;
|
||||||
|
}
|
||||||
|
- if (FullData && FullDataSize) {
|
||||||
|
- FreePool(FullData);
|
||||||
|
- }
|
||||||
|
+ v->data = FullData;
|
||||||
|
+ v->data_size = FullDataSize;
|
||||||
|
dprint(L"returning %r\n", efi_status);
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
@@ -454,8 +507,11 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
BOOLEAN present = FALSE;
|
||||||
|
|
||||||
|
if (v->rtname) {
|
||||||
|
- if (v->flags & MOK_MIRROR_DELETE_FIRST)
|
||||||
|
- LibDeleteVariable(v->rtname, v->guid);
|
||||||
|
+ if (v->flags & MOK_MIRROR_DELETE_FIRST) {
|
||||||
|
+ dprint(L"deleting \"%s\"\n", v->rtname);
|
||||||
|
+ efi_status = LibDeleteVariable(v->rtname, v->guid);
|
||||||
|
+ dprint(L"LibDeleteVariable(\"%s\",...) => %r\n", v->rtname, efi_status);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
efi_status = mirror_one_mok_variable(v);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
@@ -505,6 +561,12 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct mok_variable_config_entry {
|
||||||
|
+ CHAR8 name[256];
|
||||||
|
+ UINT64 data_size;
|
||||||
|
+ UINT8 data[];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Verify our non-volatile MoK state. This checks the variables above
|
||||||
|
* accessable and have valid attributes. If they don't, it removes
|
||||||
|
@@ -527,6 +589,11 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
user_insecure_mode = 0;
|
||||||
|
ignore_db = 0;
|
||||||
|
|
||||||
|
+ UINT64 config_sz = 0;
|
||||||
|
+ UINT8 *config_table = NULL;
|
||||||
|
+ size_t npages = 0;
|
||||||
|
+ struct mok_variable_config_entry config_template;
|
||||||
|
+
|
||||||
|
dprint(L"importing mok state\n");
|
||||||
|
for (i = 0; mok_state_variables[i].name != NULL; i++) {
|
||||||
|
struct mok_state_variable *v = &mok_state_variables[i];
|
||||||
|
@@ -579,6 +646,61 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = maybe_mirror_one_mok_variable(v, ret);
|
||||||
|
+ if (v->data && v->data_size) {
|
||||||
|
+ config_sz += v->data_size;
|
||||||
|
+ config_sz += sizeof(config_template);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Alright, so we're going to copy these to a config table. The
|
||||||
|
+ * table is a packed array of N+1 struct mok_variable_config_entry
|
||||||
|
+ * items, with the last item having all zero's in name and
|
||||||
|
+ * data_size.
|
||||||
|
+ */
|
||||||
|
+ if (config_sz) {
|
||||||
|
+ config_sz += sizeof(config_template);
|
||||||
|
+ npages = ALIGN_VALUE(config_sz, PAGE_SIZE) >> EFI_PAGE_SHIFT;
|
||||||
|
+ config_table = NULL;
|
||||||
|
+ efi_status = gBS->AllocatePages(AllocateAnyPages,
|
||||||
|
+ EfiRuntimeServicesData,
|
||||||
|
+ npages,
|
||||||
|
+ (EFI_PHYSICAL_ADDRESS *)&config_table);
|
||||||
|
+ if (EFI_ERROR(efi_status) || !config_table) {
|
||||||
|
+ console_print(L"Allocating %lu pages for mok config table failed: %r\n",
|
||||||
|
+ npages, efi_status);
|
||||||
|
+ if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
+ ret = efi_status;
|
||||||
|
+ config_table = NULL;
|
||||||
|
+ } else {
|
||||||
|
+ ZeroMem(config_table, npages << EFI_PAGE_SHIFT);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ UINT8 *p = (UINT8 *)config_table;
|
||||||
|
+ for (i = 0; p && mok_state_variables[i].name != NULL; i++) {
|
||||||
|
+ struct mok_state_variable *v = &mok_state_variables[i];
|
||||||
|
+
|
||||||
|
+ ZeroMem(&config_template, sizeof(config_template));
|
||||||
|
+ strncpya(config_template.name, (CHAR8 *)v->rtname8, 255);
|
||||||
|
+ config_template.name[255] = '\0';
|
||||||
|
+
|
||||||
|
+ config_template.data_size = v->data_size;
|
||||||
|
+
|
||||||
|
+ CopyMem(p, &config_template, sizeof(config_template));
|
||||||
|
+ p += sizeof(config_template);
|
||||||
|
+ CopyMem(p, v->data, v->data_size);
|
||||||
|
+ p += v->data_size;
|
||||||
|
+ }
|
||||||
|
+ if (p) {
|
||||||
|
+ ZeroMem(&config_template, sizeof(config_template));
|
||||||
|
+ CopyMem(p, &config_template, sizeof(config_template));
|
||||||
|
+
|
||||||
|
+ efi_status = gBS->InstallConfigurationTable(&MOK_VARIABLE_STORE,
|
||||||
|
+ config_table);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ console_print(L"Couldn't install MoK configuration table\n");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/include/guid.h b/include/guid.h
|
||||||
|
index 81689d6cc1a..91b14d96146 100644
|
||||||
|
--- a/include/guid.h
|
||||||
|
+++ b/include/guid.h
|
||||||
|
@@ -35,4 +35,6 @@ extern EFI_GUID SECURITY_PROTOCOL_GUID;
|
||||||
|
extern EFI_GUID SECURITY2_PROTOCOL_GUID;
|
||||||
|
extern EFI_GUID SHIM_LOCK_GUID;
|
||||||
|
|
||||||
|
+extern EFI_GUID MOK_VARIABLE_STORE;
|
||||||
|
+
|
||||||
|
#endif /* SHIM_GUID_H */
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
991
SOURCES/0062-Implement-lennysz-s-suggestions-for-MokListRT.patch
Normal file
991
SOURCES/0062-Implement-lennysz-s-suggestions-for-MokListRT.patch
Normal file
@ -0,0 +1,991 @@
|
|||||||
|
From 65be350308783a8ef537246c8ad0545b4e6ad069 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Sat, 25 Jul 2020 22:13:57 -0400
|
||||||
|
Subject: [PATCH 62/62] Implement lennysz's suggestions for MokListRT
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
mok.c | 726 ++++++++++++++++++++++++++++++++--------------
|
||||||
|
shim.c | 7 +-
|
||||||
|
include/PeImage.h | 3 +-
|
||||||
|
3 files changed, 515 insertions(+), 221 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mok.c b/mok.c
|
||||||
|
index 4e141fb21fc..3e6c7e43025 100644
|
||||||
|
--- a/mok.c
|
||||||
|
+++ b/mok.c
|
||||||
|
@@ -7,6 +7,8 @@
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
+#include "hexdump.h"
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Check if a variable exists
|
||||||
|
*/
|
||||||
|
@@ -25,6 +27,15 @@ static BOOLEAN check_var(CHAR16 *varname)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define SetVariable(name, guid, attrs, varsz, var) ({ \
|
||||||
|
+ EFI_STATUS efi_status_; \
|
||||||
|
+ efi_status_ = gRT->SetVariable(name, guid, attrs, varsz, var); \
|
||||||
|
+ dprint_(L"%a:%d:%a() SetVariable(\"%s\", ... varsz=0x%llx) = %r\n",\
|
||||||
|
+ __FILE__, __LINE__, __func__, \
|
||||||
|
+ name, varsz, efi_status_); \
|
||||||
|
+ efi_status_; \
|
||||||
|
+})
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* If the OS has set any of these variables we need to drop into MOK and
|
||||||
|
* handle them appropriately
|
||||||
|
@@ -193,33 +204,296 @@ should_mirror_build_cert(struct mok_state_variable *v)
|
||||||
|
|
||||||
|
static const uint8_t null_sha256[32] = { 0, };
|
||||||
|
|
||||||
|
+typedef UINTN SIZE_T;
|
||||||
|
+
|
||||||
|
+static EFI_STATUS
|
||||||
|
+get_max_var_sz(UINT32 attrs, SIZE_T *max_var_szp)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+ uint64_t max_storage_sz = 0;
|
||||||
|
+ uint64_t remaining_sz = 0;
|
||||||
|
+ uint64_t max_var_sz = 0;
|
||||||
|
+
|
||||||
|
+ *max_var_szp = 0;
|
||||||
|
+ efi_status = gRT->QueryVariableInfo(attrs, &max_storage_sz,
|
||||||
|
+ &remaining_sz, &max_var_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not get variable storage info: %r\n", efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * I just don't trust implementations to not be showing static data
|
||||||
|
+ * for max_var_sz
|
||||||
|
+ */
|
||||||
|
+ *max_var_szp = (max_var_sz < remaining_sz) ? max_var_sz : remaining_sz;
|
||||||
|
+ dprint("max_var_sz:%lx remaining_sz:%lx max_storage_sz:%lx\n",
|
||||||
|
+ max_var_sz, remaining_sz, max_storage_sz);
|
||||||
|
+ return efi_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * If any entries fit in < maxsz, and nothing goes wrong, create a variable
|
||||||
|
+ * of the given name and guid with as many esd entries as possible in it,
|
||||||
|
+ * and updates *esdp with what would be the next entry (even if makes *esdp
|
||||||
|
+ * > esl+esl->SignatureListSize), and returns whatever SetVariable()
|
||||||
|
+ * returns
|
||||||
|
+ *
|
||||||
|
+ * If no entries fit (i.e. sizeof(esl) + esl->SignatureSize > maxsz),
|
||||||
|
+ * returns EFI_BUFFER_TOO_SMALL;
|
||||||
|
+ */
|
||||||
|
+static EFI_STATUS
|
||||||
|
+mirror_one_esl(CHAR16 *name, EFI_GUID *guid, UINT32 attrs,
|
||||||
|
+ EFI_SIGNATURE_LIST *esl, EFI_SIGNATURE_DATA *esd,
|
||||||
|
+ UINTN *newsz, SIZE_T maxsz)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+ SIZE_T howmany, varsz = 0, esdsz;
|
||||||
|
+ UINT8 *var, *data;
|
||||||
|
+
|
||||||
|
+ howmany = min((maxsz - sizeof(*esl)) / esl->SignatureSize,
|
||||||
|
+ (esl->SignatureListSize - sizeof(*esl)) / esl->SignatureSize);
|
||||||
|
+ if (howmany < 1) {
|
||||||
|
+ return EFI_BUFFER_TOO_SMALL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We always assume esl->SignatureHeaderSize is 0 (and so far,
|
||||||
|
+ * that's true as per UEFI 2.8)
|
||||||
|
+ */
|
||||||
|
+ esdsz = howmany * esl->SignatureSize;
|
||||||
|
+ data = (UINT8 *)esd;
|
||||||
|
+ dprint(L"Trying to add %lx signatures to \"%s\" of size %lx\n",
|
||||||
|
+ howmany, name, esl->SignatureSize);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Because of the semantics of variable_create_esl(), the first
|
||||||
|
+ * owner guid from the data is not part of esdsz, or the data.
|
||||||
|
+ *
|
||||||
|
+ * Compensate here.
|
||||||
|
+ */
|
||||||
|
+ efi_status = variable_create_esl(data + sizeof(EFI_GUID),
|
||||||
|
+ esdsz - sizeof(EFI_GUID),
|
||||||
|
+ &esl->SignatureType,
|
||||||
|
+ &esd->SignatureOwner,
|
||||||
|
+ &var, &varsz);
|
||||||
|
+ if (EFI_ERROR(efi_status) || !var || !varsz) {
|
||||||
|
+ LogError(L"Couldn't allocate %lu bytes for mok variable \"%s\": %r\n",
|
||||||
|
+ varsz, var, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dprint(L"new esl:\n");
|
||||||
|
+ dhexdumpat(var, varsz, 0);
|
||||||
|
+
|
||||||
|
+ efi_status = SetVariable(name, guid, attrs, varsz, var);
|
||||||
|
+ FreePool(var);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ LogError(L"Couldn't create mok variable \"%s\": %r\n",
|
||||||
|
+ varsz, var, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *newsz = esdsz;
|
||||||
|
+
|
||||||
|
+ return efi_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static EFI_STATUS
|
||||||
|
+mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs,
|
||||||
|
+ UINT8 *FullData, SIZE_T FullDataSize, BOOLEAN only_first)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS efi_status = EFI_SUCCESS;
|
||||||
|
+ SIZE_T max_var_sz;
|
||||||
|
+
|
||||||
|
+ if (only_first) {
|
||||||
|
+ efi_status = get_max_var_sz(attrs, &max_var_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ LogError(L"Could not get maximum variable size: %r",
|
||||||
|
+ efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (FullDataSize <= max_var_sz) {
|
||||||
|
+ efi_status = SetVariable(name, guid, attrs,
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ CHAR16 *namen;
|
||||||
|
+ CHAR8 *namen8;
|
||||||
|
+ UINTN namelen, namesz;
|
||||||
|
+
|
||||||
|
+ namelen = StrLen(name);
|
||||||
|
+ namesz = namelen * 2;
|
||||||
|
+ if (only_first) {
|
||||||
|
+ namen = name;
|
||||||
|
+ namen8 = name8;
|
||||||
|
+ } else {
|
||||||
|
+ namelen += 18;
|
||||||
|
+ namesz += 34;
|
||||||
|
+ namen = AllocateZeroPool(namesz);
|
||||||
|
+ if (!namen) {
|
||||||
|
+ LogError(L"Could not allocate %lu bytes", namesz);
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ }
|
||||||
|
+ namen8 = AllocateZeroPool(namelen);
|
||||||
|
+ if (!namen8) {
|
||||||
|
+ FreePool(namen);
|
||||||
|
+ LogError(L"Could not allocate %lu bytes", namelen);
|
||||||
|
+ return EFI_OUT_OF_RESOURCES;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ UINTN pos, i;
|
||||||
|
+ const SIZE_T minsz = sizeof(EFI_SIGNATURE_LIST)
|
||||||
|
+ + sizeof(EFI_SIGNATURE_DATA)
|
||||||
|
+ + SHA1_DIGEST_SIZE;
|
||||||
|
+ BOOLEAN did_one = FALSE;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create any entries that can fit.
|
||||||
|
+ */
|
||||||
|
+ if (!only_first) {
|
||||||
|
+ dprint(L"full data for \"%s\":\n", name);
|
||||||
|
+ dhexdumpat(FullData, FullDataSize, 0);
|
||||||
|
+ }
|
||||||
|
+ EFI_SIGNATURE_LIST *esl = NULL;
|
||||||
|
+ UINTN esl_end_pos = 0;
|
||||||
|
+ for (i = 0, pos = 0; FullDataSize - pos >= minsz && FullData; ) {
|
||||||
|
+ EFI_SIGNATURE_DATA *esd = NULL;
|
||||||
|
+
|
||||||
|
+ dprint(L"pos:0x%llx FullDataSize:0x%llx\n", pos, FullDataSize);
|
||||||
|
+ if (esl == NULL || pos >= esl_end_pos) {
|
||||||
|
+ UINT8 *nesl = FullData + pos;
|
||||||
|
+ dprint(L"esl:0x%llx->0x%llx\n", esl, nesl);
|
||||||
|
+ esl = (EFI_SIGNATURE_LIST *)nesl;
|
||||||
|
+ esl_end_pos = pos + esl->SignatureListSize;
|
||||||
|
+ dprint(L"pos:0x%llx->0x%llx\n", pos, pos + sizeof(*esl));
|
||||||
|
+ pos += sizeof(*esl);
|
||||||
|
+ }
|
||||||
|
+ esd = (EFI_SIGNATURE_DATA *)(FullData + pos);
|
||||||
|
+ if (pos >= FullDataSize)
|
||||||
|
+ break;
|
||||||
|
+ if (esl->SignatureListSize == 0 || esl->SignatureSize == 0)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ dprint(L"esl[%lu] 0x%llx = {sls=0x%lx, ss=0x%lx} esd:0x%llx\n",
|
||||||
|
+ i, esl, esl->SignatureListSize, esl->SignatureSize, esd);
|
||||||
|
+
|
||||||
|
+ if (!only_first) {
|
||||||
|
+ SPrint(namen, namelen, L"%s%lu", name, i);
|
||||||
|
+ namen[namelen-1] = 0;
|
||||||
|
+ /* uggggh */
|
||||||
|
+ UINTN j;
|
||||||
|
+ for (j = 0; j < namelen; j++)
|
||||||
|
+ namen8[j] = (CHAR8)(namen[j] & 0xff);
|
||||||
|
+ namen8[namelen - 1] = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * In case max_var_sz is computed dynamically, refresh the
|
||||||
|
+ * value here.
|
||||||
|
+ */
|
||||||
|
+ efi_status = get_max_var_sz(attrs, &max_var_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ LogError(L"Could not get maximum variable size: %r",
|
||||||
|
+ efi_status);
|
||||||
|
+ if (!only_first) {
|
||||||
|
+ FreePool(namen);
|
||||||
|
+ FreePool(namen8);
|
||||||
|
+ }
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SIZE_T howmany;
|
||||||
|
+ UINTN adj = 0;
|
||||||
|
+ howmany = min((max_var_sz - sizeof(*esl)) / esl->SignatureSize,
|
||||||
|
+ (esl->SignatureListSize - sizeof(*esl)) / esl->SignatureSize);
|
||||||
|
+ if (!only_first && i == 0 && howmany >= 1) {
|
||||||
|
+ adj = howmany * esl->SignatureSize;
|
||||||
|
+ dprint(L"pos:0x%llx->0x%llx\n", pos, pos + adj);
|
||||||
|
+ pos += adj;
|
||||||
|
+ i++;
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ efi_status = mirror_one_esl(namen, guid, attrs,
|
||||||
|
+ esl, esd, &adj, max_var_sz);
|
||||||
|
+ dprint(L"esd:0x%llx adj:0x%llx\n", esd, adj);
|
||||||
|
+ if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
+ LogError(L"Could not mirror mok variable \"%s\": %r\n",
|
||||||
|
+ namen, efi_status);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!EFI_ERROR(efi_status)) {
|
||||||
|
+ did_one = TRUE;
|
||||||
|
+ if (only_first)
|
||||||
|
+ break;
|
||||||
|
+ dprint(L"pos:0x%llx->0x%llx\n", pos, pos + adj);
|
||||||
|
+ pos += adj;
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (only_first && !did_one) {
|
||||||
|
+ /*
|
||||||
|
+ * In this case we're going to try to create a
|
||||||
|
+ * dummy variable so that there's one there. It
|
||||||
|
+ * may or may not work, because on some firmware
|
||||||
|
+ * builds when the SetVariable call above fails it
|
||||||
|
+ * does actually set the variable(!), so aside from
|
||||||
|
+ * not using the allocation if it doesn't work, we
|
||||||
|
+ * don't care about failures here.
|
||||||
|
+ */
|
||||||
|
+ UINT8 *var;
|
||||||
|
+ UINTN varsz;
|
||||||
|
+
|
||||||
|
+ efi_status = variable_create_esl(
|
||||||
|
+ null_sha256, sizeof(null_sha256),
|
||||||
|
+ &EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
|
||||||
|
+ &var, &varsz);
|
||||||
|
+ /*
|
||||||
|
+ * from here we don't really care if it works or
|
||||||
|
+ * doesn't.
|
||||||
|
+ */
|
||||||
|
+ if (!EFI_ERROR(efi_status) && var && varsz) {
|
||||||
|
+ SetVariable(name, guid,
|
||||||
|
+ EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
+ | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
+ varsz, var);
|
||||||
|
+ FreePool(var);
|
||||||
|
+ }
|
||||||
|
+ efi_status = EFI_INVALID_PARAMETER;
|
||||||
|
+ } else if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to set %s: %r\n", name, efi_status);
|
||||||
|
+ }
|
||||||
|
+ return efi_status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static EFI_STATUS nonnull(1)
|
||||||
|
-mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
+mirror_one_mok_variable(struct mok_state_variable *v,
|
||||||
|
+ BOOLEAN only_first)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status = EFI_SUCCESS;
|
||||||
|
uint8_t *FullData = NULL;
|
||||||
|
size_t FullDataSize = 0;
|
||||||
|
vendor_addend_category_t addend_category = VENDOR_ADDEND_NONE;
|
||||||
|
uint8_t *p = NULL;
|
||||||
|
-
|
||||||
|
+ uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
+ EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
+ BOOLEAN measure = v->flags & MOK_VARIABLE_MEASURE;
|
||||||
|
+ BOOLEAN log = v->flags & MOK_VARIABLE_LOG;
|
||||||
|
size_t build_cert_esl_sz = 0, addend_esl_sz = 0;
|
||||||
|
+ bool reuse = FALSE;
|
||||||
|
|
||||||
|
if (v->categorize_addend)
|
||||||
|
addend_category = v->categorize_addend(v);
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * we're always mirroring the original data, whether this is an efi
|
||||||
|
- * security database or not
|
||||||
|
- */
|
||||||
|
- dprint(L"v->name:\"%s\" v->rtname:\"%s\"\n", v->name, v->rtname);
|
||||||
|
- dprint(L"v->data_size:%lu v->data:0x%08llx\n", v->data_size, v->data);
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n", FullDataSize, FullData);
|
||||||
|
- if (v->data_size) {
|
||||||
|
- FullDataSize = v->data_size;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
- FullDataSize, FullData);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* if it is, there's more data
|
||||||
|
*/
|
||||||
|
@@ -227,7 +501,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're mirroring (into) an efi security database, aka an
|
||||||
|
- * array of efi_signature_list_t. Its layout goes like:
|
||||||
|
+ * array of EFI_SIGNATURE_LIST. Its layout goes like:
|
||||||
|
*
|
||||||
|
* existing_variable_data
|
||||||
|
* existing_variable_data_size
|
||||||
|
@@ -251,30 +525,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * first bit is existing data, but we added that above
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * then the build cert if it's there
|
||||||
|
- */
|
||||||
|
- if (should_mirror_build_cert(v)) {
|
||||||
|
- efi_status = fill_esl(*v->build_cert,
|
||||||
|
- *v->build_cert_size,
|
||||||
|
- &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
- &SHIM_LOCK_GUID,
|
||||||
|
- NULL, &build_cert_esl_sz);
|
||||||
|
- if (efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
- perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
- v->name, efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
- }
|
||||||
|
- FullDataSize += build_cert_esl_sz;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
- FullDataSize, FullData);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * then the addend data
|
||||||
|
+ * *first* vendor_db or vendor_cert
|
||||||
|
*/
|
||||||
|
switch (addend_category) {
|
||||||
|
case VENDOR_ADDEND_DB:
|
||||||
|
@@ -282,7 +533,7 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
* if it's an ESL already, we use it wholesale
|
||||||
|
*/
|
||||||
|
FullDataSize += *v->addend_size;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx\n",
|
||||||
|
FullDataSize, FullData);
|
||||||
|
break;
|
||||||
|
case VENDOR_ADDEND_X509:
|
||||||
|
@@ -296,17 +547,51 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
FullDataSize += addend_esl_sz;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx\n",
|
||||||
|
FullDataSize, FullData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case VENDOR_ADDEND_NONE:
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx\n",
|
||||||
|
FullDataSize, FullData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * then the build cert if it's there
|
||||||
|
+ */
|
||||||
|
+ if (should_mirror_build_cert(v)) {
|
||||||
|
+ efi_status = fill_esl(*v->build_cert,
|
||||||
|
+ *v->build_cert_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ NULL, &build_cert_esl_sz);
|
||||||
|
+ if (efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ FullDataSize += build_cert_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:0x%lx FullData:0x%llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * we're always mirroring the original data, whether this is an efi
|
||||||
|
+ * security database or not
|
||||||
|
+ */
|
||||||
|
+ dprint(L"v->name:\"%s\" v->rtname:\"%s\"\n", v->name, v->rtname);
|
||||||
|
+ dprint(L"v->data_size:%lu v->data:0x%llx\n", v->data_size, v->data);
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx\n", FullDataSize, FullData);
|
||||||
|
+ if (v->data_size) {
|
||||||
|
+ FullDataSize += v->data_size;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx\n",
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ }
|
||||||
|
+ if (v->data_size == FullDataSize)
|
||||||
|
+ reuse = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we have the full size
|
||||||
|
@@ -316,38 +601,33 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
* allocate the buffer, or use the old one if it's just the
|
||||||
|
* existing data.
|
||||||
|
*/
|
||||||
|
- if (FullDataSize != v->data_size) {
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx allocating FullData\n",
|
||||||
|
+ if (FullDataSize == v->data_size) {
|
||||||
|
+ FullData = v->data;
|
||||||
|
+ FullDataSize = v->data_size;
|
||||||
|
+ p = FullData + FullDataSize;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ } else {
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx allocating FullData\n",
|
||||||
|
FullDataSize, FullData);
|
||||||
|
- FullData = AllocatePool(FullDataSize);
|
||||||
|
+ /*
|
||||||
|
+ * make sure we've got some zeroes at the end, just
|
||||||
|
+ * in case.
|
||||||
|
+ */
|
||||||
|
+ UINTN allocsz = FullDataSize + sizeof(EFI_SIGNATURE_LIST);
|
||||||
|
+ allocsz = ALIGN_VALUE(allocsz, 4096);
|
||||||
|
+ FullData = AllocateZeroPool(FullDataSize);
|
||||||
|
if (!FullData) {
|
||||||
|
- FreePool(v->data);
|
||||||
|
- v->data = NULL;
|
||||||
|
- v->data_size = 0;
|
||||||
|
perror(L"Failed to allocate %lu bytes for %s\n",
|
||||||
|
FullDataSize, v->name);
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
p = FullData;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
- FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- if (v->data && v->data_size) {
|
||||||
|
- CopyMem(p, v->data, v->data_size);
|
||||||
|
- p += v->data_size;
|
||||||
|
- }
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
- FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- } else {
|
||||||
|
- FullData = v->data;
|
||||||
|
- FullDataSize = v->data_size;
|
||||||
|
- p = FullData + FullDataSize;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
- FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- v->data = NULL;
|
||||||
|
- v->data_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -355,35 +635,13 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
*/
|
||||||
|
if (v->flags & MOK_MIRROR_KEYDB) {
|
||||||
|
/*
|
||||||
|
- * first bit is existing data, but again, we added that above
|
||||||
|
+ * first vendor_cert or vendor_db
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * second is the build cert
|
||||||
|
- */
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
- FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- if (should_mirror_build_cert(v)) {
|
||||||
|
- efi_status = fill_esl(*v->build_cert,
|
||||||
|
- *v->build_cert_size,
|
||||||
|
- &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
- &SHIM_LOCK_GUID,
|
||||||
|
- p, &build_cert_esl_sz);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
- v->name, efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
- }
|
||||||
|
- p += build_cert_esl_sz;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
- FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
switch (addend_category) {
|
||||||
|
case VENDOR_ADDEND_DB:
|
||||||
|
CopyMem(p, *v->addend, *v->addend_size);
|
||||||
|
p += *v->addend_size;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
break;
|
||||||
|
case VENDOR_ADDEND_X509:
|
||||||
|
@@ -397,16 +655,53 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
p += addend_esl_sz;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case VENDOR_ADDEND_NONE:
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * then is the build cert
|
||||||
|
+ */
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ if (should_mirror_build_cert(v)) {
|
||||||
|
+ efi_status = fill_esl(*v->build_cert,
|
||||||
|
+ *v->build_cert_size,
|
||||||
|
+ &EFI_CERT_TYPE_X509_GUID,
|
||||||
|
+ &SHIM_LOCK_GUID,
|
||||||
|
+ p, &build_cert_esl_sz);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not add built-in cert to %s: %r\n",
|
||||||
|
+ v->name, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ p += build_cert_esl_sz;
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * last bit is existing data, unless it's the only thing,
|
||||||
|
+ * in which case it's already there.
|
||||||
|
+ */
|
||||||
|
+ if (!reuse) {
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ if (v->data && v->data_size) {
|
||||||
|
+ CopyMem(p, v->data, v->data_size);
|
||||||
|
+ p += v->data_size;
|
||||||
|
+ }
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
+ FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* We always want to create our key databases, so in this case we
|
||||||
|
* need a dummy entry
|
||||||
|
@@ -422,68 +717,55 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
return efi_status;
|
||||||
|
}
|
||||||
|
p = FullData + FullDataSize;
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%08llx p:0x%08llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
}
|
||||||
|
|
||||||
|
- dprint(L"FullDataSize:%lu FullData:0x%016llx p:0x%016llx pos:%lld\n",
|
||||||
|
+ dprint(L"FullDataSize:%lu FullData:0x%llx p:0x%llx pos:%lld\n",
|
||||||
|
FullDataSize, FullData, p, p-(uintptr_t)FullData);
|
||||||
|
- if (FullDataSize) {
|
||||||
|
- uint32_t attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
- EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
- uint64_t max_storage_sz = 0;
|
||||||
|
- uint64_t remaining_sz = 0;
|
||||||
|
- uint64_t max_var_sz = 0;
|
||||||
|
- UINT8 *tmp = NULL;
|
||||||
|
- UINTN tmpsz = 0;
|
||||||
|
-
|
||||||
|
- efi_status = gRT->QueryVariableInfo(attrs, &max_storage_sz,
|
||||||
|
- &remaining_sz, &max_var_sz);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Could not get variable storage info: %r\n", efi_status);
|
||||||
|
- return efi_status;
|
||||||
|
- }
|
||||||
|
- dprint(L"calling SetVariable(\"%s\", 0x%016llx, 0x%08lx, %lu, 0x%016llx)\n",
|
||||||
|
- v->rtname, v->guid,
|
||||||
|
- EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
- | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
- FullDataSize, FullData);
|
||||||
|
- efi_status = gRT->SetVariable(v->rtname, v->guid,
|
||||||
|
- EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
- | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
- FullDataSize, FullData);
|
||||||
|
- if (efi_status == EFI_INVALID_PARAMETER && max_var_sz < FullDataSize) {
|
||||||
|
+ if (FullDataSize && v->flags & MOK_MIRROR_KEYDB) {
|
||||||
|
+ dprint(L"calling mirror_mok_db(\"%s\", datasz=%lu)\n",
|
||||||
|
+ v->rtname, FullDataSize);
|
||||||
|
+ efi_status = mirror_mok_db(v->rtname, (CHAR8 *)v->rtname8, v->guid,
|
||||||
|
+ attrs, FullData, FullDataSize,
|
||||||
|
+ only_first);
|
||||||
|
+ dprint(L"mirror_mok_db(\"%s\", datasz=%lu) returned %r\n",
|
||||||
|
+ v->rtname, FullDataSize, efi_status);
|
||||||
|
+ } else if (FullDataSize && only_first) {
|
||||||
|
+ efi_status = SetVariable(v->rtname, v->guid, attrs,
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ }
|
||||||
|
+ if (FullDataSize && only_first) {
|
||||||
|
+ if (measure) {
|
||||||
|
/*
|
||||||
|
- * In this case we're going to try to create a
|
||||||
|
- * dummy variable so that there's one there. It
|
||||||
|
- * may or may not work, because on some firmware
|
||||||
|
- * builds when the SetVariable call above fails it
|
||||||
|
- * does actually set the variable(!), so aside from
|
||||||
|
- * not using the allocation if it doesn't work, we
|
||||||
|
- * don't care about failures here.
|
||||||
|
+ * Measure this into PCR 7 in the Microsoft format
|
||||||
|
*/
|
||||||
|
- console_print(L"WARNING: Maximum volatile variable size is %lu.\n", max_var_sz);
|
||||||
|
- console_print(L"WARNING: Cannot set %s (%lu bytes)\n", v->rtname, FullDataSize);
|
||||||
|
- perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
|
||||||
|
- efi_status = variable_create_esl(
|
||||||
|
- null_sha256, sizeof(null_sha256),
|
||||||
|
- &EFI_CERT_SHA256_GUID, &SHIM_LOCK_GUID,
|
||||||
|
- &tmp, &tmpsz);
|
||||||
|
+ efi_status = tpm_measure_variable(v->name, *v->guid,
|
||||||
|
+ FullDataSize, FullData);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ dprint(L"tpm_measure_variable(\"%s\",%lu,0x%llx)->%r\n",
|
||||||
|
+ v->name, FullDataSize, FullData, efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (log) {
|
||||||
|
/*
|
||||||
|
- * from here we don't really care if it works or
|
||||||
|
- * doens't.
|
||||||
|
+ * Log this variable into whichever PCR the table
|
||||||
|
+ * says.
|
||||||
|
*/
|
||||||
|
- if (!EFI_ERROR(efi_status) && tmp && tmpsz) {
|
||||||
|
- gRT->SetVariable(v->rtname, v->guid,
|
||||||
|
- EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
|
- | EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
|
- tmpsz, tmp);
|
||||||
|
- FreePool(tmp);
|
||||||
|
+ EFI_PHYSICAL_ADDRESS datap =
|
||||||
|
+ (EFI_PHYSICAL_ADDRESS)(UINTN)FullData,
|
||||||
|
+ efi_status = tpm_log_event(datap, FullDataSize,
|
||||||
|
+ v->pcr, (CHAR8 *)v->name8);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ dprint(L"tpm_log_event(0x%llx, %lu, %lu, \"%s\")->%r\n",
|
||||||
|
+ FullData, FullDataSize, v->pcr, v->name,
|
||||||
|
+ efi_status);
|
||||||
|
+ return efi_status;
|
||||||
|
}
|
||||||
|
- efi_status = EFI_INVALID_PARAMETER;
|
||||||
|
- } else if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Failed to set %s: %r\n", v->rtname, efi_status);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
}
|
||||||
|
if (v->data && v->data_size && v->data != FullData) {
|
||||||
|
FreePool(v->data);
|
||||||
|
@@ -501,19 +783,20 @@ mirror_one_mok_variable(struct mok_state_variable *v)
|
||||||
|
* EFI_SECURITY_VIOLATION status at the same time.
|
||||||
|
*/
|
||||||
|
static EFI_STATUS nonnull(1)
|
||||||
|
-maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
+maybe_mirror_one_mok_variable(struct mok_state_variable *v,
|
||||||
|
+ EFI_STATUS ret, BOOLEAN only_first)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
BOOLEAN present = FALSE;
|
||||||
|
|
||||||
|
if (v->rtname) {
|
||||||
|
- if (v->flags & MOK_MIRROR_DELETE_FIRST) {
|
||||||
|
+ if (!only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) {
|
||||||
|
dprint(L"deleting \"%s\"\n", v->rtname);
|
||||||
|
efi_status = LibDeleteVariable(v->rtname, v->guid);
|
||||||
|
dprint(L"LibDeleteVariable(\"%s\",...) => %r\n", v->rtname, efi_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
- efi_status = mirror_one_mok_variable(v);
|
||||||
|
+ efi_status = mirror_one_mok_variable(v, only_first);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
ret = efi_status;
|
||||||
|
@@ -530,34 +813,6 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, EFI_STATUS ret)
|
||||||
|
*v->state = v->data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (v->flags & MOK_VARIABLE_MEASURE) {
|
||||||
|
- /*
|
||||||
|
- * Measure this into PCR 7 in the Microsoft format
|
||||||
|
- */
|
||||||
|
- efi_status = tpm_measure_variable(v->name, *v->guid,
|
||||||
|
- v->data_size,
|
||||||
|
- v->data);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
- ret = efi_status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (v->flags & MOK_VARIABLE_LOG) {
|
||||||
|
- /*
|
||||||
|
- * Log this variable into whichever PCR the table
|
||||||
|
- * says.
|
||||||
|
- */
|
||||||
|
- EFI_PHYSICAL_ADDRESS datap =
|
||||||
|
- (EFI_PHYSICAL_ADDRESS)(UINTN)v->data,
|
||||||
|
- efi_status = tpm_log_event(datap, v->data_size,
|
||||||
|
- v->pcr, (CHAR8 *)v->name8);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
- ret = efi_status;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -567,6 +822,66 @@ struct mok_variable_config_entry {
|
||||||
|
UINT8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
+EFI_STATUS import_one_mok_state(struct mok_state_variable *v,
|
||||||
|
+ BOOLEAN only_first)
|
||||||
|
+{
|
||||||
|
+ EFI_STATUS ret = EFI_SUCCESS;
|
||||||
|
+ EFI_STATUS efi_status;
|
||||||
|
+
|
||||||
|
+ user_insecure_mode = 0;
|
||||||
|
+ ignore_db = 0;
|
||||||
|
+
|
||||||
|
+ UINT32 attrs = 0;
|
||||||
|
+ BOOLEAN delete = FALSE;
|
||||||
|
+
|
||||||
|
+ dprint(L"importing mok state for \"%s\"\n", v->name);
|
||||||
|
+
|
||||||
|
+ efi_status = get_variable_attr(v->name,
|
||||||
|
+ &v->data, &v->data_size,
|
||||||
|
+ *v->guid, &attrs);
|
||||||
|
+ if (efi_status == EFI_NOT_FOUND) {
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ } else if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Could not verify %s: %r\n", v->name,
|
||||||
|
+ efi_status);
|
||||||
|
+ delete = TRUE;
|
||||||
|
+ } else {
|
||||||
|
+ if (!(attrs & v->yes_attr)) {
|
||||||
|
+ perror(L"Variable %s is missing attributes:\n",
|
||||||
|
+ v->name);
|
||||||
|
+ perror(L" 0x%08x should have 0x%08x set.\n",
|
||||||
|
+ attrs, v->yes_attr);
|
||||||
|
+ delete = TRUE;
|
||||||
|
+ }
|
||||||
|
+ if (attrs & v->no_attr) {
|
||||||
|
+ perror(L"Variable %s has incorrect attribute:\n",
|
||||||
|
+ v->name);
|
||||||
|
+ perror(L" 0x%08x should not have 0x%08x set.\n",
|
||||||
|
+ attrs, v->no_attr);
|
||||||
|
+ delete = TRUE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (delete == TRUE) {
|
||||||
|
+ perror(L"Deleting bad variable %s\n", v->name);
|
||||||
|
+ efi_status = LibDeleteVariable(v->name, v->guid);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ perror(L"Failed to erase %s\n", v->name);
|
||||||
|
+ ret = EFI_SECURITY_VIOLATION;
|
||||||
|
+ }
|
||||||
|
+ FreePool(v->data);
|
||||||
|
+ v->data = NULL;
|
||||||
|
+ v->data_size = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dprint(L"maybe mirroring \"%s\". original data:\n", v->name);
|
||||||
|
+ dhexdumpat(v->data, v->data_size, 0);
|
||||||
|
+
|
||||||
|
+ ret = maybe_mirror_one_mok_variable(v, ret, only_first);
|
||||||
|
+ dprint(L"returning %r\n", ret);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Verify our non-volatile MoK state. This checks the variables above
|
||||||
|
* accessable and have valid attributes. If they don't, it removes
|
||||||
|
@@ -594,58 +909,22 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
size_t npages = 0;
|
||||||
|
struct mok_variable_config_entry config_template;
|
||||||
|
|
||||||
|
- dprint(L"importing mok state\n");
|
||||||
|
+ dprint(L"importing minimal mok state variables\n");
|
||||||
|
for (i = 0; mok_state_variables[i].name != NULL; i++) {
|
||||||
|
struct mok_state_variable *v = &mok_state_variables[i];
|
||||||
|
- UINT32 attrs = 0;
|
||||||
|
- BOOLEAN delete = FALSE;
|
||||||
|
|
||||||
|
- efi_status = get_variable_attr(v->name,
|
||||||
|
- &v->data, &v->data_size,
|
||||||
|
- *v->guid, &attrs);
|
||||||
|
- dprint(L"maybe mirroring %s\n", v->name);
|
||||||
|
- if (efi_status == EFI_NOT_FOUND) {
|
||||||
|
- v->data = NULL;
|
||||||
|
- v->data_size = 0;
|
||||||
|
- } else if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Could not verify %s: %r\n", v->name,
|
||||||
|
- efi_status);
|
||||||
|
+ efi_status = import_one_mok_state(v, TRUE);
|
||||||
|
+ if (EFI_ERROR(efi_status)) {
|
||||||
|
+ dprint(L"import_one_mok_state(ih, \"%s\", TRUE): %r\n",
|
||||||
|
+ v->rtname);
|
||||||
|
/*
|
||||||
|
* don't clobber EFI_SECURITY_VIOLATION from some
|
||||||
|
* other variable in the list.
|
||||||
|
*/
|
||||||
|
if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
ret = efi_status;
|
||||||
|
- delete = TRUE;
|
||||||
|
- } else {
|
||||||
|
- if (!(attrs & v->yes_attr)) {
|
||||||
|
- perror(L"Variable %s is missing attributes:\n",
|
||||||
|
- v->name);
|
||||||
|
- perror(L" 0x%08x should have 0x%08x set.\n",
|
||||||
|
- attrs, v->yes_attr);
|
||||||
|
- delete = TRUE;
|
||||||
|
- }
|
||||||
|
- if (attrs & v->no_attr) {
|
||||||
|
- perror(L"Variable %s has incorrect attribute:\n",
|
||||||
|
- v->name);
|
||||||
|
- perror(L" 0x%08x should not have 0x%08x set.\n",
|
||||||
|
- attrs, v->no_attr);
|
||||||
|
- delete = TRUE;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (delete == TRUE) {
|
||||||
|
- perror(L"Deleting bad variable %s\n", v->name);
|
||||||
|
- efi_status = LibDeleteVariable(v->name, v->guid);
|
||||||
|
- if (EFI_ERROR(efi_status)) {
|
||||||
|
- perror(L"Failed to erase %s\n", v->name);
|
||||||
|
- ret = EFI_SECURITY_VIOLATION;
|
||||||
|
- }
|
||||||
|
- FreePool(v->data);
|
||||||
|
- v->data = NULL;
|
||||||
|
- v->data_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = maybe_mirror_one_mok_variable(v, ret);
|
||||||
|
if (v->data && v->data_size) {
|
||||||
|
config_sz += v->data_size;
|
||||||
|
config_sz += sizeof(config_template);
|
||||||
|
@@ -669,8 +948,6 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
if (EFI_ERROR(efi_status) || !config_table) {
|
||||||
|
console_print(L"Allocating %lu pages for mok config table failed: %r\n",
|
||||||
|
npages, efi_status);
|
||||||
|
- if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
- ret = efi_status;
|
||||||
|
config_table = NULL;
|
||||||
|
} else {
|
||||||
|
ZeroMem(config_table, npages << EFI_PAGE_SHIFT);
|
||||||
|
@@ -703,6 +980,16 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * This is really just to make it easy for userland.
|
||||||
|
+ */
|
||||||
|
+ dprint(L"importing full mok state variables\n");
|
||||||
|
+ for (i = 0; mok_state_variables[i].name != NULL; i++) {
|
||||||
|
+ struct mok_state_variable *v = &mok_state_variables[i];
|
||||||
|
+
|
||||||
|
+ import_one_mok_state(v, FALSE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Enter MokManager if necessary. Any actual *changes* here will
|
||||||
|
* cause MokManager to demand a machine reboot, so this is safe to
|
||||||
|
@@ -712,6 +999,9 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||||
|
efi_status = check_mok_request(image_handle);
|
||||||
|
dprint(L"mok returned %r\n", efi_status);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
+ /*
|
||||||
|
+ * don't clobber EFI_SECURITY_VIOLATION
|
||||||
|
+ */
|
||||||
|
if (ret != EFI_SECURITY_VIOLATION)
|
||||||
|
ret = efi_status;
|
||||||
|
return ret;
|
||||||
|
diff --git a/shim.c b/shim.c
|
||||||
|
index 9248642bd57..1a4d7bb9ded 100644
|
||||||
|
--- a/shim.c
|
||||||
|
+++ b/shim.c
|
||||||
|
@@ -1445,7 +1445,10 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
|
||||||
|
sha256hash, sha1hash);
|
||||||
|
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
- console_error(L"Verification failed", efi_status);
|
||||||
|
+ if (verbose)
|
||||||
|
+ console_print(L"Verification failed: %r\n", efi_status);
|
||||||
|
+ else
|
||||||
|
+ console_error(L"Verification failed", efi_status);
|
||||||
|
return efi_status;
|
||||||
|
} else {
|
||||||
|
if (verbose)
|
||||||
|
@@ -2648,7 +2651,6 @@ shim_init(void)
|
||||||
|
{
|
||||||
|
EFI_STATUS efi_status;
|
||||||
|
|
||||||
|
- setup_verbosity();
|
||||||
|
dprint(L"%a", shim_version);
|
||||||
|
|
||||||
|
/* Set the second stage loader */
|
||||||
|
@@ -2797,6 +2799,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
||||||
|
* Ensure that gnu-efi functions are available
|
||||||
|
*/
|
||||||
|
InitializeLib(image_handle, systab);
|
||||||
|
+ setup_verbosity();
|
||||||
|
|
||||||
|
dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
|
||||||
|
__FILE__, __LINE__, __func__, vendor_authorized, vendor_authorized_size);
|
||||||
|
diff --git a/include/PeImage.h b/include/PeImage.h
|
||||||
|
index a606e8b2a9f..209b96fb8ff 100644
|
||||||
|
--- a/include/PeImage.h
|
||||||
|
+++ b/include/PeImage.h
|
||||||
|
@@ -768,7 +768,8 @@ typedef struct {
|
||||||
|
UINT8 CertData[1];
|
||||||
|
} WIN_CERTIFICATE_EFI_PKCS;
|
||||||
|
|
||||||
|
-#define SHA256_DIGEST_SIZE 32
|
||||||
|
+#define SHA1_DIGEST_SIZE 20
|
||||||
|
+#define SHA256_DIGEST_SIZE 32
|
||||||
|
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
BIN
SOURCES/redhatsecurebootca5.cer
Normal file
BIN
SOURCES/redhatsecurebootca5.cer
Normal file
Binary file not shown.
Binary file not shown.
@ -18,23 +18,81 @@
|
|||||||
|
|
||||||
Name: shim-unsigned-%{efiarch}
|
Name: shim-unsigned-%{efiarch}
|
||||||
Version: 15
|
Version: 15
|
||||||
Release: 2%{?dist}
|
Release: 7%{?dist}
|
||||||
Summary: First-stage UEFI bootloader
|
Summary: First-stage UEFI bootloader
|
||||||
ExclusiveArch: x86_64
|
ExclusiveArch: x86_64
|
||||||
License: BSD
|
License: BSD
|
||||||
URL: https://github.com/rhboot/shim
|
URL: https://github.com/rhboot/shim
|
||||||
Source0: https://github.com/rhboot/shim/releases/download/%{version}/shim-%{version}.tar.bz2
|
Source0: https://github.com/rhboot/shim/releases/download/%{version}/shim-%{version}.tar.bz2
|
||||||
Source1: securebootca.cer
|
Source1: redhatsecurebootca5.cer
|
||||||
# currently here's what's in our dbx:
|
# currently here's what's in our dbx:
|
||||||
# nothing.
|
# nothing.
|
||||||
Source2: dbx.esl
|
Source2: dbx.esl
|
||||||
|
|
||||||
Source100: shim-find-debuginfo.sh
|
Source100: shim-find-debuginfo.sh
|
||||||
|
|
||||||
Patch0001: 0001-Make-sure-that-MOK-variables-always-get-mirrored.patch
|
Patch0001: 0001-Make-some-things-dprint-instead-of-console_print.patch
|
||||||
Patch0002: 0002-mok-fix-the-mirroring-of-RT-variables.patch
|
Patch0002: 0002-Makefiles-ensure-m32-gets-propogated-to-our-gcc-para.patch
|
||||||
Patch0003: 0003-mok-consolidate-mirroring-code-in-a-helper-instead-o.patch
|
Patch0003: 0003-Let-MokManager-follow-a-MokTimeout-var-for-timeout-l.patch
|
||||||
Patch0004: 0004-Make-VLogError-behave-as-expected.patch
|
Patch0004: 0004-httpboot-return-EFI_NOT_FOUND-when-it-fails-to-find-.patch
|
||||||
|
Patch0005: 0005-httpboot-print-more-messages-when-it-fails-to-set-IP.patch
|
||||||
|
Patch0006: 0006-httpboot-allow-the-IPv4-gateway-to-be-empty.patch
|
||||||
|
Patch0007: 0007-httpboot-show-the-error-message-for-the-ChildHandle.patch
|
||||||
|
Patch0008: 0008-Fix-typo-in-debug-path-in-shim.h.patch
|
||||||
|
Patch0009: 0009-MokManager-Stop-using-EFI_VARIABLE_APPEND_WRITE.patch
|
||||||
|
Patch0010: 0010-shim-Extend-invalid-reloc-size-warning-message.patch
|
||||||
|
Patch0011: 0011-Add-GRUB-s-PCR-Usage-to-README.tpm.patch
|
||||||
|
Patch0012: 0012-Fix-the-compile-error-of-mkdir-wrong-directory.patch
|
||||||
|
Patch0013: 0013-shim-Properly-generate-absolute-paths-from-relative-.patch
|
||||||
|
Patch0014: 0014-shim-Prevent-shim-to-set-itself-as-a-second-stage-lo.patch
|
||||||
|
Patch0015: 0015-Fix-for-Section-0-has-negative-size-error-when-loadi.patch
|
||||||
|
Patch0016: 0016-Fix-apparent-typo-in-ARM-32-on-64-code.patch
|
||||||
|
Patch0017: 0017-Makefile-do-not-run-git-on-clean-if-there-s-no-.git-.patch
|
||||||
|
Patch0018: 0018-Make.default-use-correct-flags-to-disable-unaligned-.patch
|
||||||
|
Patch0019: 0019-Cryptlib-fix-build-on-32bit-ARM.patch
|
||||||
|
Patch0020: 0020-Make-sure-that-MOK-variables-always-get-mirrored.patch
|
||||||
|
Patch0021: 0021-mok-fix-the-mirroring-of-RT-variables.patch
|
||||||
|
Patch0022: 0022-mok-consolidate-mirroring-code-in-a-helper-instead-o.patch
|
||||||
|
Patch0023: 0023-shim-only-include-shim_cert.h-in-shim.c.patch
|
||||||
|
Patch0024: 0024-mok-also-mirror-the-build-cert-to-MokListRT.patch
|
||||||
|
Patch0025: 0025-mok-minor-cleanups.patch
|
||||||
|
Patch0026: 0026-Remove-call-to-TPM2-get_event_log.patch
|
||||||
|
Patch0027: 0027-Make-EFI-variable-copying-fatal-only-on-secureboot-e.patch
|
||||||
|
Patch0028: 0028-VLogError-Avoid-NULL-pointer-dereferences-in-V-Sprin.patch
|
||||||
|
Patch0029: 0029-Once-again-try-even-harder-to-get-binaries-without-t.patch
|
||||||
|
Patch0030: 0030-shim-Rework-pause-functions-and-add-read_counter.patch
|
||||||
|
Patch0031: 0031-Hook-exit-when-shim_lock-protocol-installed.patch
|
||||||
|
Patch0032: 0032-Work-around-stuff-Waddress-of-packed-member-finds.patch
|
||||||
|
Patch0033: 0033-Fix-a-use-of-strlen-instead-of-Strlen.patch
|
||||||
|
Patch0034: 0034-MokManager-Use-CompareMem-on-MokListNode.Type-instea.patch
|
||||||
|
Patch0035: 0035-OpenSSL-always-provide-OBJ_create-with-name-strings.patch
|
||||||
|
Patch0036: 0036-Use-portable-shebangs-bin-bash-usr-bin-env-bash.patch
|
||||||
|
Patch0037: 0037-tpm-Fix-off-by-one-error-when-calculating-event-size.patch
|
||||||
|
Patch0038: 0038-tpm-Define-EFI_VARIABLE_DATA_TREE-as-packed.patch
|
||||||
|
Patch0039: 0039-MokManager-console-mode-modification-for-hi-dpi-scre.patch
|
||||||
|
Patch0040: 0040-MokManager-avoid-Werror-address-of-packed-member.patch
|
||||||
|
Patch0041: 0041-tpm-Don-t-log-duplicate-identical-events.patch
|
||||||
|
Patch0042: 0042-Slightly-better-debugging-messages.patch
|
||||||
|
Patch0043: 0043-Actually-check-for-errors-from-set_second_stage.patch
|
||||||
|
Patch0044: 0044-translate_slashes-don-t-write-to-string-literals.patch
|
||||||
|
Patch0045: 0045-shim-Update-EFI_LOADED_IMAGE-with-the-second-stage-l.patch
|
||||||
|
Patch0046: 0046-tpm-Include-information-about-PE-COFF-images-in-the-.patch
|
||||||
|
Patch0047: 0047-Fix-the-license-on-our-buildid-extractor.patch
|
||||||
|
Patch0048: 0048-Update-README.tpm.patch
|
||||||
|
Patch0049: 0049-Check-PxeReplyReceived-as-fallback-in-netboot.patch
|
||||||
|
Patch0050: 0050-Remove-a-couple-of-incorrect-license-claims.patch
|
||||||
|
Patch0051: 0051-MokManager-fix-uninitialized-value.patch
|
||||||
|
Patch0052: 0052-Fix-some-volatile-usage-gcc-whines-about.patch
|
||||||
|
Patch0053: 0053-MokManager-fix-a-wrong-allocation-failure-check.patch
|
||||||
|
Patch0054: 0054-simple_file-fix-uninitialized-variable-unchecked-ret.patch
|
||||||
|
Patch0055: 0055-Fix-a-broken-tpm-type.patch
|
||||||
|
Patch0056: 0056-Make-cert.S-not-impossible-to-read.patch
|
||||||
|
Patch0057: 0057-Add-support-for-vendor_db-built-in-shim-authorized-l.patch
|
||||||
|
Patch0058: 0058-Handle-binaries-with-multiple-signatures.patch
|
||||||
|
Patch0059: 0059-Make-openssl-accept-the-right-set-of-KU-EKUs.patch
|
||||||
|
Patch0060: 0060-Improve-debug-output-some.patch
|
||||||
|
Patch0061: 0061-Also-use-a-config-table-to-mirror-mok-variables.patch
|
||||||
|
Patch0062: 0062-Implement-lennysz-s-suggestions-for-MokListRT.patch
|
||||||
|
|
||||||
BuildRequires: elfutils-libelf-devel
|
BuildRequires: elfutils-libelf-devel
|
||||||
BuildRequires: git openssl-devel openssl
|
BuildRequires: git openssl-devel openssl
|
||||||
@ -108,10 +166,10 @@ MAKEFLAGS="TOPDIR=.. -f ../Makefile COMMITID=${COMMITID} "
|
|||||||
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
||||||
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
||||||
MAKEFLAGS+="%{_smp_mflags}"
|
MAKEFLAGS+="%{_smp_mflags}"
|
||||||
if [ -f "%{SOURCE1}" ]; then
|
if [ -s "%{SOURCE1}" ]; then
|
||||||
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
||||||
fi
|
fi
|
||||||
if [ -f "%{SOURCE2}" ]; then
|
if [ -s "%{SOURCE2}" ]; then
|
||||||
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -128,10 +186,10 @@ COMMITID=$(cat commit)
|
|||||||
MAKEFLAGS="TOPDIR=.. -f ../Makefile COMMITID=${COMMITID} "
|
MAKEFLAGS="TOPDIR=.. -f ../Makefile COMMITID=${COMMITID} "
|
||||||
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
||||||
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
||||||
if [ -f "%{SOURCE1}" ]; then
|
if [ -s "%{SOURCE1}" ]; then
|
||||||
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
||||||
fi
|
fi
|
||||||
if [ -f "%{SOURCE2}" ]; then
|
if [ -s "%{SOURCE2}" ]; then
|
||||||
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -172,6 +230,36 @@ cd ..
|
|||||||
%files debugsource -f build-%{efiarch}/debugsource.list
|
%files debugsource -f build-%{efiarch}/debugsource.list
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Jul 25 2020 Peter Jones <pjones@redhat.com> - 15-7
|
||||||
|
- Implement Lenny's workaround
|
||||||
|
Related: CVE-2020-10713
|
||||||
|
Related: CVE-2020-14308
|
||||||
|
Related: CVE-2020-14309
|
||||||
|
Related: CVE-2020-14310
|
||||||
|
Related: CVE-2020-14311
|
||||||
|
|
||||||
|
* Fri Jul 24 2020 Peter Jones <pjones@redhat.com> - 15-5
|
||||||
|
- Once more with the MokListRT config table patch added.
|
||||||
|
Related: CVE-2020-10713
|
||||||
|
Related: CVE-2020-14308
|
||||||
|
Related: CVE-2020-14309
|
||||||
|
Related: CVE-2020-14310
|
||||||
|
Related: CVE-2020-14311
|
||||||
|
|
||||||
|
* Thu Jul 23 2020 Peter Jones <pjones@redhat.com> - 15-4
|
||||||
|
- Rebuild for bug fixes and new signing keys
|
||||||
|
Related: CVE-2020-10713
|
||||||
|
Related: CVE-2020-14308
|
||||||
|
Related: CVE-2020-14309
|
||||||
|
Related: CVE-2020-14310
|
||||||
|
Related: CVE-2020-14311
|
||||||
|
|
||||||
|
* Wed Jun 05 2019 Javier Martinez Canillas <javierm@redhat.com> - 15-3
|
||||||
|
- Make EFI variable copying fatal only on secureboot enabled systems
|
||||||
|
Resolves: rhbz#1715878
|
||||||
|
- Fix booting shim from an EFI shell using a relative path
|
||||||
|
Resolves: rhbz#1717064
|
||||||
|
|
||||||
* Tue Feb 12 2019 Peter Jones <pjones@redhat.com> - 15-2
|
* Tue Feb 12 2019 Peter Jones <pjones@redhat.com> - 15-2
|
||||||
- Fix MoK mirroring issue which breaks kdump without intervention
|
- Fix MoK mirroring issue which breaks kdump without intervention
|
||||||
Related: rhbz#1668966
|
Related: rhbz#1668966
|
||||||
|
Loading…
Reference in New Issue
Block a user