Pull in the RHEL CVE fixes.
Related: rhbz#1915194 Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
parent
5a953172d0
commit
34668cd0d4
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,8 +1,2 @@
|
||||
*~
|
||||
*.tar.*
|
||||
/shim-*.tar.bz2
|
||||
*.rpm
|
||||
.build*.log
|
||||
.*.sw?
|
||||
clog
|
||||
rhtest.cer
|
||||
shim-*/
|
||||
|
29
0001-Make-some-things-dprint-instead-of-console_print.patch
Normal file
29
0001-Make-some-things-dprint-instead-of-console_print.patch
Normal file
@ -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
|
||||
|
131
0002-Makefiles-ensure-m32-gets-propogated-to-our-gcc-para.patch
Normal file
131
0002-Makefiles-ensure-m32-gets-propogated-to-our-gcc-para.patch
Normal file
@ -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
|
||||
|
107
0005-httpboot-print-more-messages-when-it-fails-to-set-IP.patch
Normal file
107
0005-httpboot-print-more-messages-when-it-fails-to-set-IP.patch
Normal file
@ -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
|
||||
|
68
0006-httpboot-allow-the-IPv4-gateway-to-be-empty.patch
Normal file
68
0006-httpboot-allow-the-IPv4-gateway-to-be-empty.patch
Normal file
@ -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
0008-Fix-typo-in-debug-path-in-shim.h.patch
Normal file
54
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
|
||||
|
43
0009-MokManager-Stop-using-EFI_VARIABLE_APPEND_WRITE.patch
Normal file
43
0009-MokManager-Stop-using-EFI_VARIABLE_APPEND_WRITE.patch
Normal file
@ -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
|
||||
|
40
0010-shim-Extend-invalid-reloc-size-warning-message.patch
Normal file
40
0010-shim-Extend-invalid-reloc-size-warning-message.patch
Normal file
@ -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
0011-Add-GRUB-s-PCR-Usage-to-README.tpm.patch
Normal file
34
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
|
||||
|
36
0012-Fix-the-compile-error-of-mkdir-wrong-directory.patch
Normal file
36
0012-Fix-the-compile-error-of-mkdir-wrong-directory.patch
Normal file
@ -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
|
||||
|
121
0015-Fix-for-Section-0-has-negative-size-error-when-loadi.patch
Normal file
121
0015-Fix-for-Section-0-has-negative-size-error-when-loadi.patch
Normal file
@ -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
0016-Fix-apparent-typo-in-ARM-32-on-64-code.patch
Normal file
30
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
0019-Cryptlib-fix-build-on-32bit-ARM.patch
Normal file
34
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
|
||||
|
61
0020-Make-sure-that-MOK-variables-always-get-mirrored.patch
Normal file
61
0020-Make-sure-that-MOK-variables-always-get-mirrored.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From ac0400b20264ef67b67891d2216edd3fe20e5571 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||
Date: Mon, 5 Nov 2018 14:51:16 +0100
|
||||
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
|
||||
not be copied to Runtime, even if we have data to be added to it (vendor cert).
|
||||
This patch makes sure that if we have extra data to append, we still mirror
|
||||
the variable.
|
||||
|
||||
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
|
||||
Upstream-commit-id: 9ab0d796bdc
|
||||
---
|
||||
mok.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/mok.c b/mok.c
|
||||
index 38675211e0e..00dd1ad3034 100644
|
||||
--- a/mok.c
|
||||
+++ b/mok.c
|
||||
@@ -223,11 +223,26 @@ 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;
|
||||
+
|
||||
efi_status = get_variable_attr(v->name,
|
||||
&v->data, &v->data_size,
|
||||
*v->guid, &attrs);
|
||||
- if (efi_status == EFI_NOT_FOUND)
|
||||
+ if (efi_status == EFI_NOT_FOUND) {
|
||||
+ if (v->rtname && addend) {
|
||||
+ efi_status = mirror_one_mok_variable(v);
|
||||
+ if (EFI_ERROR(efi_status) &&
|
||||
+ ret != EFI_SECURITY_VIOLATION)
|
||||
+ ret = efi_status;
|
||||
+ }
|
||||
+ /*
|
||||
+ * after possibly adding, we can continue, no
|
||||
+ * further checks to be done.
|
||||
+ */
|
||||
continue;
|
||||
+ }
|
||||
if (EFI_ERROR(efi_status)) {
|
||||
perror(L"Could not verify %s: %r\n", v->name,
|
||||
efi_status);
|
||||
@@ -272,9 +287,6 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||
}
|
||||
|
||||
present = (v->data && v->data_size) ? TRUE : FALSE;
|
||||
- addend = (v->addend_source && v->addend_size &&
|
||||
- *v->addend_source && *v->addend_size)
|
||||
- ? TRUE : FALSE;
|
||||
|
||||
if (v->flags & MOK_VARIABLE_MEASURE && present) {
|
||||
/*
|
||||
--
|
||||
2.26.2
|
||||
|
50
0021-mok-fix-the-mirroring-of-RT-variables.patch
Normal file
50
0021-mok-fix-the-mirroring-of-RT-variables.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From f748139695384fb4e09833898f0b8cb3ab85d810 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 21 Nov 2018 12:47:43 +0800
|
||||
Subject: [PATCH 21/62] mok: fix the mirroring of RT variables
|
||||
|
||||
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
|
||||
check of 'present' and 'addend' invalidates the mirroring of MokListXRT,
|
||||
MokSBStateRT, and MokIgnoreDB.
|
||||
|
||||
https://github.com/rhboot/shim/issues/154
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Upstream-commit-id: 4b27ae034ba
|
||||
---
|
||||
mok.c | 11 ++++-------
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/mok.c b/mok.c
|
||||
index 00dd1ad3034..41925abbb49 100644
|
||||
--- a/mok.c
|
||||
+++ b/mok.c
|
||||
@@ -231,12 +231,8 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||
&v->data, &v->data_size,
|
||||
*v->guid, &attrs);
|
||||
if (efi_status == EFI_NOT_FOUND) {
|
||||
- if (v->rtname && addend) {
|
||||
- efi_status = mirror_one_mok_variable(v);
|
||||
- if (EFI_ERROR(efi_status) &&
|
||||
- ret != EFI_SECURITY_VIOLATION)
|
||||
- ret = efi_status;
|
||||
- }
|
||||
+ if (addend)
|
||||
+ goto mirror_addend;
|
||||
/*
|
||||
* after possibly adding, we can continue, no
|
||||
* further checks to be done.
|
||||
@@ -316,7 +312,8 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||
}
|
||||
}
|
||||
|
||||
- if (v->rtname && present && addend) {
|
||||
+mirror_addend:
|
||||
+ if (v->rtname && (present || addend)) {
|
||||
if (v->flags & MOK_MIRROR_DELETE_FIRST)
|
||||
LibDeleteVariable(v->rtname, v->guid);
|
||||
|
||||
--
|
||||
2.26.2
|
||||
|
110
0022-mok-consolidate-mirroring-code-in-a-helper-instead-o.patch
Normal file
110
0022-mok-consolidate-mirroring-code-in-a-helper-instead-o.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From ff6e5cda136c8fd637d3d6b8334f4f221ba2b1ee Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 31 Jan 2019 13:45:30 -0500
|
||||
Subject: [PATCH 22/62] mok: consolidate mirroring code in a helper instead of
|
||||
using goto
|
||||
|
||||
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.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Upstream-commit-id: 29c11483101
|
||||
---
|
||||
mok.c | 42 +++++++++++++++++++++++++++++-------------
|
||||
shim.h | 2 ++
|
||||
2 files changed, 31 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/mok.c b/mok.c
|
||||
index 41925abbb49..2b9d796a0e8 100644
|
||||
--- a/mok.c
|
||||
+++ b/mok.c
|
||||
@@ -130,7 +130,8 @@ struct mok_state_variable mok_state_variables[] = {
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
-static EFI_STATUS mirror_one_mok_variable(struct mok_state_variable *v)
|
||||
+static EFI_STATUS nonnull(1)
|
||||
+mirror_one_mok_variable(struct mok_state_variable *v)
|
||||
{
|
||||
EFI_STATUS efi_status = EFI_SUCCESS;
|
||||
void *FullData = NULL;
|
||||
@@ -196,6 +197,29 @@ static EFI_STATUS mirror_one_mok_variable(struct mok_state_variable *v)
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Mirror a variable if it has an rtname, and preserve any
|
||||
+ * 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)
|
||||
+{
|
||||
+ EFI_STATUS efi_status;
|
||||
+ if (v->rtname) {
|
||||
+ if (v->flags & MOK_MIRROR_DELETE_FIRST)
|
||||
+ LibDeleteVariable(v->rtname, v->guid);
|
||||
+
|
||||
+ efi_status = mirror_one_mok_variable(v);
|
||||
+ if (EFI_ERROR(efi_status)) {
|
||||
+ if (ret != EFI_SECURITY_VIOLATION)
|
||||
+ ret = efi_status;
|
||||
+ perror(L"Could not create %s: %r\n", v->rtname,
|
||||
+ efi_status);
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Verify our non-volatile MoK state. This checks the variables above
|
||||
* accessable and have valid attributes. If they don't, it removes
|
||||
@@ -232,7 +256,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||
*v->guid, &attrs);
|
||||
if (efi_status == EFI_NOT_FOUND) {
|
||||
if (addend)
|
||||
- goto mirror_addend;
|
||||
+ ret = maybe_mirror_one_mok_variable(v, ret);
|
||||
/*
|
||||
* after possibly adding, we can continue, no
|
||||
* further checks to be done.
|
||||
@@ -312,16 +336,8 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle)
|
||||
}
|
||||
}
|
||||
|
||||
-mirror_addend:
|
||||
- if (v->rtname && (present || addend)) {
|
||||
- if (v->flags & MOK_MIRROR_DELETE_FIRST)
|
||||
- LibDeleteVariable(v->rtname, v->guid);
|
||||
-
|
||||
- efi_status = mirror_one_mok_variable(v);
|
||||
- if (EFI_ERROR(efi_status) &&
|
||||
- ret != EFI_SECURITY_VIOLATION)
|
||||
- ret = efi_status;
|
||||
- }
|
||||
+ if (present)
|
||||
+ ret = maybe_mirror_one_mok_variable(v, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -340,4 +356,4 @@ mirror_addend:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-// vim:fenc=utf-8:tw=75
|
||||
+// vim:fenc=utf-8:tw=75:noet
|
||||
diff --git a/shim.h b/shim.h
|
||||
index 2b359d821e3..c26d5f06538 100644
|
||||
--- a/shim.h
|
||||
+++ b/shim.h
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
+#define nonnull(...) __attribute__((__nonnull__(__VA_ARGS__)))
|
||||
+
|
||||
#define min(a, b) ({(a) < (b) ? (a) : (b);})
|
||||
|
||||
#ifdef __x86_64__
|
||||
--
|
||||
2.26.2
|
||||
|
82
0023-shim-only-include-shim_cert.h-in-shim.c.patch
Normal file
82
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
0024-mok-also-mirror-the-build-cert-to-MokListRT.patch
Normal file
153
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
0025-mok-minor-cleanups.patch
Normal file
37
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
0026-Remove-call-to-TPM2-get_event_log.patch
Normal file
91
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
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 344a8364cb05cdaafc43231d0f73d5217c4e118c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Tue, 12 Feb 2019 18:04:49 -0500
|
||||
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>
|
||||
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 +++------------
|
||||
1 file changed, 3 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/errlog.c b/errlog.c
|
||||
index 18be4822d53..eebb266d396 100644
|
||||
--- a/errlog.c
|
||||
+++ b/errlog.c
|
||||
@@ -14,29 +14,20 @@ EFI_STATUS
|
||||
VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args)
|
||||
{
|
||||
va_list args2;
|
||||
- UINTN size = 0, size2;
|
||||
CHAR16 **newerrs;
|
||||
|
||||
- size = SPrint(NULL, 0, L"%a:%d %a() ", file, line, func);
|
||||
- va_copy(args2, args);
|
||||
- size2 = VSPrint(NULL, 0, fmt, args2);
|
||||
- va_end(args2);
|
||||
-
|
||||
newerrs = ReallocatePool(errs, (nerrs + 1) * sizeof(*errs),
|
||||
(nerrs + 3) * sizeof(*errs));
|
||||
if (!newerrs)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
- newerrs[nerrs] = AllocatePool(size*2+2);
|
||||
+ newerrs[nerrs] = PoolPrint(L"%a:%d %a() ", file, line, func);
|
||||
if (!newerrs[nerrs])
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
- newerrs[nerrs+1] = AllocatePool(size2*2+2);
|
||||
+ va_copy(args2, args);
|
||||
+ newerrs[nerrs+1] = VPoolPrint(fmt, args2);
|
||||
if (!newerrs[nerrs+1])
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
-
|
||||
- SPrint(newerrs[nerrs], size*2+2, L"%a:%d %a() ", file, line, func);
|
||||
- va_copy(args2, args);
|
||||
- VSPrint(newerrs[nerrs+1], size2*2+2, fmt, args2);
|
||||
va_end(args2);
|
||||
|
||||
nerrs += 2;
|
||||
--
|
||||
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
|
||||
|
280
0030-shim-Rework-pause-functions-and-add-read_counter.patch
Normal file
280
0030-shim-Rework-pause-functions-and-add-read_counter.patch
Normal file
@ -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
|
||||
|
49
0031-Hook-exit-when-shim_lock-protocol-installed.patch
Normal file
49
0031-Hook-exit-when-shim_lock-protocol-installed.patch
Normal file
@ -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
|
||||
|
89
0032-Work-around-stuff-Waddress-of-packed-member-finds.patch
Normal file
89
0032-Work-around-stuff-Waddress-of-packed-member-finds.patch
Normal file
@ -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
0033-Fix-a-use-of-strlen-instead-of-Strlen.patch
Normal file
27
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
|
||||
|
42
0036-Use-portable-shebangs-bin-bash-usr-bin-env-bash.patch
Normal file
42
0036-Use-portable-shebangs-bin-bash-usr-bin-env-bash.patch
Normal file
@ -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
|
||||
|
36
0038-tpm-Define-EFI_VARIABLE_DATA_TREE-as-packed.patch
Normal file
36
0038-tpm-Define-EFI_VARIABLE_DATA_TREE-as-packed.patch
Normal file
@ -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
|
||||
|
223
0039-MokManager-console-mode-modification-for-hi-dpi-scre.patch
Normal file
223
0039-MokManager-console-mode-modification-for-hi-dpi-scre.patch
Normal file
@ -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
|
||||
|
111
0040-MokManager-avoid-Werror-address-of-packed-member.patch
Normal file
111
0040-MokManager-avoid-Werror-address-of-packed-member.patch
Normal file
@ -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
0041-tpm-Don-t-log-duplicate-identical-events.patch
Normal file
31
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
0042-Slightly-better-debugging-messages.patch
Normal file
57
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
|
||||
|
69
0043-Actually-check-for-errors-from-set_second_stage.patch
Normal file
69
0043-Actually-check-for-errors-from-set_second_stage.patch
Normal file
@ -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
|
||||
|
140
0044-translate_slashes-don-t-write-to-string-literals.patch
Normal file
140
0044-translate_slashes-don-t-write-to-string-literals.patch
Normal file
@ -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
|
||||
|
124
0046-tpm-Include-information-about-PE-COFF-images-in-the-.patch
Normal file
124
0046-tpm-Include-information-about-PE-COFF-images-in-the-.patch
Normal file
@ -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
0047-Fix-the-license-on-our-buildid-extractor.patch
Normal file
27
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
0048-Update-README.tpm.patch
Normal file
27
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
|
||||
|
61
0049-Check-PxeReplyReceived-as-fallback-in-netboot.patch
Normal file
61
0049-Check-PxeReplyReceived-as-fallback-in-netboot.patch
Normal file
@ -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
|
||||
|
46
0050-Remove-a-couple-of-incorrect-license-claims.patch
Normal file
46
0050-Remove-a-couple-of-incorrect-license-claims.patch
Normal file
@ -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
0051-MokManager-fix-uninitialized-value.patch
Normal file
27
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
0052-Fix-some-volatile-usage-gcc-whines-about.patch
Normal file
41
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
|
||||
|
31
0053-MokManager-fix-a-wrong-allocation-failure-check.patch
Normal file
31
0053-MokManager-fix-a-wrong-allocation-failure-check.patch
Normal file
@ -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
0055-Fix-a-broken-tpm-type.patch
Normal file
27
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
0056-Make-cert.S-not-impossible-to-read.patch
Normal file
279
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
|
||||
|
943
0057-Add-support-for-vendor_db-built-in-shim-authorized-l.patch
Normal file
943
0057-Add-support-for-vendor_db-built-in-shim-authorized-l.patch
Normal file
@ -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
0058-Handle-binaries-with-multiple-signatures.patch
Normal file
366
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
0059-Make-openssl-accept-the-right-set-of-KU-EKUs.patch
Normal file
119
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
0060-Improve-debug-output-some.patch
Normal file
451
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
|
||||
|
352
0061-Also-use-a-config-table-to-mirror-mok-variables.patch
Normal file
352
0061-Also-use-a-config-table-to-mirror-mok-variables.patch
Normal file
@ -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
0062-Implement-lennysz-s-suggestions-for-MokListRT.patch
Normal file
991
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
|
||||
|
77
0063-hexdump.h-fix-arithmetic-error.patch
Normal file
77
0063-hexdump.h-fix-arithmetic-error.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 9313a515432ba938e66f2edc1e22d548fed1eb5c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 30 Jul 2020 14:34:22 -0400
|
||||
Subject: [PATCH] hexdump.h: fix arithmetic error.
|
||||
|
||||
When I modified the hexdumper to help debug MokListRT mirroring not
|
||||
working because of PcdMaxVolatileVariableSize being tiny, I
|
||||
inadvertently added something that is effectively:
|
||||
|
||||
hexdump(..., char *buf, ..., int position)
|
||||
{
|
||||
unsigned long begin = (position % 16);
|
||||
unsigned long i;
|
||||
...
|
||||
for (i = 0; i < begin; i++) {
|
||||
...
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
Unfortunately, in c if 0x8 is set in position, that means begin is
|
||||
0xfffffffffffff8, because signed integer math is horrifying:
|
||||
|
||||
include/hexdump.h:99:vhexdumpf() &data[offset]:0x9E77E6BC size-offset:0x14
|
||||
include/hexdump.h:15:prepare_hex() position:0x9E77E6BC
|
||||
include/hexdump.h:17:prepare_hex() before:0xFFFFFFFFFFFFFFFC size:0x14
|
||||
include/hexdump.h:19:prepare_hex() before:0xFFFFFFFFFFFFFFFC after:0x0
|
||||
include/hexdump.h:21:prepare_hex() buf:0x000000009E77E2BC offset:0 &buf[offset]:0x000000009E77E2BC
|
||||
|
||||
Woops.
|
||||
|
||||
This could further have been prevented in /some/ cases by simply not
|
||||
preparing the hexdump buffer when "verbose" is disabled.
|
||||
|
||||
This patch makes "pos" be unsigned in all cases, and also checks for
|
||||
verbose in vhexdumpf() and simply returns if it is 0.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
include/hexdump.h | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/hexdump.h b/include/hexdump.h
|
||||
index f3f3ac284a3..b2968cd4f85 100644
|
||||
--- a/include/hexdump.h
|
||||
+++ b/include/hexdump.h
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
static inline unsigned long UNUSED
|
||||
-prepare_hex(const void *data, size_t size, char *buf, int position)
|
||||
+prepare_hex(const void *data, size_t size, char *buf, unsigned int position)
|
||||
{
|
||||
char hexchars[] = "0123456789abcdef";
|
||||
int offset = 0;
|
||||
@@ -48,7 +48,7 @@ prepare_hex(const void *data, size_t size, char *buf, int position)
|
||||
#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
|
||||
|
||||
static inline void UNUSED
|
||||
-prepare_text(const void *data, size_t size, char *buf, int position)
|
||||
+prepare_text(const void *data, size_t size, char *buf, unsigned int position)
|
||||
{
|
||||
int offset = 0;
|
||||
unsigned long i;
|
||||
@@ -84,6 +84,9 @@ vhexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt
|
||||
unsigned long display_offset = at;
|
||||
unsigned long offset = 0;
|
||||
|
||||
+ if (verbose == 0)
|
||||
+ return;
|
||||
+
|
||||
while (offset < size) {
|
||||
char hexbuf[49];
|
||||
char txtbuf[19];
|
||||
--
|
||||
2.26.2
|
||||
|
122
0064-Fix-some-mokmanager-deletion-paths.patch
Normal file
122
0064-Fix-some-mokmanager-deletion-paths.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From 18843127dc0eace16d43d479bd091e221e8785c4 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 17 Aug 2020 15:47:19 -0400
|
||||
Subject: [PATCH] Fix some mokmanager deletion paths
|
||||
|
||||
This fixes several codepaths where MokList and MokListX are supposed to
|
||||
be deleted, but are not. It also adds debug logging to much of the
|
||||
deletion codepath.
|
||||
|
||||
---
|
||||
MokManager.c | 24 +++++++++++++++++++++++-
|
||||
Makefile | 2 +-
|
||||
2 files changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/MokManager.c b/MokManager.c
|
||||
index c9949e33bcf..9bae3414fe7 100644
|
||||
--- a/MokManager.c
|
||||
+++ b/MokManager.c
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "shim.h"
|
||||
|
||||
+#include "hexdump.h"
|
||||
+
|
||||
#define PASSWORD_MAX 256
|
||||
#define PASSWORD_MIN 1
|
||||
#define SB_PASSWORD_LEN 16
|
||||
@@ -1050,9 +1052,11 @@ static EFI_STATUS mok_reset_prompt(BOOLEAN MokX)
|
||||
if (MokX) {
|
||||
LibDeleteVariable(L"MokXNew", &SHIM_LOCK_GUID);
|
||||
LibDeleteVariable(L"MokXAuth", &SHIM_LOCK_GUID);
|
||||
+ LibDeleteVariable(L"MokListX", &SHIM_LOCK_GUID);
|
||||
} else {
|
||||
LibDeleteVariable(L"MokNew", &SHIM_LOCK_GUID);
|
||||
LibDeleteVariable(L"MokAuth", &SHIM_LOCK_GUID);
|
||||
+ LibDeleteVariable(L"MokList", &SHIM_LOCK_GUID);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@@ -1075,6 +1079,7 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||
else
|
||||
db_name = L"MokList";
|
||||
|
||||
+ dprint(L"Writing back %s (%d entries)\n", db_name, key_num);
|
||||
for (i = 0; i < key_num; i++) {
|
||||
if (list[i].Mok == NULL)
|
||||
continue;
|
||||
@@ -1085,8 +1090,15 @@ static EFI_STATUS write_back_mok_list(MokListNode * list, INTN key_num,
|
||||
DataSize += sizeof(EFI_GUID);
|
||||
DataSize += list[i].MokSize;
|
||||
}
|
||||
- if (DataSize == 0)
|
||||
+ if (DataSize == 0) {
|
||||
+ dprint(L"DataSize = 0; deleting variable %s\n", db_name);
|
||||
+ efi_status = gRT->SetVariable(db_name, &SHIM_LOCK_GUID,
|
||||
+ EFI_VARIABLE_NON_VOLATILE |
|
||||
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||
+ DataSize, Data);
|
||||
+ dprint(L"efi_status:%llu\n", efi_status);
|
||||
return EFI_SUCCESS;
|
||||
+ }
|
||||
|
||||
Data = AllocatePool(DataSize);
|
||||
if (Data == NULL)
|
||||
@@ -1291,11 +1303,15 @@ static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||
}
|
||||
|
||||
if (auth_size == PASSWORD_CRYPT_SIZE) {
|
||||
+ dprint(L"matching password with CRYPT");
|
||||
efi_status = match_password((PASSWORD_CRYPT *) auth, NULL, 0,
|
||||
NULL, NULL);
|
||||
+ dprint(L"match_password(0x%llx, NULL, 0, NULL, NULL) = %lu\n", auth, efi_status);
|
||||
} else {
|
||||
+ dprint(L"matching password as sha256sum");
|
||||
efi_status =
|
||||
match_password(NULL, MokDel, MokDelSize, auth, NULL);
|
||||
+ dprint(L"match_password(NULL, 0x%llx, %llu, 0x%llx, NULL) = %lu\n", MokDel, MokDelSize, auth, efi_status);
|
||||
}
|
||||
if (EFI_ERROR(efi_status))
|
||||
return EFI_ACCESS_DENIED;
|
||||
@@ -1365,12 +1381,17 @@ static EFI_STATUS delete_keys(void *MokDel, UINTN MokDelSize, BOOLEAN MokX)
|
||||
}
|
||||
|
||||
/* Search and destroy */
|
||||
+ dprint(L"deleting certs from %a\n", MokX ? "MokListX" : "MokList");
|
||||
for (i = 0; i < del_num; i++) {
|
||||
type = del_key[i].Type; /* avoid -Werror=address-of-packed-member */
|
||||
if (CompareGuid(&type, &X509_GUID) == 0) {
|
||||
+ dprint(L"deleting key %d (total %d):\n", i, mok_num);
|
||||
+ dhexdumpat(del_key[i].Mok, del_key[i].MokSize, 0);
|
||||
delete_cert(del_key[i].Mok, del_key[i].MokSize,
|
||||
mok, mok_num);
|
||||
} else if (is_sha2_hash(del_key[i].Type)) {
|
||||
+ dprint(L"deleting hash %d (total %d):\n", i, mok_num);
|
||||
+ dhexdumpat(del_key[i].Mok, del_key[i].MokSize, 0);
|
||||
delete_hash_list(del_key[i].Type, del_key[i].Mok,
|
||||
del_key[i].MokSize, mok, mok_num);
|
||||
}
|
||||
@@ -2564,6 +2585,7 @@ EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * systab)
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
|
||||
+ setup_verbosity();
|
||||
setup_rand();
|
||||
|
||||
console_mode_handle();
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 49e14a26521..a17fa2bef14 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -36,7 +36,7 @@ endif
|
||||
OBJS = shim.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o
|
||||
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
|
||||
ORIG_SOURCES = shim.c mok.c netboot.c replacements.c tpm.c errlog.c shim.h version.h $(wildcard include/*.h)
|
||||
-MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o
|
||||
+MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o
|
||||
ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
|
||||
FALLBACK_OBJS = fallback.o tpm.o errlog.o
|
||||
ORIG_FALLBACK_SRCS = fallback.c
|
||||
--
|
||||
2.26.2
|
||||
|
@ -0,0 +1,37 @@
|
||||
From ac610fe45491deccaab2c4ee689cbbdac117930a Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Tue, 8 Sep 2020 12:26:45 +0200
|
||||
Subject: [PATCH] Fix buffer overrun due DEFAULT_LOADER length miscalculation
|
||||
|
||||
The DEFAULT_LOADER is a UCS-2 string and the StrLen() function returns the
|
||||
number of UCS-2 encoded characters in the string. But the allocated memory
|
||||
is in bytes, so only half of the needed memory to store it is allocated.
|
||||
|
||||
This leads to a buffer overrun when the StrCpy() function attempts to copy
|
||||
the DEFAULT_LOADER to the allocated buffer.
|
||||
|
||||
Fixes: 354bd9b1931 ("Actually check for errors from set_second_stage()")
|
||||
Reported-by: Stuart Hayes <stuart_hayes@dell.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
---
|
||||
shim.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/shim.c b/shim.c
|
||||
index 34dce25c330..82913c934f6 100644
|
||||
--- a/shim.c
|
||||
+++ b/shim.c
|
||||
@@ -2096,8 +2096,9 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
|
||||
unsigned int i;
|
||||
UINTN second_stage_len;
|
||||
|
||||
- second_stage_len = StrLen(DEFAULT_LOADER) + 1;
|
||||
+ second_stage_len = (StrLen(DEFAULT_LOADER) + 1) * sizeof(CHAR16);
|
||||
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;
|
||||
--
|
||||
2.28.0
|
||||
|
BIN
fedora-ca.cer
BIN
fedora-ca.cer
Binary file not shown.
BIN
redhatsecurebootca5.cer
Normal file
BIN
redhatsecurebootca5.cer
Normal file
Binary file not shown.
BIN
secureboot.cer
Normal file
BIN
secureboot.cer
Normal file
Binary file not shown.
BIN
securebootca.cer
Normal file
BIN
securebootca.cer
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
%global pesign_vre 0.106-1
|
||||
%global gnuefi_vre 1:3.0.8-1
|
||||
%global gnuefi_vre 1:3.0.5-6
|
||||
%global openssl_vre 1.0.2j
|
||||
|
||||
%global debug_package %{nil}
|
||||
@ -18,26 +18,85 @@
|
||||
|
||||
Name: shim-unsigned-%{efiarch}
|
||||
Version: 15
|
||||
Release: 1%{?dist}
|
||||
Release: 9.el8
|
||||
Summary: First-stage UEFI bootloader
|
||||
ExclusiveArch: x86_64
|
||||
License: BSD
|
||||
URL: https://github.com/rhboot/shim
|
||||
Source0: https://github.com/rhboot/shim/releases/download/%{version}/shim-%{version}.tar.bz2
|
||||
Source1: fedora-ca.cer
|
||||
Source1: redhatsecurebootca5.cer
|
||||
# currently here's what's in our dbx:
|
||||
# grub2-efi-2.00-11.fc18.x86_64:
|
||||
# grubx64.efi 6ac839881e73504047c06a1aac0c4763408ecb3642783c8acf77a2d393ea5cd7
|
||||
# gcdx64.efi 065cd63bab696ad2f4732af9634d66f2c0d48f8a3134b8808750d378550be151
|
||||
# grub2-efi-2.00-11.fc19.x86_64:
|
||||
# grubx64.efi 49ece9a10a9403b32c8e0c892fd9afe24a974323c96f2cc3dd63608754bf9b45
|
||||
# gcdx64.efi 99fcaa957786c155a92b40be9c981c4e4685b8c62b408cb0f6cb2df9c30b9978
|
||||
# woops.
|
||||
# nothing.
|
||||
Source2: dbx.esl
|
||||
|
||||
Source100: shim-find-debuginfo.sh
|
||||
|
||||
BuildRequires: gcc make
|
||||
Patch0001: 0001-Make-some-things-dprint-instead-of-console_print.patch
|
||||
Patch0002: 0002-Makefiles-ensure-m32-gets-propogated-to-our-gcc-para.patch
|
||||
Patch0003: 0003-Let-MokManager-follow-a-MokTimeout-var-for-timeout-l.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
|
||||
Patch0063: 0063-hexdump.h-fix-arithmetic-error.patch
|
||||
Patch0064: 0064-Fix-some-mokmanager-deletion-paths.patch
|
||||
Patch0065: 0065-Fix-buffer-overrun-due-DEFAULT_LOADER-length-miscalc.patch
|
||||
|
||||
BuildRequires: elfutils-libelf-devel
|
||||
BuildRequires: git openssl-devel openssl
|
||||
BuildRequires: pesign >= %{pesign_vre}
|
||||
@ -71,6 +130,7 @@ Provides: bundled(openssl) = %{openssl_vre}
|
||||
%package debuginfo
|
||||
Summary: Debug information for shim-unsigned-%{efiarch}
|
||||
Requires: %{name}-debugsource = %{version}-%{release}
|
||||
Group: Development/Debug
|
||||
AutoReqProv: 0
|
||||
BuildArch: noarch
|
||||
|
||||
@ -79,6 +139,7 @@ BuildArch: noarch
|
||||
|
||||
%package -n shim-unsigned-%{efialtarch}-debuginfo
|
||||
Summary: Debug information for shim-unsigned-%{efialtarch}
|
||||
Group: Development/Debug
|
||||
Requires: %{name}-debugsource = %{version}-%{release}
|
||||
AutoReqProv: 0
|
||||
BuildArch: noarch
|
||||
@ -88,6 +149,7 @@ BuildArch: noarch
|
||||
|
||||
%package debugsource
|
||||
Summary: Debug Source for shim-unsigned
|
||||
Group: Development/Debug
|
||||
AutoReqProv: 0
|
||||
BuildArch: noarch
|
||||
|
||||
@ -107,10 +169,10 @@ MAKEFLAGS="TOPDIR=.. -f ../Makefile COMMITID=${COMMITID} "
|
||||
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
||||
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
||||
MAKEFLAGS+="%{_smp_mflags}"
|
||||
if [ -f "%{SOURCE1}" ]; then
|
||||
if [ -s "%{SOURCE1}" ]; then
|
||||
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
||||
fi
|
||||
if [ -f "%{SOURCE2}" ]; then
|
||||
if [ -s "%{SOURCE2}" ]; then
|
||||
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
||||
fi
|
||||
|
||||
@ -127,10 +189,10 @@ COMMITID=$(cat commit)
|
||||
MAKEFLAGS="TOPDIR=.. -f ../Makefile COMMITID=${COMMITID} "
|
||||
MAKEFLAGS+="EFIDIR=%{efidir} PKGNAME=shim RELEASE=%{release} "
|
||||
MAKEFLAGS+="ENABLE_HTTPBOOT=true ENABLE_SHIM_HASH=true "
|
||||
if [ -f "%{SOURCE1}" ]; then
|
||||
if [ -s "%{SOURCE1}" ]; then
|
||||
MAKEFLAGS="$MAKEFLAGS VENDOR_CERT_FILE=%{SOURCE1}"
|
||||
fi
|
||||
if [ -f "%{SOURCE2}" ]; then
|
||||
if [ -s "%{SOURCE2}" ]; then
|
||||
MAKEFLAGS="$MAKEFLAGS VENDOR_DBX_FILE=%{SOURCE2}"
|
||||
fi
|
||||
|
||||
@ -171,6 +233,56 @@ cd ..
|
||||
%files debugsource -f build-%{efiarch}/debugsource.list
|
||||
|
||||
%changelog
|
||||
* Thu Sep 17 2020 Peter Jones <pjones@redhat.com> - 15-9.el8
|
||||
- Fix an incorrect allocation size.
|
||||
Related: rhbz#1877253
|
||||
|
||||
* Thu Jul 30 2020 Peter Jones <pjones@redhat.com> - 15-8
|
||||
- Fix a load-address-dependent forever loop.
|
||||
Resolves: rhbz#1861977
|
||||
Related: CVE-2020-10713
|
||||
Related: CVE-2020-14308
|
||||
Related: CVE-2020-14309
|
||||
Related: CVE-2020-14310
|
||||
Related: CVE-2020-14311
|
||||
Related: CVE-2020-15705
|
||||
Related: CVE-2020-15706
|
||||
Related: CVE-2020-15707
|
||||
|
||||
* 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
|
||||
- Fix MoK mirroring issue which breaks kdump without intervention
|
||||
Related: rhbz#1668966
|
||||
|
||||
* Thu Apr 05 2018 Peter Jones <pjones@redhat.com> - 15-1
|
||||
- Update to shim 15
|
||||
- better checking for bad linker output
|
||||
|
Loading…
Reference in New Issue
Block a user