Skip to content

Commit

Permalink
OvmfPkg/GenericQemuLoadImageLib: support booting via shim
Browse files Browse the repository at this point in the history
Try load shim first.  In case that succeeded update the command line to
list 'kernel' first so shim will fetch the kernel from the kernel loader
file system.

This allows to use direct kernel boot with distro kernels and secure
boot enabled.  Usually distro kernels can only be verified by distro
shim using the distro keys compiled into the shim binary.

Signed-off-by: Gerd Hoffmann <[email protected]>
  • Loading branch information
kraxel committed Sep 17, 2024
1 parent 42d273d commit 33de8b8
Showing 1 changed file with 49 additions and 2 deletions.
51 changes: 49 additions & 2 deletions OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
}
};

STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mShimDevicePath = {
{
{
MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
{ sizeof (VENDOR_DEVICE_PATH) }
},
QEMU_KERNEL_LOADER_FS_MEDIA_GUID
}, {
{
MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP,
{ sizeof (KERNEL_FILE_DEVPATH) }
},
L"shim",
}, {
END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL) }
}
};

STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFsDevicePath = {
{
{
Expand Down Expand Up @@ -174,18 +193,38 @@ QemuLoadKernelImage (
UINTN CommandLineSize;
CHAR8 *CommandLine;
UINTN InitrdSize;
BOOLEAN Shim;

//
// Load the image. This should call back into the QEMU EFI loader file system.
//
Status = gBS->LoadImage (
FALSE, // BootPolicy: exact match required
gImageHandle, // ParentImageHandle
(EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *)&mShimDevicePath,
NULL, // SourceBuffer
0, // SourceSize
&KernelImageHandle
);
if (Status == EFI_SUCCESS) {
Shim = TRUE;
DEBUG ((DEBUG_INFO, "%a: booting via shim\n", __func__));
} else {
Shim = FALSE;
if (Status == EFI_SECURITY_VIOLATION) {
gBS->UnloadImage (KernelImageHandle);
}

Status = gBS->LoadImage (
FALSE, // BootPolicy: exact match required
gImageHandle, // ParentImageHandle
(EFI_DEVICE_PATH_PROTOCOL *)&mKernelDevicePath,
NULL, // SourceBuffer
0, // SourceSize
&KernelImageHandle
);
}

switch (Status) {
case EFI_SUCCESS:
break;
Expand Down Expand Up @@ -303,6 +342,13 @@ QemuLoadKernelImage (
KernelLoadedImage->LoadOptionsSize += sizeof (L" initrd=initrd") - 2;
}

if (Shim) {
//
// Prefix 'kernel ' in UTF-16.
//
KernelLoadedImage->LoadOptionsSize += sizeof (L"kernel ") - 2;
}

if (KernelLoadedImage->LoadOptionsSize == 0) {
KernelLoadedImage->LoadOptions = NULL;
} else {
Expand All @@ -323,7 +369,8 @@ QemuLoadKernelImage (
UnicodeSPrintAsciiFormat (
KernelLoadedImage->LoadOptions,
KernelLoadedImage->LoadOptionsSize,
"%a%a",
"%a%a%a",
(Shim == FALSE) ? "" : "kernel ",
(CommandLineSize == 0) ? "" : CommandLine,
(InitrdSize == 0) ? "" : " initrd=initrd"
);
Expand Down

0 comments on commit 33de8b8

Please sign in to comment.