diff mbox series

[scarthgap,1/3] u-boot: fix CVE-2025-24857

Message ID 20260427045650.2365793-1-hongxu.jia@windriver.com
State Under Review
Delegated to: Fabien Thomas
Headers show
Series [scarthgap,1/3] u-boot: fix CVE-2025-24857 | expand

Commit Message

Hongxu Jia April 27, 2026, 4:56 a.m. UTC
According to [1], Improper access control for volatile memory containing boot
code in Universal Boot Loader (U-Boot) before 2017.11 and Qualcomm chips IPQ4019,
IPQ5018, IPQ5322, IPQ6018, IPQ8064, IPQ8074, and IPQ9574 could allow an attacker
to execute arbitrary code.

Backport a patch [2] from upstream to fix CVE-2025-24857

[1] https://nvd.nist.gov/vuln/detail/CVE-2025-24857
[2] https://source.denx.de/u-boot/u-boot/-/commit/87d85139a96a39429120cca838e739408ef971a2

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 .../u-boot/files/CVE-2025-24857.patch         | 42 +++++++++++++++++++
 meta/recipes-bsp/u-boot/u-boot-common.inc     |  4 +-
 2 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 meta/recipes-bsp/u-boot/files/CVE-2025-24857.patch

Comments

Hongxu Jia April 27, 2026, 5:01 a.m. UTC | #1
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]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

Patch

diff --git a/meta/recipes-bsp/u-boot/files/CVE-2025-24857.patch b/meta/recipes-bsp/u-boot/files/CVE-2025-24857.patch
new file mode 100644
index 0000000000..99acd5bab1
--- /dev/null
+++ b/meta/recipes-bsp/u-boot/files/CVE-2025-24857.patch
@@ -0,0 +1,42 @@ 
+From 15a46d72515c04d0eeaca19bf0356a39efc9cf93 Mon Sep 17 00:00:00 2001
+From: Tom Rini <trini@konsulko.com>
+Date: Tue, 9 Dec 2025 15:23:01 -0600
+Subject: [PATCH] fs: fat: Perform sanity checks on getsize in get_fatent()
+
+We do not perform a check on the value of getsize in get_fatent to
+ensure that it will fit within the allocated buffer. For safety sake,
+add a check now and if the value exceeds FATBUFBLOCKS use that value
+instead. While not currently actively exploitable, it was in the past so
+adding this check is worthwhile.
+
+This addresses CVE-2025-24857 and was originally reported by Harvey
+Phillips of Amazon Element55.
+
+Signed-off-by: Tom Rini <trini@konsulko.com>
+
+CVE: CVE-2025-24857
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/87d85139a96a39429120cca838e739408ef971a2]
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ fs/fat/fat.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/fat/fat.c b/fs/fat/fat.c
+index e2570e81676..f6dc7ed15fe 100644
+--- a/fs/fat/fat.c
++++ b/fs/fat/fat.c
+@@ -215,6 +215,11 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry)
+ 		if (flush_dirty_fat_buffer(mydata) < 0)
+ 			return -1;
+ 
++		if (getsize > FATBUFBLOCKS) {
++			debug("getsize is too large for bufptr\n");
++			getsize = FATBUFBLOCKS;
++		}
++
+ 		if (disk_read(startblock, getsize, bufptr) < 0) {
+ 			debug("Error reading FAT blocks\n");
+ 			return ret;
+-- 
+2.49.0
+
diff --git a/meta/recipes-bsp/u-boot/u-boot-common.inc b/meta/recipes-bsp/u-boot/u-boot-common.inc
index 1f17bd7d0a..5f6bd44ab7 100644
--- a/meta/recipes-bsp/u-boot/u-boot-common.inc
+++ b/meta/recipes-bsp/u-boot/u-boot-common.inc
@@ -14,7 +14,9 @@  PE = "1"
 # repo during parse
 SRCREV = "866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e"
 
-SRC_URI = "git://source.denx.de/u-boot/u-boot.git;protocol=https;branch=master"
+SRC_URI = "git://source.denx.de/u-boot/u-boot.git;protocol=https;branch=master \
+           file://CVE-2025-24857.patch \
+"
 
 S = "${WORKDIR}/git"
 B = "${WORKDIR}/build"