From: Hongxu Jia <hongxu.jia@windriver.com>
To: openembedded-core@lists.openembedded.org, yoann.congal@smile.fr
Subject: Re: [OE-core] [scarthgap][PATCH 2/3] ovmf: fix CVE-2025-2296
Date: Mon, 27 Apr 2026 13:01:09 +0800 [thread overview]
Message-ID: <6db064df-dafc-4634-aae8-8587d325751d@windriver.com> (raw)
In-Reply-To: <18AA1DD7A8866F0B.1773850@lists.openembedded.org>
Because of ovmf use `CR' at the end of lines, I submitted the patch to
my github also
repo: https://github.com/hongxu-jia/openembedded-core.git
branch scarthgap
//Hongxu
On 4/27/26 12:56, hongxu via lists.openembedded.org wrote:
> According to [1], EDK2 contains a vulnerability in BIOS where an attacker may
> cause “ Improper Input Validation” by local access. Successful exploitation of
> this vulnerability could alter control flow in unexpected ways, potentially
> allowing arbitrary command execution and impacting Confidentiality, Integrity,
> and Availability.
>
> Backport patches from upstream [2] to fix CVE-2025-2296
>
> Note: backport 0001-AmdSev-Halt-on-failed-blob-allocation.patch to apply
> the CVE patches without confliction
>
> [1] https://nvd.nist.gov/vuln/detail/CVE-2025-2296
> [2] https://github.com/tianocore/edk2/pull/10628
>
> Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> ---
> ...mdSev-Halt-on-failed-blob-allocation.patch | 159 ++++
> .../ovmf/ovmf/CVE-2025-2296-1.patch | 762 ++++++++++++++++++
> .../ovmf/ovmf/CVE-2025-2296-2.patch | 175 ++++
> .../ovmf/ovmf/CVE-2025-2296-3.patch | 42 +
> .../ovmf/ovmf/CVE-2025-2296-4.patch | 34 +
> .../ovmf/ovmf/CVE-2025-2296-5.patch | 36 +
> .../ovmf/ovmf/CVE-2025-2296-6.patch | 54 ++
> .../ovmf/ovmf/CVE-2025-2296-7.patch | 124 +++
> .../ovmf/ovmf/CVE-2025-2296-8.patch | 125 +++
> .../ovmf/ovmf/CVE-2025-2296-9.patch | 108 +++
> meta/recipes-core/ovmf/ovmf_git.bb | 10 +
> 11 files changed, 1629 insertions(+)
> create mode 100644 meta/recipes-core/ovmf/ovmf/0001-AmdSev-Halt-on-failed-blob-allocation.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-1.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-2.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-3.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-4.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-5.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-6.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-7.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-8.patch
> create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2025-2296-9.patch
>
> diff --git a/meta/recipes-core/ovmf/ovmf/0001-AmdSev-Halt-on-failed-blob-allocation.patch b/meta/recipes-core/ovmf/ovmf/0001-AmdSev-Halt-on-failed-blob-allocation.patch
> new file mode 100644
> index 0000000000..181ff3376a
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/0001-AmdSev-Halt-on-failed-blob-allocation.patch
> @@ -0,0 +1,159 @@
> +From dbec8dc5ba6341d816ffd495fcd7eeece1716bb4 Mon Sep 17 00:00:00 2001
> +From: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
> +Date: Mon, 29 Apr 2024 20:07:19 +0000
> +Subject: [PATCH] AmdSev: Halt on failed blob allocation
> +
> +A malicious host may be able to undermine the fw_cfg
> +interface such that loading a blob fails.
> +
> +In this case rather than continuing to the next boot
> +option, the blob verifier should halt.
> +
> +For non-confidential guests, the error should be non-fatal.
> +
> +Signed-off-by: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
> +
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/10b4bb8d6d0c515ed9663691aea3684be8f7b0fc]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../BlobVerifierSevHashes.c | 17 ++++++++++++++++-
> + OvmfPkg/Include/Library/BlobVerifierLib.h | 11 +++++++----
> + .../BlobVerifierLibNull/BlobVerifierNull.c | 13 ++++++++-----
> + .../QemuKernelLoaderFsDxe.c | 9 ++++-----
> + 4 files changed, 35 insertions(+), 15 deletions(-)
> +
> +diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
> +index 2e58794c3c..6477c5c3d3 100644
> +--- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
> ++++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
> +@@ -80,6 +80,7 @@ FindBlobEntryGuid (
> + @param[in] BlobName The name of the blob
> + @param[in] Buf The data of the blob
> + @param[in] BufSize The size of the blob in bytes
> ++ @param[in] FetchStatus The status of the previous blob fetch
> +
> + @retval EFI_SUCCESS The blob was verified successfully.
> + @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
> +@@ -90,13 +91,27 @@ EFIAPI
> + VerifyBlob (
> + IN CONST CHAR16 *BlobName,
> + IN CONST VOID *Buf,
> +- IN UINT32 BufSize
> ++ IN UINT32 BufSize,
> ++ IN EFI_STATUS FetchStatus
> + )
> + {
> + CONST GUID *Guid;
> + INT32 Remaining;
> + HASH_TABLE *Entry;
> +
> ++ // Enter a dead loop if the fetching of this blob
> ++ // failed. This prevents a malicious host from
> ++ // circumventing the following checks.
> ++ if (EFI_ERROR (FetchStatus)) {
> ++ DEBUG ((
> ++ DEBUG_ERROR,
> ++ "%a: Fetching blob failed.\n",
> ++ __func__
> ++ ));
> ++
> ++ CpuDeadLoop ();
> ++ }
> ++
> + if ((mHashesTable == NULL) || (mHashesTableSize == 0)) {
> + DEBUG ((
> + DEBUG_ERROR,
> +diff --git a/OvmfPkg/Include/Library/BlobVerifierLib.h b/OvmfPkg/Include/Library/BlobVerifierLib.h
> +index 7e1af27574..09af1b77de 100644
> +--- a/OvmfPkg/Include/Library/BlobVerifierLib.h
> ++++ b/OvmfPkg/Include/Library/BlobVerifierLib.h
> +@@ -22,17 +22,20 @@
> + @param[in] BlobName The name of the blob
> + @param[in] Buf The data of the blob
> + @param[in] BufSize The size of the blob in bytes
> ++ @param[in] FetchStatus The status of fetching this blob
> +
> +- @retval EFI_SUCCESS The blob was verified successfully.
> +- @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
> +- should be considered non-secure.
> ++ @retval EFI_SUCCESS The blob was verified successfully or was not
> ++ found in the hash table.
> ++ @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can
> ++ continue safely.
> + **/
> + EFI_STATUS
> + EFIAPI
> + VerifyBlob (
> + IN CONST CHAR16 *BlobName,
> + IN CONST VOID *Buf,
> +- IN UINT32 BufSize
> ++ IN UINT32 BufSize,
> ++ IN EFI_STATUS FetchStatus
> + );
> +
> + #endif
> +diff --git a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
> +index e817c3cc95..db5320571c 100644
> +--- a/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
> ++++ b/OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierNull.c
> +@@ -16,18 +16,21 @@
> + @param[in] BlobName The name of the blob
> + @param[in] Buf The data of the blob
> + @param[in] BufSize The size of the blob in bytes
> ++ @param[in] FetchStatus The status of the fetch of this blob
> +
> +- @retval EFI_SUCCESS The blob was verified successfully.
> +- @retval EFI_ACCESS_DENIED The blob could not be verified, and therefore
> +- should be considered non-secure.
> ++ @retval EFI_SUCCESS The blob was verified successfully or was not
> ++ found in the hash table.
> ++ @retval EFI_ACCESS_DENIED Kernel hashes not supported but the boot can
> ++ continue safely.
> + **/
> + EFI_STATUS
> + EFIAPI
> + VerifyBlob (
> + IN CONST CHAR16 *BlobName,
> + IN CONST VOID *Buf,
> +- IN UINT32 BufSize
> ++ IN UINT32 BufSize,
> ++ IN EFI_STATUS FetchStatus
> + )
> + {
> +- return EFI_SUCCESS;
> ++ return FetchStatus;
> + }
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 3c12085f6c..cf58c97cd2 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -1042,6 +1042,7 @@ QemuKernelLoaderFsDxeEntrypoint (
> + KERNEL_BLOB *CurrentBlob;
> + KERNEL_BLOB *KernelBlob;
> + EFI_STATUS Status;
> ++ EFI_STATUS FetchStatus;
> + EFI_HANDLE FileSystemHandle;
> + EFI_HANDLE InitrdLoadFile2Handle;
> +
> +@@ -1060,15 +1061,13 @@ QemuKernelLoaderFsDxeEntrypoint (
> + //
> + for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
> + CurrentBlob = &mKernelBlob[BlobType];
> +- Status = FetchBlob (CurrentBlob);
> +- if (EFI_ERROR (Status)) {
> +- goto FreeBlobs;
> +- }
> ++ FetchStatus = FetchBlob (CurrentBlob);
> +
> + Status = VerifyBlob (
> + CurrentBlob->Name,
> + CurrentBlob->Data,
> +- CurrentBlob->Size
> ++ CurrentBlob->Size,
> ++ FetchStatus
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeBlobs;
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-1.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-1.patch
> new file mode 100644
> index 0000000000..5cdbb12f19
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-1.patch
> @@ -0,0 +1,762 @@
> +From 459f5ffa24ae8574657c4105af0ff7dc30ac428d Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Tue, 14 Jan 2025 17:36:39 +0100
> +Subject: [PATCH 01/10] OvmfPkg/QemuKernelLoaderFsDxe: rework direct kernel
> + boot filesystem
> +
> +Split KERNEL_BLOB struct into two:
> +
> + * One (KERNEL_BLOB_ITEMS) static array describing how to load (unnamed)
> + blobs from fw_cfg.
> + * And one (KERNEL_BLOB) dynamically allocated linked list carrying the
> + data blobs for the pseudo filesystem.
> +
> +Also add some debug logging. Prefix most functions with 'QemuKernel'
> +for consistency and easier log file grepping. Add some small helper
> +functions.
> +
> +This refactoring prepares for loading blobs in other ways.
> +No (intentional) change in filesystem protocol behavior.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/459f5ffa24ae8574657c4105af0ff7dc30ac428d]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../QemuKernelLoaderFsDxe.c | 345 +++++++++++-------
> + 1 file changed, 205 insertions(+), 140 deletions(-)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index cf58c97cd2..7ad1b3828f 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -31,13 +31,6 @@
> + //
> + // Static data that hosts the fw_cfg blobs and serves file requests.
> + //
> +-typedef enum {
> +- KernelBlobTypeKernel,
> +- KernelBlobTypeInitrd,
> +- KernelBlobTypeCommandLine,
> +- KernelBlobTypeMax
> +-} KERNEL_BLOB_TYPE;
> +-
> + typedef struct {
> + CONST CHAR16 Name[8];
> + struct {
> +@@ -45,11 +38,17 @@ typedef struct {
> + FIRMWARE_CONFIG_ITEM CONST DataKey;
> + UINT32 Size;
> + } FwCfgItem[2];
> +- UINT32 Size;
> +- UINT8 *Data;
> +-} KERNEL_BLOB;
> ++} KERNEL_BLOB_ITEMS;
> ++
> ++typedef struct KERNEL_BLOB KERNEL_BLOB;
> ++struct KERNEL_BLOB {
> ++ CHAR16 Name[8];
> ++ UINT32 Size;
> ++ UINT8 *Data;
> ++ KERNEL_BLOB *Next;
> ++};
> +
> +-STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {
> ++STATIC KERNEL_BLOB_ITEMS mKernelBlobItems[] = {
> + {
> + L"kernel",
> + {
> +@@ -69,7 +68,9 @@ STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {
> + }
> + };
> +
> +-STATIC UINT64 mTotalBlobBytes;
> ++STATIC KERNEL_BLOB *mKernelBlobs;
> ++STATIC UINT64 mKernelBlobCount;
> ++STATIC UINT64 mTotalBlobBytes;
> +
> + //
> + // Device path for the handle that incorporates our "EFI stub filesystem".
> +@@ -117,7 +118,7 @@ STATIC EFI_TIME mInitTime;
> + typedef struct {
> + UINT64 Signature; // Carries STUB_FILE_SIG.
> +
> +- KERNEL_BLOB_TYPE BlobType; // Index into mKernelBlob. KernelBlobTypeMax
> ++ KERNEL_BLOB *Blob; // Index into mKernelBlob. KernelBlobTypeMax
> + // denotes the root directory of the filesystem.
> +
> + UINT64 Position; // Byte position for regular files;
> +@@ -177,7 +178,7 @@ typedef struct {
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileOpen (
> ++QemuKernelStubFileOpen (
> + IN EFI_FILE_PROTOCOL *This,
> + OUT EFI_FILE_PROTOCOL **NewHandle,
> + IN CHAR16 *FileName,
> +@@ -196,7 +197,7 @@ StubFileOpen (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileClose (
> ++QemuKernelStubFileClose (
> + IN EFI_FILE_PROTOCOL *This
> + )
> + {
> +@@ -219,7 +220,7 @@ StubFileClose (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileDelete (
> ++QemuKernelStubFileDelete (
> + IN EFI_FILE_PROTOCOL *This
> + )
> + {
> +@@ -229,18 +230,17 @@ StubFileDelete (
> +
> + /**
> + Helper function that formats an EFI_FILE_INFO structure into the
> +- user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including
> +- KernelBlobTypeMax, which stands for the root directory).
> ++ user-allocated buffer, for any valid KERNEL_BLOB (including NULL,
> ++ which stands for the root directory).
> +
> + The interface follows the EFI_FILE_GET_INFO -- and for directories, the
> + EFI_FILE_READ -- interfaces.
> +
> +- @param[in] BlobType The KERNEL_BLOB_TYPE value identifying the fw_cfg
> ++ @param[in] Blob The KERNEL_BLOB identifying the fw_cfg
> + blob backing the STUB_FILE that information is
> +- being requested about. If BlobType equals
> +- KernelBlobTypeMax, then information will be
> +- provided about the root directory of the
> +- filesystem.
> ++ being requested about. If Blob is NULL,
> ++ then information will be provided about the root
> ++ directory of the filesystem.
> +
> + @param[in,out] BufferSize On input, the size of Buffer. On output, the
> + amount of data returned in Buffer. In both cases,
> +@@ -257,10 +257,10 @@ StubFileDelete (
> + **/
> + STATIC
> + EFI_STATUS
> +-ConvertKernelBlobTypeToFileInfo (
> +- IN KERNEL_BLOB_TYPE BlobType,
> +- IN OUT UINTN *BufferSize,
> +- OUT VOID *Buffer
> ++QemuKernelBlobTypeToFileInfo (
> ++ IN KERNEL_BLOB *Blob,
> ++ IN OUT UINTN *BufferSize,
> ++ OUT VOID *Buffer
> + )
> + {
> + CONST CHAR16 *Name;
> +@@ -272,17 +272,16 @@ ConvertKernelBlobTypeToFileInfo (
> + EFI_FILE_INFO *FileInfo;
> + UINTN OriginalBufferSize;
> +
> +- if (BlobType == KernelBlobTypeMax) {
> ++ if (Blob == NULL) {
> + //
> + // getting file info about the root directory
> + //
> ++ DEBUG ((DEBUG_INFO, "%a: file info: directory\n", __func__));
> + Name = L"\\";
> +- FileSize = KernelBlobTypeMax;
> ++ FileSize = mKernelBlobCount;
> + Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
> + } else {
> +- CONST KERNEL_BLOB *Blob;
> +-
> +- Blob = &mKernelBlob[BlobType];
> ++ DEBUG ((DEBUG_INFO, "%a: file info: \"%s\"\n", __func__, Blob->Name));
> + Name = Blob->Name;
> + FileSize = Blob->Size;
> + Attribute = EFI_FILE_READ_ONLY;
> +@@ -312,6 +311,23 @@ ConvertKernelBlobTypeToFileInfo (
> + return EFI_SUCCESS;
> + }
> +
> ++STATIC
> ++KERNEL_BLOB *
> ++FindKernelBlob (
> ++ CHAR16 *FileName
> ++ )
> ++{
> ++ KERNEL_BLOB *Blob;
> ++
> ++ for (Blob = mKernelBlobs; Blob != NULL; Blob = Blob->Next) {
> ++ if (StrCmp (FileName, Blob->Name) == 0) {
> ++ return Blob;
> ++ }
> ++ }
> ++
> ++ return NULL;
> ++}
> ++
> + /**
> + Reads data from a file, or continues scanning a directory.
> +
> +@@ -349,25 +365,25 @@ ConvertKernelBlobTypeToFileInfo (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileRead (
> ++QemuKernelStubFileRead (
> + IN EFI_FILE_PROTOCOL *This,
> + IN OUT UINTN *BufferSize,
> + OUT VOID *Buffer
> + )
> + {
> +- STUB_FILE *StubFile;
> +- CONST KERNEL_BLOB *Blob;
> +- UINT64 Left;
> ++ STUB_FILE *StubFile;
> ++ KERNEL_BLOB *Blob;
> ++ UINT64 Left, Pos;
> +
> + StubFile = STUB_FILE_FROM_FILE (This);
> +
> + //
> + // Scanning the root directory?
> + //
> +- if (StubFile->BlobType == KernelBlobTypeMax) {
> ++ if (StubFile->Blob == NULL) {
> + EFI_STATUS Status;
> +
> +- if (StubFile->Position == KernelBlobTypeMax) {
> ++ if (StubFile->Position == mKernelBlobCount) {
> + //
> + // Scanning complete.
> + //
> +@@ -375,8 +391,16 @@ StubFileRead (
> + return EFI_SUCCESS;
> + }
> +
> +- Status = ConvertKernelBlobTypeToFileInfo (
> +- (KERNEL_BLOB_TYPE)StubFile->Position,
> ++ for (Pos = 0, Blob = mKernelBlobs;
> ++ Pos < StubFile->Position;
> ++ Pos++, Blob = Blob->Next)
> ++ {
> ++ }
> ++
> ++ DEBUG ((DEBUG_INFO, "%a: file list: #%d \"%s\"\n", __func__, Pos, Blob->Name));
> ++
> ++ Status = QemuKernelBlobTypeToFileInfo (
> ++ Blob,
> + BufferSize,
> + Buffer
> + );
> +@@ -391,7 +415,7 @@ StubFileRead (
> + //
> + // Reading a file.
> + //
> +- Blob = &mKernelBlob[StubFile->BlobType];
> ++ Blob = StubFile->Blob;
> + if (StubFile->Position > Blob->Size) {
> + return EFI_DEVICE_ERROR;
> + }
> +@@ -402,6 +426,7 @@ StubFileRead (
> + }
> +
> + if (Blob->Data != NULL) {
> ++ DEBUG ((DEBUG_INFO, "%a: file read: \"%s\", %d bytes\n", __func__, Blob->Name, *BufferSize));
> + CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);
> + }
> +
> +@@ -435,7 +460,7 @@ StubFileRead (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileWrite (
> ++QemuKernelStubFileWrite (
> + IN EFI_FILE_PROTOCOL *This,
> + IN OUT UINTN *BufferSize,
> + IN VOID *Buffer
> +@@ -444,7 +469,7 @@ StubFileWrite (
> + STUB_FILE *StubFile;
> +
> + StubFile = STUB_FILE_FROM_FILE (This);
> +- return (StubFile->BlobType == KernelBlobTypeMax) ?
> ++ return (StubFile->Blob == NULL) ?
> + EFI_UNSUPPORTED :
> + EFI_WRITE_PROTECTED;
> + }
> +@@ -466,7 +491,7 @@ StubFileWrite (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileGetPosition (
> ++QemuKernelStubFileGetPosition (
> + IN EFI_FILE_PROTOCOL *This,
> + OUT UINT64 *Position
> + )
> +@@ -474,7 +499,7 @@ StubFileGetPosition (
> + STUB_FILE *StubFile;
> +
> + StubFile = STUB_FILE_FROM_FILE (This);
> +- if (StubFile->BlobType == KernelBlobTypeMax) {
> ++ if (StubFile->Blob == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> +@@ -501,7 +526,7 @@ StubFileGetPosition (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileSetPosition (
> ++QemuKernelStubFileSetPosition (
> + IN EFI_FILE_PROTOCOL *This,
> + IN UINT64 Position
> + )
> +@@ -511,7 +536,7 @@ StubFileSetPosition (
> +
> + StubFile = STUB_FILE_FROM_FILE (This);
> +
> +- if (StubFile->BlobType == KernelBlobTypeMax) {
> ++ if (StubFile->Blob == NULL) {
> + if (Position == 0) {
> + //
> + // rewinding a directory scan is allowed
> +@@ -526,7 +551,7 @@ StubFileSetPosition (
> + //
> + // regular file seek
> + //
> +- Blob = &mKernelBlob[StubFile->BlobType];
> ++ Blob = StubFile->Blob;
> + if (Position == MAX_UINT64) {
> + //
> + // seek to end
> +@@ -583,7 +608,7 @@ StubFileSetPosition (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileGetInfo (
> ++QemuKernelStubFileGetInfo (
> + IN EFI_FILE_PROTOCOL *This,
> + IN EFI_GUID *InformationType,
> + IN OUT UINTN *BufferSize,
> +@@ -596,8 +621,8 @@ StubFileGetInfo (
> + StubFile = STUB_FILE_FROM_FILE (This);
> +
> + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
> +- return ConvertKernelBlobTypeToFileInfo (
> +- StubFile->BlobType,
> ++ return QemuKernelBlobTypeToFileInfo (
> ++ StubFile->Blob,
> + BufferSize,
> + Buffer
> + );
> +@@ -685,7 +710,7 @@ StubFileGetInfo (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileSetInfo (
> ++QemuKernelStubFileSetInfo (
> + IN EFI_FILE_PROTOCOL *This,
> + IN EFI_GUID *InformationType,
> + IN UINTN BufferSize,
> +@@ -712,7 +737,7 @@ StubFileSetInfo (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileFlush (
> ++QemuKernelStubFileFlush (
> + IN EFI_FILE_PROTOCOL *This
> + )
> + {
> +@@ -724,16 +749,16 @@ StubFileFlush (
> + //
> + STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
> + EFI_FILE_PROTOCOL_REVISION, // revision 1
> +- StubFileOpen,
> +- StubFileClose,
> +- StubFileDelete,
> +- StubFileRead,
> +- StubFileWrite,
> +- StubFileGetPosition,
> +- StubFileSetPosition,
> +- StubFileGetInfo,
> +- StubFileSetInfo,
> +- StubFileFlush,
> ++ QemuKernelStubFileOpen,
> ++ QemuKernelStubFileClose,
> ++ QemuKernelStubFileDelete,
> ++ QemuKernelStubFileRead,
> ++ QemuKernelStubFileWrite,
> ++ QemuKernelStubFileGetPosition,
> ++ QemuKernelStubFileSetPosition,
> ++ QemuKernelStubFileGetInfo,
> ++ QemuKernelStubFileSetInfo,
> ++ QemuKernelStubFileFlush,
> + NULL, // OpenEx, revision 2
> + NULL, // ReadEx, revision 2
> + NULL, // WriteEx, revision 2
> +@@ -743,7 +768,7 @@ STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileOpen (
> ++QemuKernelStubFileOpen (
> + IN EFI_FILE_PROTOCOL *This,
> + OUT EFI_FILE_PROTOCOL **NewHandle,
> + IN CHAR16 *FileName,
> +@@ -752,7 +777,7 @@ StubFileOpen (
> + )
> + {
> + CONST STUB_FILE *StubFile;
> +- UINTN BlobType;
> ++ KERNEL_BLOB *Blob;
> + STUB_FILE *NewStubFile;
> +
> + //
> +@@ -774,21 +799,20 @@ StubFileOpen (
> + // Only the root directory supports opening files in it.
> + //
> + StubFile = STUB_FILE_FROM_FILE (This);
> +- if (StubFile->BlobType != KernelBlobTypeMax) {
> ++ if (StubFile->Blob != NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Locate the file.
> + //
> +- for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
> +- if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {
> +- break;
> +- }
> +- }
> ++ Blob = FindKernelBlob (FileName);
> +
> +- if (BlobType == KernelBlobTypeMax) {
> ++ if (Blob == NULL) {
> ++ DEBUG ((DEBUG_INFO, "%a: file not found: \"%s\"\n", __func__, FileName));
> + return EFI_NOT_FOUND;
> ++ } else {
> ++ DEBUG ((DEBUG_INFO, "%a: file opened: \"%s\"\n", __func__, FileName));
> + }
> +
> + //
> +@@ -800,7 +824,7 @@ StubFileOpen (
> + }
> +
> + NewStubFile->Signature = STUB_FILE_SIG;
> +- NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType;
> ++ NewStubFile->Blob = Blob;
> + NewStubFile->Position = 0;
> + CopyMem (
> + &NewStubFile->File,
> +@@ -842,7 +866,7 @@ StubFileOpen (
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-StubFileSystemOpenVolume (
> ++QemuKernelStubFileSystemOpenVolume (
> + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
> + OUT EFI_FILE_PROTOCOL **Root
> + )
> +@@ -855,7 +879,7 @@ StubFileSystemOpenVolume (
> + }
> +
> + StubFile->Signature = STUB_FILE_SIG;
> +- StubFile->BlobType = KernelBlobTypeMax;
> ++ StubFile->Blob = NULL;
> + StubFile->Position = 0;
> + CopyMem (
> + &StubFile->File,
> +@@ -869,13 +893,13 @@ StubFileSystemOpenVolume (
> +
> + STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
> + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
> +- StubFileSystemOpenVolume
> ++ QemuKernelStubFileSystemOpenVolume
> + };
> +
> + STATIC
> + EFI_STATUS
> + EFIAPI
> +-InitrdLoadFile2 (
> ++QemuKernelInitrdLoadFile2 (
> + IN EFI_LOAD_FILE2_PROTOCOL *This,
> + IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
> + IN BOOLEAN BootPolicy,
> +@@ -883,8 +907,11 @@ InitrdLoadFile2 (
> + OUT VOID *Buffer OPTIONAL
> + )
> + {
> +- CONST KERNEL_BLOB *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];
> ++ KERNEL_BLOB *InitrdBlob;
> +
> ++ DEBUG ((DEBUG_INFO, "%a: initrd read\n", __func__));
> ++ InitrdBlob = FindKernelBlob (L"initrd");
> ++ ASSERT (InitrdBlob != NULL);
> + ASSERT (InitrdBlob->Size > 0);
> +
> + if (BootPolicy) {
> +@@ -913,17 +940,33 @@ InitrdLoadFile2 (
> + }
> +
> + STATIC CONST EFI_LOAD_FILE2_PROTOCOL mInitrdLoadFile2 = {
> +- InitrdLoadFile2,
> ++ QemuKernelInitrdLoadFile2,
> + };
> +
> + //
> + // Utility functions.
> + //
> +
> ++STATIC VOID
> ++QemuKernelChunkedRead (
> ++ UINT8 *Dest,
> ++ UINT32 Bytes
> ++ )
> ++{
> ++ UINT32 Chunk;
> ++
> ++ while (Bytes > 0) {
> ++ Chunk = (Bytes < SIZE_1MB) ? Bytes : SIZE_1MB;
> ++ QemuFwCfgReadBytes (Chunk, Dest);
> ++ Bytes -= Chunk;
> ++ Dest += Chunk;
> ++ }
> ++}
> ++
> + /**
> + Populate a blob in mKernelBlob.
> +
> +- param[in,out] Blob Pointer to the KERNEL_BLOB element in mKernelBlob that is
> ++ param[in,out] Blob Pointer to the KERNEL_BLOB_ITEMS that is
> + to be filled from fw_cfg.
> +
> + @retval EFI_SUCCESS Blob has been populated. If fw_cfg reported a
> +@@ -934,35 +977,46 @@ STATIC CONST EFI_LOAD_FILE2_PROTOCOL mInitrdLoadFile2 = {
> + **/
> + STATIC
> + EFI_STATUS
> +-FetchBlob (
> +- IN OUT KERNEL_BLOB *Blob
> ++QemuKernelFetchBlob (
> ++ IN KERNEL_BLOB_ITEMS *BlobItems
> + )
> + {
> +- UINT32 Left;
> +- UINTN Idx;
> +- UINT8 *ChunkData;
> ++ UINT32 Size;
> ++ UINTN Idx;
> ++ UINT8 *ChunkData;
> ++ KERNEL_BLOB *Blob;
> ++ EFI_STATUS Status;
> +
> + //
> + // Read blob size.
> + //
> +- Blob->Size = 0;
> +- for (Idx = 0; Idx < ARRAY_SIZE (Blob->FwCfgItem); Idx++) {
> +- if (Blob->FwCfgItem[Idx].SizeKey == 0) {
> ++ for (Size = 0, Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) {
> ++ if (BlobItems->FwCfgItem[Idx].SizeKey == 0) {
> + break;
> + }
> +
> +- QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].SizeKey);
> +- Blob->FwCfgItem[Idx].Size = QemuFwCfgRead32 ();
> +- Blob->Size += Blob->FwCfgItem[Idx].Size;
> ++ QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey);
> ++ BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 ();
> ++ Size += BlobItems->FwCfgItem[Idx].Size;
> + }
> +
> +- if (Blob->Size == 0) {
> ++ if (Size == 0) {
> + return EFI_SUCCESS;
> + }
> +
> ++ Blob = AllocatePool (sizeof (*Blob));
> ++ if (Blob->Data == NULL) {
> ++ return EFI_OUT_OF_RESOURCES;
> ++ }
> ++
> ++ ZeroMem (Blob, sizeof (*Blob));
> ++
> + //
> + // Read blob.
> + //
> ++ Status = StrCpyS (Blob->Name, sizeof (Blob->Name), BlobItems->Name);
> ++ ASSERT (!EFI_ERROR (Status));
> ++ Blob->Size = Size;
> + Blob->Data = AllocatePool (Blob->Size);
> + if (Blob->Data == NULL) {
> + DEBUG ((
> +@@ -972,6 +1026,7 @@ FetchBlob (
> + (INT64)Blob->Size,
> + Blob->Name
> + ));
> ++ FreePool (Blob);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> +@@ -984,34 +1039,48 @@ FetchBlob (
> + ));
> +
> + ChunkData = Blob->Data;
> +- for (Idx = 0; Idx < ARRAY_SIZE (Blob->FwCfgItem); Idx++) {
> +- if (Blob->FwCfgItem[Idx].DataKey == 0) {
> ++ for (Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) {
> ++ if (BlobItems->FwCfgItem[Idx].DataKey == 0) {
> + break;
> + }
> +
> +- QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].DataKey);
> ++ QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].DataKey);
> ++ QemuKernelChunkedRead (ChunkData, BlobItems->FwCfgItem[Idx].Size);
> ++ ChunkData += BlobItems->FwCfgItem[Idx].Size;
> ++ }
> +
> +- Left = Blob->FwCfgItem[Idx].Size;
> +- while (Left > 0) {
> +- UINT32 Chunk;
> ++ Blob->Next = mKernelBlobs;
> ++ mKernelBlobs = Blob;
> ++ mKernelBlobCount++;
> ++ mTotalBlobBytes += Blob->Size;
> ++ return EFI_SUCCESS;
> ++}
> +
> +- Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;
> +- QemuFwCfgReadBytes (Chunk, ChunkData + Blob->FwCfgItem[Idx].Size - Left);
> +- Left -= Chunk;
> +- DEBUG ((
> +- DEBUG_VERBOSE,
> +- "%a: %Ld bytes remaining for \"%s\" (%d)\n",
> +- __func__,
> +- (INT64)Left,
> +- Blob->Name,
> +- (INT32)Idx
> +- ));
> +- }
> ++STATIC
> ++EFI_STATUS
> ++QemuKernelVerifyBlob (
> ++ CHAR16 *FileName,
> ++ EFI_STATUS FetchStatus
> ++ )
> ++{
> ++ KERNEL_BLOB *Blob;
> ++ EFI_STATUS Status;
> +
> +- ChunkData += Blob->FwCfgItem[Idx].Size;
> ++ if ((StrCmp (FileName, L"kernel") != 0) &&
> ++ (StrCmp (FileName, L"initrd") != 0) &&
> ++ (StrCmp (FileName, L"cmdline") != 0))
> ++ {
> ++ return EFI_SUCCESS;
> + }
> +
> +- return EFI_SUCCESS;
> ++ Blob = FindKernelBlob (FileName);
> ++ Status = VerifyBlob (
> ++ FileName,
> ++ Blob ? Blob->Data : NULL,
> ++ Blob ? Blob->Size : 0,
> ++ FetchStatus
> ++ );
> ++ return Status;
> + }
> +
> + //
> +@@ -1038,13 +1107,13 @@ QemuKernelLoaderFsDxeEntrypoint (
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> + {
> +- UINTN BlobType;
> +- KERNEL_BLOB *CurrentBlob;
> +- KERNEL_BLOB *KernelBlob;
> +- EFI_STATUS Status;
> +- EFI_STATUS FetchStatus;
> +- EFI_HANDLE FileSystemHandle;
> +- EFI_HANDLE InitrdLoadFile2Handle;
> ++ UINTN BlobIdx;
> ++ KERNEL_BLOB_ITEMS *BlobItems;
> ++ KERNEL_BLOB *Blob;
> ++ EFI_STATUS Status;
> ++ EFI_STATUS FetchStatus;
> ++ EFI_HANDLE FileSystemHandle;
> ++ EFI_HANDLE InitrdLoadFile2Handle;
> +
> + if (!QemuFwCfgIsAvailable ()) {
> + return EFI_NOT_FOUND;
> +@@ -1059,26 +1128,22 @@ QemuKernelLoaderFsDxeEntrypoint (
> + //
> + // Fetch all blobs.
> + //
> +- for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
> +- CurrentBlob = &mKernelBlob[BlobType];
> +- FetchStatus = FetchBlob (CurrentBlob);
> +-
> +- Status = VerifyBlob (
> +- CurrentBlob->Name,
> +- CurrentBlob->Data,
> +- CurrentBlob->Size,
> ++ for (BlobIdx = 0; BlobIdx < ARRAY_SIZE (mKernelBlobItems); ++BlobIdx) {
> ++ BlobItems = &mKernelBlobItems[BlobIdx];
> ++ FetchStatus = QemuKernelFetchBlob (BlobItems);
> ++
> ++ Status = QemuKernelVerifyBlob (
> ++ (CHAR16 *)BlobItems->Name,
> + FetchStatus
> + );
> + if (EFI_ERROR (Status)) {
> + goto FreeBlobs;
> + }
> +-
> +- mTotalBlobBytes += CurrentBlob->Size;
> + }
> +
> +- KernelBlob = &mKernelBlob[KernelBlobTypeKernel];
> +-
> +- if (KernelBlob->Data == NULL) {
> ++ Blob = FindKernelBlob (L"kernel");
> ++ if (Blob == NULL) {
> ++ DEBUG ((DEBUG_INFO, "%a: no kernel present -> quit\n", __func__));
> + Status = EFI_NOT_FOUND;
> + goto FreeBlobs;
> + }
> +@@ -1106,7 +1171,9 @@ QemuKernelLoaderFsDxeEntrypoint (
> + goto FreeBlobs;
> + }
> +
> +- if (KernelBlob[KernelBlobTypeInitrd].Size > 0) {
> ++ Blob = FindKernelBlob (L"initrd");
> ++ if (Blob != NULL) {
> ++ DEBUG ((DEBUG_INFO, "%a: initrd setup\n", __func__));
> + InitrdLoadFile2Handle = NULL;
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &InitrdLoadFile2Handle,
> +@@ -1141,13 +1208,11 @@ UninstallFileSystemHandle:
> + ASSERT_EFI_ERROR (Status);
> +
> + FreeBlobs:
> +- while (BlobType > 0) {
> +- CurrentBlob = &mKernelBlob[--BlobType];
> +- if (CurrentBlob->Data != NULL) {
> +- FreePool (CurrentBlob->Data);
> +- CurrentBlob->Size = 0;
> +- CurrentBlob->Data = NULL;
> +- }
> ++ while (mKernelBlobs != NULL) {
> ++ Blob = mKernelBlobs;
> ++ mKernelBlobs = Blob->Next;
> ++ FreePool (Blob->Data);
> ++ FreePool (Blob);
> + }
> +
> + return Status;
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-2.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-2.patch
> new file mode 100644
> index 0000000000..964ee306bf
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-2.patch
> @@ -0,0 +1,175 @@
> +From 20df7c42bd446fe725bfc78cdb40577456c421d8 Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Wed, 15 Jan 2025 00:29:52 +0100
> +Subject: [PATCH 02/10] OvmfPkg/QemuKernelLoaderFsDxe: add support for named
> + blobs
> +
> +Load all named fw_cfg blobs with "etc/boot/" prefix into the pseudo
> +filesystem.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/20df7c42bd446fe725bfc78cdb40577456c421d8]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../QemuKernelLoaderFsDxe.c | 94 ++++++++++++++++---
> + .../QemuKernelLoaderFsDxe.inf | 1 +
> + 2 files changed, 84 insertions(+), 11 deletions(-)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 7ad1b3828f..1f63adda0b 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -21,6 +21,7 @@
> + #include <Library/DebugLib.h>
> + #include <Library/DevicePathLib.h>
> + #include <Library/MemoryAllocationLib.h>
> ++#include <Library/PrintLib.h>
> + #include <Library/QemuFwCfgLib.h>
> + #include <Library/UefiBootServicesTableLib.h>
> + #include <Library/UefiRuntimeServicesTableLib.h>
> +@@ -32,12 +33,12 @@
> + // Static data that hosts the fw_cfg blobs and serves file requests.
> + //
> + typedef struct {
> +- CONST CHAR16 Name[8];
> ++ CHAR16 Name[8];
> + struct {
> +- FIRMWARE_CONFIG_ITEM CONST SizeKey;
> +- FIRMWARE_CONFIG_ITEM CONST DataKey;
> +- UINT32 Size;
> +- } FwCfgItem[2];
> ++ FIRMWARE_CONFIG_ITEM SizeKey;
> ++ FIRMWARE_CONFIG_ITEM DataKey;
> ++ UINT32 Size;
> ++ } FwCfgItem[2];
> + } KERNEL_BLOB_ITEMS;
> +
> + typedef struct KERNEL_BLOB KERNEL_BLOB;
> +@@ -989,15 +990,23 @@ QemuKernelFetchBlob (
> +
> + //
> + // Read blob size.
> ++ // Size != 0 -> use size as-is
> ++ // SizeKey != 0 -> read size from fw_cfg
> ++ // both are 0 -> unused entry
> + //
> + for (Size = 0, Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) {
> +- if (BlobItems->FwCfgItem[Idx].SizeKey == 0) {
> ++ if ((BlobItems->FwCfgItem[Idx].SizeKey == 0) &&
> ++ (BlobItems->FwCfgItem[Idx].Size == 0))
> ++ {
> + break;
> + }
> +
> +- QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey);
> +- BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 ();
> +- Size += BlobItems->FwCfgItem[Idx].Size;
> ++ if (BlobItems->FwCfgItem[Idx].SizeKey) {
> ++ QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey);
> ++ BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 ();
> ++ }
> ++
> ++ Size += BlobItems->FwCfgItem[Idx].Size;
> + }
> +
> + if (Size == 0) {
> +@@ -1083,6 +1092,55 @@ QemuKernelVerifyBlob (
> + return Status;
> + }
> +
> ++STATIC
> ++EFI_STATUS
> ++QemuKernelFetchNamedBlobs (
> ++ VOID
> ++ )
> ++{
> ++ struct {
> ++ UINT32 FileSize;
> ++ UINT16 FileSelect;
> ++ UINT16 Reserved;
> ++ CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE];
> ++ } *DirEntry;
> ++ KERNEL_BLOB_ITEMS Items;
> ++ EFI_STATUS Status;
> ++ EFI_STATUS FetchStatus;
> ++ UINT32 Count;
> ++ UINT32 Idx;
> ++
> ++ QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
> ++ Count = SwapBytes32 (QemuFwCfgRead32 ());
> ++
> ++ DirEntry = AllocatePool (sizeof (*DirEntry) * Count);
> ++ QemuFwCfgReadBytes (sizeof (*DirEntry) * Count, DirEntry);
> ++
> ++ for (Idx = 0; Idx < Count; ++Idx) {
> ++ if (AsciiStrnCmp (DirEntry[Idx].FileName, "etc/boot/", 9) != 0) {
> ++ continue;
> ++ }
> ++
> ++ ZeroMem (&Items, sizeof (Items));
> ++ UnicodeSPrint (Items.Name, sizeof (Items.Name), L"%a", DirEntry[Idx].FileName + 9);
> ++ Items.FwCfgItem[0].DataKey = SwapBytes16 (DirEntry[Idx].FileSelect);
> ++ Items.FwCfgItem[0].Size = SwapBytes32 (DirEntry[Idx].FileSize);
> ++
> ++ FetchStatus = QemuKernelFetchBlob (&Items);
> ++ Status = QemuKernelVerifyBlob (
> ++ (CHAR16 *)Items.Name,
> ++ FetchStatus
> ++ );
> ++ if (EFI_ERROR (Status)) {
> ++ FreePool (DirEntry);
> ++ return Status;
> ++ }
> ++ }
> ++
> ++ FreePool (DirEntry);
> ++ return EFI_SUCCESS;
> ++}
> ++
> + //
> + // The entry point of the feature.
> + //
> +@@ -1126,10 +1184,24 @@ QemuKernelLoaderFsDxeEntrypoint (
> + }
> +
> + //
> +- // Fetch all blobs.
> ++ // Fetch named blobs.
> + //
> ++ DEBUG ((DEBUG_INFO, "%a: named blobs (etc/boot/*)\n", __func__));
> ++ Status = QemuKernelFetchNamedBlobs ();
> ++ if (EFI_ERROR (Status)) {
> ++ goto FreeBlobs;
> ++ }
> ++
> ++ //
> ++ // Fetch traditional blobs.
> ++ //
> ++ DEBUG ((DEBUG_INFO, "%a: traditional blobs\n", __func__));
> + for (BlobIdx = 0; BlobIdx < ARRAY_SIZE (mKernelBlobItems); ++BlobIdx) {
> +- BlobItems = &mKernelBlobItems[BlobIdx];
> ++ BlobItems = &mKernelBlobItems[BlobIdx];
> ++ if (FindKernelBlob (BlobItems->Name)) {
> ++ continue;
> ++ }
> ++
> + FetchStatus = QemuKernelFetchBlob (BlobItems);
> +
> + Status = QemuKernelVerifyBlob (
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
> +index 7b35adb8e0..a2f44bbca1 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf
> +@@ -30,6 +30,7 @@
> + DebugLib
> + DevicePathLib
> + MemoryAllocationLib
> ++ PrintLib
> + QemuFwCfgLib
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-3.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-3.patch
> new file mode 100644
> index 0000000000..0ea2a70bf5
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-3.patch
> @@ -0,0 +1,42 @@
> +From adf385ecab69631952bdc8b774ebd77e82b94a00 Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Thu, 16 Jan 2025 15:42:13 +0100
> +Subject: [PATCH 03/10] OvmfPkg/QemuKernelLoaderFsDxe: allow longer file names
> +
> +QEMU_FW_CFG_FNAME_SIZE is 56. 'etc/boot/' prefix is minus 9. Add one
> +for the terminating '\0'. Effective max size is 48.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/adf385ecab69631952bdc8b774ebd77e82b94a00]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 4 ++--
> + 1 file changed, 2 insertions(+), 2 deletions(-)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 1f63adda0b..0947b6bf2d 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -33,7 +33,7 @@
> + // Static data that hosts the fw_cfg blobs and serves file requests.
> + //
> + typedef struct {
> +- CHAR16 Name[8];
> ++ CHAR16 Name[48];
> + struct {
> + FIRMWARE_CONFIG_ITEM SizeKey;
> + FIRMWARE_CONFIG_ITEM DataKey;
> +@@ -43,7 +43,7 @@ typedef struct {
> +
> + typedef struct KERNEL_BLOB KERNEL_BLOB;
> + struct KERNEL_BLOB {
> +- CHAR16 Name[8];
> ++ CHAR16 Name[48];
> + UINT32 Size;
> + UINT8 *Data;
> + KERNEL_BLOB *Next;
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-4.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-4.patch
> new file mode 100644
> index 0000000000..bba3b51c78
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-4.patch
> @@ -0,0 +1,34 @@
> +From 1111e9fe7078eed9e5c50e1808776ee40a629e16 Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Thu, 16 Jan 2025 15:52:54 +0100
> +Subject: [PATCH 04/10] OvmfPkg/QemuKernelLoaderFsDxe: drop bogus assert
> +
> +Triggers when trying to get root directory info.
> +Reproducer:
> + * Use qemu -kernel with something edk2 can not load.
> + * When dropped into the efi shell try inspect the file system.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1111e9fe7078eed9e5c50e1808776ee40a629e16]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 1 -
> + 1 file changed, 1 deletion(-)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 0947b6bf2d..3e1a876bf0 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -290,7 +290,6 @@ QemuKernelBlobTypeToFileInfo (
> +
> + NameSize = (StrLen (Name) + 1) * 2;
> + FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize;
> +- ASSERT (FileInfoSize >= sizeof *FileInfo);
> +
> + OriginalBufferSize = *BufferSize;
> + *BufferSize = FileInfoSize;
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-5.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-5.patch
> new file mode 100644
> index 0000000000..e3a8292356
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-5.patch
> @@ -0,0 +1,36 @@
> +From 46ae4e4b9574530e5081e98af0495d6f6d28379f Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Thu, 16 Jan 2025 16:03:01 +0100
> +Subject: [PATCH 05/10] OvmfPkg/QemuKernelLoaderFsDxe: accept absolute paths
> +
> +EFI shell looks for "\startup.nsh".
> +Try "-fw_cfg name=etc/boot/startup.nsh,string='echo hello'" ;)
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/46ae4e4b9574530e5081e98af0495d6f6d28379f]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 5 +++++
> + 1 file changed, 5 insertions(+)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 3e1a876bf0..5b90420dad 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -806,6 +806,11 @@ QemuKernelStubFileOpen (
> + //
> + // Locate the file.
> + //
> ++ if (FileName[0] == '\\') {
> ++ // also accept absolute paths, i.e. '\kernel' for 'kernel'
> ++ FileName++;
> ++ }
> ++
> + Blob = FindKernelBlob (FileName);
> +
> + if (Blob == NULL) {
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-6.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-6.patch
> new file mode 100644
> index 0000000000..3515efe008
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-6.patch
> @@ -0,0 +1,54 @@
> +From c45051450efbdae4a38f07998b3e7b77abe7173a Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Mon, 20 Jan 2025 11:28:37 +0100
> +Subject: [PATCH 06/10] OvmfPkg/QemuKernelLoaderFsDxe: don't quit when named
> + blobs are present
> +
> +Allows to use the qemu kernel loader pseudo file system for other
> +purposes than loading a linux kernel (or efi binary). Passing
> +startup.nsh for EFI shell is one example.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/c45051450efbdae4a38f07998b3e7b77abe7173a]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 7 +++++--
> + 1 file changed, 5 insertions(+), 2 deletions(-)
> +
> +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +index 5b90420dad..add914daa8 100644
> +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c
> +@@ -71,6 +71,7 @@ STATIC KERNEL_BLOB_ITEMS mKernelBlobItems[] = {
> +
> + STATIC KERNEL_BLOB *mKernelBlobs;
> + STATIC UINT64 mKernelBlobCount;
> ++STATIC UINT64 mKernelNamedBlobCount;
> + STATIC UINT64 mTotalBlobBytes;
> +
> + //
> +@@ -1139,6 +1140,8 @@ QemuKernelFetchNamedBlobs (
> + FreePool (DirEntry);
> + return Status;
> + }
> ++
> ++ mKernelNamedBlobCount++;
> + }
> +
> + FreePool (DirEntry);
> +@@ -1218,8 +1221,8 @@ QemuKernelLoaderFsDxeEntrypoint (
> + }
> +
> + Blob = FindKernelBlob (L"kernel");
> +- if (Blob == NULL) {
> +- DEBUG ((DEBUG_INFO, "%a: no kernel present -> quit\n", __func__));
> ++ if ((Blob == NULL) && (mKernelNamedBlobCount == 0)) {
> ++ DEBUG ((DEBUG_INFO, "%a: no kernel and no named blobs present -> quit\n", __func__));
> + Status = EFI_NOT_FOUND;
> + goto FreeBlobs;
> + }
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-7.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-7.patch
> new file mode 100644
> index 0000000000..a9d9922695
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-7.patch
> @@ -0,0 +1,124 @@
> +From 3da39f2cb681eb69f4eef54acd4b25d25cd7103d Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Wed, 10 Apr 2024 17:25:03 +0200
> +Subject: [PATCH 07/10] OvmfPkg/X86QemuLoadImageLib: support booting via shim
> +
> +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 <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/3da39f2cb681eb69f4eef54acd4b25d25cd7103d]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../X86QemuLoadImageLib/X86QemuLoadImageLib.c | 56 ++++++++++++++++++-
> + 1 file changed, 54 insertions(+), 2 deletions(-)
> +
> +diff --git a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> +index a7ab43ca74..e4dbc2dc7e 100644
> +--- a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> ++++ b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> +@@ -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
> + VOID
> + FreeLegacyImage (
> +@@ -339,6 +358,7 @@ QemuLoadKernelImage (
> + UINTN CommandLineSize;
> + CHAR8 *CommandLine;
> + UINTN InitrdSize;
> ++ BOOLEAN Shim;
> +
> + //
> + // Redundant assignment to work around GCC48/GCC49 limitations.
> +@@ -351,11 +371,35 @@ QemuLoadKernelImage (
> + 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);
> ++ }
> ++
> ++ if (Status != EFI_NOT_FOUND) {
> ++ DEBUG ((DEBUG_INFO, "%a: LoadImage(shim): %r\n", __func__, Status));
> ++ return Status;
> ++ }
> ++
> ++ 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;
> +@@ -465,6 +509,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 {
> +@@ -485,7 +536,8 @@ QemuLoadKernelImage (
> + UnicodeSPrintAsciiFormat (
> + KernelLoadedImage->LoadOptions,
> + KernelLoadedImage->LoadOptionsSize,
> +- "%a%a",
> ++ "%a%a%a",
> ++ (Shim == FALSE) ? "" : "kernel ",
> + (CommandLineSize == 0) ? "" : CommandLine,
> + (InitrdSize == 0) ? "" : " initrd=initrd"
> + );
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-8.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-8.patch
> new file mode 100644
> index 0000000000..97d77883fd
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-8.patch
> @@ -0,0 +1,125 @@
> +From 4b507b49664514d7f09e6b7a9ca2da25a5e440fd Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Thu, 11 Apr 2024 08:15:22 +0200
> +Subject: [PATCH 08/10] OvmfPkg/GenericQemuLoadImageLib: support booting via
> + shim
> +
> +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 <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/4b507b49664514d7f09e6b7a9ca2da25a5e440fd]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../GenericQemuLoadImageLib.c | 56 ++++++++++++++++++-
> + 1 file changed, 54 insertions(+), 2 deletions(-)
> +
> +diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> +index b99fb350aa..9d0ba77755 100644
> +--- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> ++++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> +@@ -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 = {
> + {
> + {
> +@@ -174,6 +193,7 @@ QemuLoadKernelImage (
> + UINTN CommandLineSize;
> + CHAR8 *CommandLine;
> + UINTN InitrdSize;
> ++ BOOLEAN Shim;
> +
> + //
> + // Load the image. This should call back into the QEMU EFI loader file system.
> +@@ -181,11 +201,35 @@ QemuLoadKernelImage (
> + 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);
> ++ }
> ++
> ++ if (Status != EFI_NOT_FOUND) {
> ++ DEBUG ((DEBUG_INFO, "%a: LoadImage(shim): %r\n", __func__, Status));
> ++ return Status;
> ++ }
> ++
> ++ 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;
> +@@ -303,6 +347,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 {
> +@@ -323,7 +374,8 @@ QemuLoadKernelImage (
> + UnicodeSPrintAsciiFormat (
> + KernelLoadedImage->LoadOptions,
> + KernelLoadedImage->LoadOptionsSize,
> +- "%a%a",
> ++ "%a%a%a",
> ++ (Shim == FALSE) ? "" : "kernel ",
> + (CommandLineSize == 0) ? "" : CommandLine,
> + (InitrdSize == 0) ? "" : " initrd=initrd"
> + );
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-9.patch b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-9.patch
> new file mode 100644
> index 0000000000..8f0535cc4b
> --- /dev/null
> +++ b/meta/recipes-core/ovmf/ovmf/CVE-2025-2296-9.patch
> @@ -0,0 +1,108 @@
> +From 1549bf11cc94b135b6ad8fa5ebc34bdf7c18ba9c Mon Sep 17 00:00:00 2001
> +From: Gerd Hoffmann <kraxel@redhat.com>
> +Date: Tue, 17 Dec 2024 09:59:21 +0100
> +Subject: [PATCH 09/10] OvmfPkg/X86QemuLoadImageLib: make legacy loader
> + configurable.
> +
> +Add the 'opt/org.tianocore/EnableLegacyLoader' FwCfg option to
> +enable/disable the insecure legacy linux kernel loader.
> +
> +For now this is enabled by default. Probably the default will be
> +flipped to disabled at some point in the future.
> +
> +Also print a warning to the screen in case the linux kernel secure
> +boot verification has failed.
> +
> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> +
> +CVE: CVE-2025-2296
> +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1549bf11cc94b135b6ad8fa5ebc34bdf7c18ba9c]
> +Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
> +---
> + .../X86QemuLoadImageLib/X86QemuLoadImageLib.c | 48 ++++++++++++++++---
> + .../X86QemuLoadImageLib.inf | 1 +
> + 2 files changed, 42 insertions(+), 7 deletions(-)
> +
> +diff --git a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> +index e4dbc2dc7e..2d610f6bd3 100644
> +--- a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> ++++ b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c
> +@@ -19,8 +19,10 @@
> + #include <Library/MemoryAllocationLib.h>
> + #include <Library/PrintLib.h>
> + #include <Library/QemuFwCfgLib.h>
> ++#include <Library/QemuFwCfgSimpleParserLib.h>
> + #include <Library/QemuLoadImageLib.h>
> + #include <Library/UefiBootServicesTableLib.h>
> ++#include <Library/UefiLib.h>
> + #include <Protocol/DevicePath.h>
> + #include <Protocol/LoadedImage.h>
> + #include <Protocol/OvmfLoadedX86LinuxKernel.h>
> +@@ -421,13 +423,45 @@ QemuLoadKernelImage (
> + // Fall through
> + //
> + case EFI_ACCESS_DENIED:
> +- //
> +- // We are running with UEFI secure boot enabled, and the image failed to
> +- // authenticate. For compatibility reasons, we fall back to the legacy
> +- // loader in this case.
> +- //
> +- // Fall through
> +- //
> ++ //
> ++ // We are running with UEFI secure boot enabled, and the image failed to
> ++ // authenticate. For compatibility reasons, we fall back to the legacy
> ++ // loader in this case (unless disabled via fw_cfg).
> ++ //
> ++ {
> ++ EFI_STATUS RetStatus;
> ++ BOOLEAN Enabled = TRUE;
> ++
> ++ AsciiPrint (
> ++ "OVMF: Secure boot image verification failed. Consider using the '-shim'\n"
> ++ "OVMF: command line switch for qemu (available in version 10.0 + newer).\n"
> ++ "\n"
> ++ );
> ++
> ++ RetStatus = QemuFwCfgParseBool (
> ++ "opt/org.tianocore/EnableLegacyLoader",
> ++ &Enabled
> ++ );
> ++ if (EFI_ERROR (RetStatus)) {
> ++ Enabled = TRUE;
> ++ }
> ++
> ++ if (!Enabled) {
> ++ AsciiPrint (
> ++ "OVMF: Fallback to insecure legacy linux kernel loader is disabled.\n"
> ++ "\n"
> ++ );
> ++ return EFI_ACCESS_DENIED;
> ++ } else {
> ++ AsciiPrint (
> ++ "OVMF: Using legacy linux kernel loader (insecure and deprecated).\n"
> ++ "\n"
> ++ );
> ++ //
> ++ // Fall through
> ++ //
> ++ }
> ++ }
> + case EFI_UNSUPPORTED:
> + //
> + // The image is not natively supported or cross-type supported. Let's try
> +diff --git a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
> +index c7ec041cb7..09babd3be8 100644
> +--- a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
> ++++ b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf
> +@@ -33,6 +33,7 @@
> + LoadLinuxLib
> + PrintLib
> + QemuFwCfgLib
> ++ QemuFwCfgSimpleParserLib
> + ReportStatusCodeLib
> + UefiBootServicesTableLib
> +
> +--
> +2.49.0
> +
> diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb
> index 319f03a8d2..f0503db9fb 100644
> --- a/meta/recipes-core/ovmf/ovmf_git.bb
> +++ b/meta/recipes-core/ovmf/ovmf_git.bb
> @@ -26,6 +26,16 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
> file://0004-reproducible.patch \
> file://0001-MdePkg-Fix-overflow-issue-in-BasePeCoffLib.patch \
> file://0001-MdeModulePkg-Potential-UINT32-overflow-in-S3-ResumeC.patch \
> + file://0001-AmdSev-Halt-on-failed-blob-allocation.patch \
> + file://CVE-2025-2296-1.patch \
> + file://CVE-2025-2296-2.patch \
> + file://CVE-2025-2296-3.patch \
> + file://CVE-2025-2296-4.patch \
> + file://CVE-2025-2296-5.patch \
> + file://CVE-2025-2296-6.patch \
> + file://CVE-2025-2296-7.patch \
> + file://CVE-2025-2296-8.patch \
> + file://CVE-2025-2296-9.patch \
> "
>
> PV = "edk2-stable202402"
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#235976): https://lists.openembedded.org/g/openembedded-core/message/235976
> Mute This Topic: https://lists.openembedded.org/mt/119026030/3617049
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [hongxu.jia@windriver.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
prev parent reply other threads:[~2026-04-27 5:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 4:56 [scarthgap][PATCH 1/3] u-boot: fix CVE-2025-24857 Hongxu Jia
2026-04-27 4:56 ` [scarthgap][PATCH 2/3] ovmf: fix CVE-2025-2296 Hongxu Jia
2026-04-27 4:56 ` [scarthgap][PATCH 3/3] ovmf: fix CVE-2024-38798 Hongxu Jia
2026-04-30 9:25 ` [OE-core] " Fabien Thomas
2026-04-30 12:05 ` Hongxu Jia
2026-04-30 12:25 ` Fabien Thomas
[not found] ` <18AA1DD7A8866F0B.1773850@lists.openembedded.org>
2026-04-27 5:01 ` Hongxu Jia [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6db064df-dafc-4634-aae8-8587d325751d@windriver.com \
--to=hongxu.jia@windriver.com \
--cc=openembedded-core@lists.openembedded.org \
--cc=yoann.congal@smile.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox