Merge ~xnox/grub:do-not-validate-twice into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu

Proposed by Dimitri John Ledkov
Status: Merged
Merge reported by: Julian Andres Klode
Merged at revision: f1786b635047cabdbac852094294e60547e9f4cf
Proposed branch: ~xnox/grub:do-not-validate-twice
Merge into: ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Diff against target: 242 lines (+228/-0)
2 files modified
debian/patches/linuxefi-do-not-validate-kernels-twice.patch (+227/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Ubuntu Core Development Team Pending
Review via email: mp+416890@code.launchpad.net

Commit message

Do not validate kernels twice

To post a comment you must log in.
Revision history for this message
Julian Andres Klode (juliank) wrote :

Rebased and merged

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/patches/linuxefi-do-not-validate-kernels-twice.patch b/debian/patches/linuxefi-do-not-validate-kernels-twice.patch
2new file mode 100644
3index 0000000..e6c059f
4--- /dev/null
5+++ b/debian/patches/linuxefi-do-not-validate-kernels-twice.patch
6@@ -0,0 +1,227 @@
7+From: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
8+Date: Thu, 3 Mar 2022 13:10:56 +0100
9+Subject: linuxefi: do not validate kernels twice
10+
11+On codebases that have shim-lock-verifier built into the grub core
12+(like 2.06 upstream), shim-lock-verifier is in enforcing mode when
13+booted with secureboot. It means that grub_cmd_linux() command
14+attempts to perform shim validate upon opening linux kernel image,
15+including kernel measurement. And the verifier correctly returns file
16+open error when shim validate protocol is not present or shim fails to
17+validate the kernel.
18+
19+This makes the call to grub_linuxefi_secure_validate() redundant, but
20+also harmful. As validating the kernel image twice, extends the PCRs
21+with the same measurement twice. Which breaks existing sealing
22+policies when upgrading from grub2.04+rhboot+sb+linuxefi to
23+grub2.06+rhboot+sb+linuxefi builds. It is also incorrect to measure
24+the kernel twice.
25+
26+This patch must not be ported to older editions of grub code bases
27+that do not have verifiers framework, or it is not builtin, or
28+shim-lock-verifier is an optional module.
29+
30+This patch is tested to ensure that unsigned kernels are not possible
31+to boot in secureboot mode when shim rejects kernel, or shim protocol
32+is missing, and that the measurements become stable once again. The
33+above also ensures that CVE-2020-15705 is not reintroduced.
34+
35+This is a backport of https://github.com/rhboot/grub2/pull/97 onto
36+Ubuntu packaging.
37+
38+Signed-off-by: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
39+---
40+ grub-core/kern/arm/coreboot/coreboot.S | 2 --
41+ grub-core/loader/efi/chainloader.c | 8 ++-----
42+ grub-core/loader/efi/linux.c | 12 ----------
43+ grub-core/loader/efi/linux_sb.c | 41 ----------------------------------
44+ grub-core/loader/i386/efi/linux.c | 13 -----------
45+ include/grub/efi/linux.h | 2 --
46+ 6 files changed, 2 insertions(+), 76 deletions(-)
47+
48+diff --git a/grub-core/kern/arm/coreboot/coreboot.S b/grub-core/kern/arm/coreboot/coreboot.S
49+index 70998c0..13e73ac 100644
50+--- a/grub-core/kern/arm/coreboot/coreboot.S
51++++ b/grub-core/kern/arm/coreboot/coreboot.S
52+@@ -42,8 +42,6 @@ FUNCTION(grub_armv7_get_timer_frequency)
53+ mrc p15, 0, r0, c14, c0, 0
54+ bx lr
55+
56+-int
57+-EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
58+ grub_err_t
59+ EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
60+ void *kernel_param);
61+diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
62+index 4a85f41..c6ae2fc 100644
63+--- a/grub-core/loader/efi/chainloader.c
64++++ b/grub-core/loader/efi/chainloader.c
65+@@ -910,7 +910,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
66+ grub_efi_device_path_t *dp = 0;
67+ char *filename;
68+ void *boot_image = 0;
69+- int rc;
70+
71+ if (argc == 0)
72+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
73+@@ -1080,9 +1079,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
74+ }
75+ #endif
76+
77+- rc = grub_linuxefi_secure_validate((void *)((grub_addr_t) address), fsize);
78+- grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
79+- if (rc > 0)
80++ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
81+ {
82+ grub_file_close (file);
83+ if (orig_dev)
84+@@ -1092,7 +1089,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
85+ grub_secureboot_chainloader_unload, 0);
86+ return 0;
87+ }
88+- else if (rc == 0)
89++ else
90+ {
91+ grub_load_and_start_image(boot_image);
92+ grub_file_close (file);
93+@@ -1103,7 +1100,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
94+
95+ return 0;
96+ }
97+- // -1 fall-through to fail
98+
99+ fail:
100+ if (orig_dev)
101+diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
102+index 576d8cb..24abc0c 100644
103+--- a/grub-core/loader/efi/linux.c
104++++ b/grub-core/loader/efi/linux.c
105+@@ -433,7 +433,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
106+ struct linux_arch_kernel_header lh;
107+ struct grub_arm64_linux_pe_header *pe;
108+ grub_err_t err;
109+- int rc;
110+
111+ grub_dl_ref (my_mod);
112+
113+@@ -478,17 +477,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
114+
115+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
116+
117+- if (grub_efi_get_secureboot() == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
118+- {
119+- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
120+- if (rc <= 0)
121+- {
122+- grub_error (GRUB_ERR_INVALID_COMMAND,
123+- N_("%s has invalid signature"), argv[0]);
124+- goto fail;
125+- }
126+- }
127+-
128+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
129+ handover_offset = pe->opt.entry_addr;
130+
131+diff --git a/grub-core/loader/efi/linux_sb.c b/grub-core/loader/efi/linux_sb.c
132+index a09479c..13bcb02 100644
133+--- a/grub-core/loader/efi/linux_sb.c
134++++ b/grub-core/loader/efi/linux_sb.c
135+@@ -25,47 +25,6 @@
136+ #include <grub/efi/linux.h>
137+ #include <grub/efi/sb.h>
138+
139+-#define SHIM_LOCK_GUID \
140+- { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
141+-
142+-struct grub_efi_shim_lock
143+-{
144+- grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
145+-};
146+-typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
147+-
148+-// Returns 1 on success, -1 on error, 0 when not available
149+-int
150+-grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
151+-{
152+- grub_efi_guid_t guid = SHIM_LOCK_GUID;
153+- grub_efi_shim_lock_t *shim_lock;
154+- int status;
155+-
156+- grub_dprintf ("linuxefi", "Locating shim protocol\n");
157+- shim_lock = grub_efi_locate_protocol(&guid, NULL);
158+- grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock);
159+- if (!shim_lock)
160+- {
161+- grub_dprintf ("secureboot", "shim not available\n");
162+- return 0;
163+- }
164+-
165+- grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n");
166+- status = shim_lock->verify (data, size);
167+- grub_dprintf ("secureboot", "shim_lock->verify(): %d\n", status);
168+- if (status == GRUB_EFI_SUCCESS)
169+- {
170+- grub_dprintf ("secureboot", "Kernel signature verification passed\n");
171+- return 1;
172+- }
173+-
174+- grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
175+- (unsigned long) status);
176+-
177+- return -1;
178+-}
179+-
180+ typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
181+
182+ grub_err_t
183+diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
184+index 6a90743..cbd313a 100644
185+--- a/grub-core/loader/i386/efi/linux.c
186++++ b/grub-core/loader/i386/efi/linux.c
187+@@ -27,7 +27,6 @@
188+ #include <grub/lib/cmdline.h>
189+ #include <grub/efi/efi.h>
190+ #include <grub/efi/linux.h>
191+-#include <grub/efi/sb.h>
192+ #include <grub/safemath.h>
193+
194+ GRUB_MOD_LICENSE ("GPLv3+");
195+@@ -170,7 +169,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
196+ grub_ssize_t start, filelen;
197+ void *kernel = NULL;
198+ int setup_header_end_offset;
199+- int rc;
200+
201+ grub_dl_ref (my_mod);
202+
203+@@ -201,17 +199,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
204+ goto fail;
205+ }
206+
207+- if (grub_efi_get_secureboot() == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
208+- {
209+- rc = grub_linuxefi_secure_validate (kernel, filelen);
210+- if (rc <= 0)
211+- {
212+- grub_error (GRUB_ERR_ACCESS_DENIED, N_("%s has invalid signature"),
213+- argv[0]);
214+- goto fail;
215+- }
216+- }
217+-
218+ params = grub_efi_allocate_pages_max (0x3fffffff,
219+ BYTES_TO_PAGES(sizeof(*params)));
220+ if (! params)
221+diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
222+index 39f5a9a..cedf20c 100644
223+--- a/include/grub/efi/linux.h
224++++ b/include/grub/efi/linux.h
225+@@ -22,8 +22,6 @@
226+ #include <grub/err.h>
227+ #include <grub/symbol.h>
228+
229+-int
230+-EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size);
231+ grub_err_t
232+ EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
233+ void *kernel_param);
234diff --git a/debian/patches/series b/debian/patches/series
235index 7942ada..3b296a2 100644
236--- a/debian/patches/series
237+++ b/debian/patches/series
238@@ -121,3 +121,4 @@ ubuntu-os-prober-auto.patch
239 efi-correct-struct-grub_efi_boot_services.patch
240 efi-implement-grub_efi_run_image.patch
241 fat-fix-listing-the-root-directory.patch
242+linuxefi-do-not-validate-kernels-twice.patch

Subscribers

People subscribed via source and target branches