* [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load
@ 2024-09-05 14:12 Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 1/5] vl: fix qemu_validate_options() indention Gerd Hoffmann
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
This series allows to boot linux kernels and other efi binaries via
direct kernel load with secure boot enabled.
The series adds two new fw_cfg files: 'etc/boot/kernel' contains the
kernel without modifications (no setup header patching), and
'etc/boot/shim' contains shim.
The path to the shim binary can be passed to qemu using the new '-shim'
command line switch.
This needs a companion patch series for tianocore which will put the new
fw_cfg files into use, a draft of that series can be found here:
https://github.com/kraxel/edk2/commits/devel/direct-secure-boot/
With everything in place it is possible to use direct kernel load with
secure boot enabled.
take care,
Gerd
Gerd Hoffmann (5):
vl: fix qemu_validate_options() indention
x86/loader: only patch linux kernels
x86/loader: read complete kernel
x86/loader: expose unpatched kernel
x86/loader: add -shim option
include/hw/boards.h | 1 +
hw/core/machine.c | 20 ++++++++++++++++++++
hw/i386/x86-common.c | 32 ++++++++++++++++++++++++++------
system/vl.c | 25 +++++++++++++++++--------
qemu-options.hx | 7 +++++++
5 files changed, 71 insertions(+), 14 deletions(-)
--
2.46.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/5] vl: fix qemu_validate_options() indention
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
@ 2024-09-05 14:12 ` Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 2/5] x86/loader: only patch linux kernels Gerd Hoffmann
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
system/vl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index 01b8b8e77ad1..302ad81285b7 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2426,15 +2426,15 @@ static void qemu_validate_options(const QDict *machine_opts)
const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
if (kernel_filename == NULL) {
- if (kernel_cmdline != NULL) {
- error_report("-append only allowed with -kernel option");
- exit(1);
- }
+ if (kernel_cmdline != NULL) {
+ error_report("-append only allowed with -kernel option");
+ exit(1);
+ }
- if (initrd_filename != NULL) {
- error_report("-initrd only allowed with -kernel option");
- exit(1);
- }
+ if (initrd_filename != NULL) {
+ error_report("-initrd only allowed with -kernel option");
+ exit(1);
+ }
}
if (loadvm && incoming) {
--
2.46.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/5] x86/loader: only patch linux kernels
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 1/5] vl: fix qemu_validate_options() indention Gerd Hoffmann
@ 2024-09-05 14:12 ` Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 3/5] x86/loader: read complete kernel Gerd Hoffmann
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
If the binary loaded via -kernel is *not* a linux kernel (in which
case protocol == 0), do not patch the linux kernel header fields.
It's (a) pointless and (b) might break binaries by random patching
and (c) changes the binary hash which in turn breaks secure boot
verification.
Background: OVMF happily loads and runs not only linux kernels but
any efi binary via direct kernel boot.
Note: Breaking the secure boot verification is a problem for linux
kernels too, but fixed that is left for another day ...
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/i386/x86-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 992ea1f25e94..b52903c47fec 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -943,7 +943,7 @@ void x86_load_linux(X86MachineState *x86ms,
* kernel on the other side of the fw_cfg interface matches the hash of the
* file the user passed in.
*/
- if (!sev_enabled()) {
+ if (!sev_enabled() && protocol > 0) {
memcpy(setup, header, MIN(sizeof(header), setup_size));
}
--
2.46.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/5] x86/loader: read complete kernel
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 1/5] vl: fix qemu_validate_options() indention Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 2/5] x86/loader: only patch linux kernels Gerd Hoffmann
@ 2024-09-05 14:12 ` Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 4/5] x86/loader: expose unpatched kernel Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 5/5] x86/loader: add -shim option Gerd Hoffmann
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
Load the complete kernel (including setup) into memory. Excluding the
setup is handled later when adding the FW_CFG_KERNEL_SIZE and
FW_CFG_KERNEL_DATA entries.
This is a preparation for the next patch which adds a new fw_cfg file
containing the complete, unpatched kernel. No functional change.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/i386/x86-common.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index b52903c47fec..82137e053ae0 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -893,7 +893,6 @@ void x86_load_linux(X86MachineState *x86ms,
fprintf(stderr, "qemu: invalid kernel header\n");
exit(1);
}
- kernel_size -= setup_size;
setup = g_malloc(setup_size);
kernel = g_malloc(kernel_size);
@@ -902,6 +901,7 @@ void x86_load_linux(X86MachineState *x86ms,
fprintf(stderr, "fread() failed\n");
exit(1);
}
+ fseek(f, 0, SEEK_SET);
if (fread(kernel, 1, kernel_size, f) != kernel_size) {
fprintf(stderr, "fread() failed\n");
exit(1);
@@ -948,10 +948,11 @@ void x86_load_linux(X86MachineState *x86ms,
}
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
- fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
- fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
- sev_load_ctx.kernel_data = (char *)kernel;
- sev_load_ctx.kernel_size = kernel_size;
+ fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size - setup_size);
+ fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA,
+ kernel + setup_size, kernel_size - setup_size);
+ sev_load_ctx.kernel_data = (char *)kernel + setup_size;
+ sev_load_ctx.kernel_size = kernel_size - setup_size;
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
--
2.46.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 4/5] x86/loader: expose unpatched kernel
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
` (2 preceding siblings ...)
2024-09-05 14:12 ` [PATCH v2 3/5] x86/loader: read complete kernel Gerd Hoffmann
@ 2024-09-05 14:12 ` Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 5/5] x86/loader: add -shim option Gerd Hoffmann
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
Add a new "etc/boot/kernel" fw_cfg file, containing the kernel without
the setup header patches. Intended use is booting in UEFI with secure
boot enabled, where the setup header patching breaks secure boot
verification.
Needs OVMF changes too to be actually useful.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/i386/x86-common.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 82137e053ae0..63cf41711e72 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -960,6 +960,9 @@ void x86_load_linux(X86MachineState *x86ms,
sev_load_ctx.setup_data = (char *)setup;
sev_load_ctx.setup_size = setup_size;
+ /* kernel without setup header patches */
+ fw_cfg_add_file(fw_cfg, "etc/boot/kernel", kernel, kernel_size);
+
if (sev_enabled()) {
sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal);
}
--
2.46.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 5/5] x86/loader: add -shim option
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
` (3 preceding siblings ...)
2024-09-05 14:12 ` [PATCH v2 4/5] x86/loader: expose unpatched kernel Gerd Hoffmann
@ 2024-09-05 14:12 ` Gerd Hoffmann
4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2024-09-05 14:12 UTC (permalink / raw)
To: qemu-devel
Cc: Paolo Bonzini, Yanan Wang, Zhao Liu, Eduardo Habkost,
Richard Henderson, Marcel Apfelbaum, Philippe Mathieu-Daudé,
Michael S. Tsirkin, Gerd Hoffmann
Add new -shim command line option, wire up for the x86 loader.
When specified load shim into the new "etc/boot/shim" fw_cfg file.
Needs OVMF changes too to be actually useful.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/hw/boards.h | 1 +
hw/core/machine.c | 20 ++++++++++++++++++++
hw/i386/x86-common.c | 16 ++++++++++++++++
system/vl.c | 9 +++++++++
qemu-options.hx | 7 +++++++
5 files changed, 53 insertions(+)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 48ff6d8b93f7..0ab83ffb0df1 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -408,6 +408,7 @@ struct MachineState {
BootConfiguration boot_config;
char *kernel_filename;
char *kernel_cmdline;
+ char *shim_filename;
char *initrd_filename;
const char *cpu_type;
AccelState *accelerator;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 27dcda024834..d0eb2387ac13 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -322,6 +322,21 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
ms->kernel_filename = g_strdup(value);
}
+static char *machine_get_shim(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return g_strdup(ms->shim_filename);
+}
+
+static void machine_set_shim(Object *obj, const char *value, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ g_free(ms->shim_filename);
+ ms->shim_filename = g_strdup(value);
+}
+
static char *machine_get_initrd(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@@ -1022,6 +1037,11 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "kernel",
"Linux kernel image file");
+ object_class_property_add_str(oc, "shim",
+ machine_get_shim, machine_set_shim);
+ object_class_property_set_description(oc, "shim",
+ "shim.efi file");
+
object_class_property_add_str(oc, "initrd",
machine_get_initrd, machine_set_initrd);
object_class_property_set_description(oc, "initrd",
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 63cf41711e72..1da86725c7ec 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -963,6 +963,22 @@ void x86_load_linux(X86MachineState *x86ms,
/* kernel without setup header patches */
fw_cfg_add_file(fw_cfg, "etc/boot/kernel", kernel, kernel_size);
+ if (machine->shim_filename) {
+ GMappedFile *mapped_file;
+ GError *gerr = NULL;
+
+ mapped_file = g_mapped_file_new(machine->shim_filename, false, &gerr);
+ if (!mapped_file) {
+ fprintf(stderr, "qemu: error reading shim %s: %s\n",
+ machine->shim_filename, gerr->message);
+ exit(1);
+ }
+
+ fw_cfg_add_file(fw_cfg, "etc/boot/shim",
+ g_mapped_file_get_contents(mapped_file),
+ g_mapped_file_get_length(mapped_file));
+ }
+
if (sev_enabled()) {
sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal);
}
diff --git a/system/vl.c b/system/vl.c
index 302ad81285b7..368704b98958 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2422,6 +2422,7 @@ static void configure_accelerators(const char *progname)
static void qemu_validate_options(const QDict *machine_opts)
{
const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
+ const char *shim_filename = qdict_get_try_str(machine_opts, "shim");
const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd");
const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append");
@@ -2431,6 +2432,11 @@ static void qemu_validate_options(const QDict *machine_opts)
exit(1);
}
+ if (shim_filename != NULL) {
+ error_report("-shim only allowed with -kernel option");
+ exit(1);
+ }
+
if (initrd_filename != NULL) {
error_report("-initrd only allowed with -kernel option");
exit(1);
@@ -2924,6 +2930,9 @@ void qemu_init(int argc, char **argv)
case QEMU_OPTION_kernel:
qdict_put_str(machine_opts_dict, "kernel", optarg);
break;
+ case QEMU_OPTION_shim:
+ qdict_put_str(machine_opts_dict, "shim", optarg);
+ break;
case QEMU_OPTION_initrd:
qdict_put_str(machine_opts_dict, "initrd", optarg);
break;
diff --git a/qemu-options.hx b/qemu-options.hx
index d94e2cbbaeb1..b182d2498397 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4197,6 +4197,13 @@ SRST
or in multiboot format.
ERST
+DEF("shim", HAS_ARG, QEMU_OPTION_shim, \
+ "-shim shim.efi use 'shim.efi' to boot the kernel\n", QEMU_ARCH_ALL)
+SRST
+``-shim shim.efi``
+ Use 'shim.efi' to boot the kernel
+ERST
+
DEF("append", HAS_ARG, QEMU_OPTION_append, \
"-append cmdline use 'cmdline' as kernel command line\n", QEMU_ARCH_ALL)
SRST
--
2.46.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-09-05 14:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-05 14:12 [PATCH v2 0/5] x86/loader: secure boot support for direct kernel load Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 1/5] vl: fix qemu_validate_options() indention Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 2/5] x86/loader: only patch linux kernels Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 3/5] x86/loader: read complete kernel Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 4/5] x86/loader: expose unpatched kernel Gerd Hoffmann
2024-09-05 14:12 ` [PATCH v2 5/5] x86/loader: add -shim option Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).