From patchwork Mon Apr 27 04:56:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hongxu Jia X-Patchwork-Id: 86981 X-Patchwork-Delegate: fabien.thomas@smile.fr Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2E27FF8865 for ; Mon, 27 Apr 2026 04:57:05 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.35637.1777265814147285785 for ; Sun, 26 Apr 2026 21:56:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=i0xYM0U3; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=857747364e=hongxu.jia@windriver.com) Received: from pps.filterd (m0250811.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R4aZGq2781991; Mon, 27 Apr 2026 04:56:53 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=content-transfer-encoding:content-type:date:from:message-id :mime-version:subject:to; s=PPS06212021; bh=vE8MbGKCE/ObxiUkYtcH 94fIgpz8mypVmFWnDqmr44w=; b=i0xYM0U3OZZrckBwHGOkOCUSA5/hiyzjVmsb XsKr1FLwa1fP4PKaaBYoLlnskvFhQ5udTNgsud870jeDsNHgwz6nZmeRDztCokgb 7j1gfLnZLAQzAIwndEaHUhzqaYM354gBA2yAQe6vuEijvYAaNYrp737DYw9LuBYT zUoqs9UeCX/XUhYeIV4MfYeYMi58+G3FvvFoNB4NIJ7rcEEotMPQxpqjudvhlCTR 0uWR1XGBor7Oocmoe2UqKGAx1adL6TigB6DB73zm5J1+AYY8SHgJKf5iKYEC9mqd P2qRi1jmUHVhyQ+W/2TubKaE8eR2pyY7XTN0J8YdpIWlZBt8tw== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4drju09kwt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 27 Apr 2026 04:56:52 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Sun, 26 Apr 2026 21:56:51 -0700 Received: from pek-lpg-core5.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Sun, 26 Apr 2026 21:56:50 -0700 From: Hongxu Jia To: , Subject: [scarthgap][PATCH 1/3] u-boot: fix CVE-2025-24857 Date: Mon, 27 Apr 2026 12:56:48 +0800 Message-ID: <20260427045650.2365793-1-hongxu.jia@windriver.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Authority-Analysis: v=2.4 cv=J+SaKgnS c=1 sm=1 tr=0 ts=69eeec94 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=klDOsUkWDRETUCZYPvoE:22 a=PYnjg3YJAAAA:8 a=YfCOm-DyAAAA:8 a=t7CeM3EgAAAA:8 a=k-42gJp3AAAA:8 a=74-8NBBHaaayuivBuCkA:9 a=zQLMK8awuJ6_Hvp-_9Ux:22 a=FdTzh2GWekK77mhwV6Dw:22 a=uCSXFHLys93vLW5PjgO_:22 X-Proofpoint-GUID: 7oFLzBJVC1qWUimmkJ8DukUCT6uc6xIb X-Proofpoint-ORIG-GUID: 7oFLzBJVC1qWUimmkJ8DukUCT6uc6xIb X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDA1MCBTYWx0ZWRfX6CUrSk4OnmYw w5eJxN30Zm49qhd4JeTCRAiDq5v0TlpjDLcu+hY9jQuy34BFCInxFHpt8muNZgnop8eYpH0eEpw UCw0cXJLSaImg8UvYAeTACNW0LRYVfkUpfE5aAUI/WR2g73TfTRsLSiBw3wuZYrOyE3vX02BvMB +Zpg89SzVDbDuWOe6WFWFeab45AsUXKY3OsQttzMhuV0GQLK6MIsQt8tjChqGA/Mz/gZstrtpnf 9vgY5e32GpnChCUc0bdzNhf5Xrn4/F/6A8qChcFTg6EJwekdHtbqU17QFbNZeQCpVlx80WY1/gk XJMicCO9NPSqcOApBXTIiSj3DDnSCuMrp2YBN0qJtubtjbAUMzfXzaHqtohws/1/Py5HEoto1yr r/3wzPO5Jq0ticW9llO2GAyE5yfyT+ClAMamTiPQNF2EJklg9/ACvyt050uCjS0uYlftspi/6lX YJLH5Pv5SGb5p8MnGzw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-27_01,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 lowpriorityscore=0 suspectscore=0 adultscore=0 malwarescore=0 phishscore=0 clxscore=1011 priorityscore=1501 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270050 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 27 Apr 2026 04:57:05 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/235975 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 --- .../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 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 +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 + +CVE: CVE-2025-24857 +Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/87d85139a96a39429120cca838e739408ef971a2] +Signed-off-by: Hongxu Jia +--- + 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" From patchwork Mon Apr 27 04:56:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hongxu Jia X-Patchwork-Id: 86982 X-Patchwork-Delegate: fabien.thomas@smile.fr Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A058DFF8861 for ; Mon, 27 Apr 2026 04:57:04 +0000 (UTC) Received: from mx0a-0064b401.pphosted.com (mx0a-0064b401.pphosted.com [205.220.166.238]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.35638.1777265814555156940 for ; Sun, 26 Apr 2026 21:56:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=SGM+dfUI; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.166.238, mailfrom: prvs=857747364e=hongxu.jia@windriver.com) Received: from pps.filterd (m0250810.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R4ktLk2953450; Sun, 26 Apr 2026 21:56:53 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=PPS06212021; bh=Ms1zEoHkb6f9qr0PgpjTkPJlCriwZ97uTQgtSo5GHOM=; b=SGM+dfUIcrxx QScFP8C00Lk8kDUsmQbSvpJq/a89M49P3gs3ayFBy74ObF5GTwGSQMqh2hyQCifp vp1OvP/yd5J2ondPF7stEroVX9+v49SEEXhdE84VQyBMV6pYTe/hXj0gySHy9Hxm EriM8W6szMx3TYRdPEalmA2Y2RZxAGqy1jqhO1b7C3MLD+u9RJDtdwFfMQZdSdxL WjpFpVXGj49Ryzk+xR+62W/uGc1j4iZMeMpewoDT1EiiEaanQ2s1pFEgjCXGdcUT F9wSOEKNW+HxTxqNQEQdepvzXz9NgjKcAHkc1ht/yDrpe6P2ETOvu0xqug6yuz1g DwxaMh9rpQ== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4drrw2scc5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Sun, 26 Apr 2026 21:56:53 -0700 (PDT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Sun, 26 Apr 2026 21:56:53 -0700 Received: from pek-lpg-core5.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Sun, 26 Apr 2026 21:56:52 -0700 From: Hongxu Jia To: , Subject: [scarthgap][PATCH 2/3] ovmf: fix CVE-2025-2296 Date: Mon, 27 Apr 2026 12:56:49 +0800 Message-ID: <20260427045650.2365793-2-hongxu.jia@windriver.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260427045650.2365793-1-hongxu.jia@windriver.com> References: <20260427045650.2365793-1-hongxu.jia@windriver.com> MIME-Version: 1.0 X-Proofpoint-GUID: gPfkAhb_urUfpbSOacq4oaxiqxDvV7wu X-Proofpoint-ORIG-GUID: gPfkAhb_urUfpbSOacq4oaxiqxDvV7wu X-Authority-Analysis: v=2.4 cv=Pu+jqQM3 c=1 sm=1 tr=0 ts=69eeec95 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=HK-ge7EqtdluswH-FwHe:22 a=PYnjg3YJAAAA:8 a=NEAV23lmAAAA:8 a=t7CeM3EgAAAA:8 a=VnNF1IyMAAAA:8 a=20KFwNOVAAAA:8 a=UF_1N54dQa9_ZajwrAQA:9 a=Xsb97kV5trg0EJB2:21 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDA1MCBTYWx0ZWRfX9FWJux6W9X0D dEJQyDOXBnQ2NfU0zVwmpLwJ0qMPD8mXzWdyjqXlDeSbDaOaNsGe91EzleYKu8rHzU5w7jc7G+P L+A1MZJhwQufquLPNCdSXW0uxTpDJgerLTfAXI+ImOVX2magwAaGfFCEnIX5aI1En/e7W135Rfq OJO37+kwi8co/RbgNgv5RsHOyFJHQ1U90S++1TySjsmCcLPcGj1878lJeQbpqAACgcyb41dPi3C TqE7t3xFs4SAZXzHwKAiNdvkiZWG9owwo2CBPIGm56dOPpvlzz/EII7cVh7HqhbL9OivdfnDNPB UK4RbbDUH4BIqHc73ponoRHBrhSXqyAxt8NNNIerFKOzTbeFggBL+NQW2YEHHyCG06ta7h5ai7p XXRodvFzY0GP6U+X4u9YlR/gLOUIyoRp85gYh5eUX+ArGn5uC22owcTiLqYFRVlIgr1H1ipt3Vt s28rnLpQqw91RrEaOSQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-27_01,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 spamscore=0 clxscore=1011 impostorscore=0 suspectscore=0 priorityscore=1501 adultscore=0 phishscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270050 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 27 Apr 2026 04:57:04 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/235976 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 --- ...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 +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 + +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/10b4bb8d6d0c515ed9663691aea3684be8f7b0fc] +Signed-off-by: Hongxu Jia +--- + .../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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/459f5ffa24ae8574657c4105af0ff7dc30ac428d] +Signed-off-by: Hongxu Jia +--- + .../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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/20df7c42bd446fe725bfc78cdb40577456c421d8] +Signed-off-by: Hongxu Jia +--- + .../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 + #include + #include ++#include + #include + #include + #include +@@ -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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/adf385ecab69631952bdc8b774ebd77e82b94a00] +Signed-off-by: Hongxu Jia +--- + 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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1111e9fe7078eed9e5c50e1808776ee40a629e16] +Signed-off-by: Hongxu Jia +--- + 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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/46ae4e4b9574530e5081e98af0495d6f6d28379f] +Signed-off-by: Hongxu Jia +--- + 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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/c45051450efbdae4a38f07998b3e7b77abe7173a] +Signed-off-by: Hongxu Jia +--- + 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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/3da39f2cb681eb69f4eef54acd4b25d25cd7103d] +Signed-off-by: Hongxu Jia +--- + .../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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/4b507b49664514d7f09e6b7a9ca2da25a5e440fd] +Signed-off-by: Hongxu Jia +--- + .../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 +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 + +CVE: CVE-2025-2296 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1549bf11cc94b135b6ad8fa5ebc34bdf7c18ba9c] +Signed-off-by: Hongxu Jia +--- + .../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 + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -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" From patchwork Mon Apr 27 04:56:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hongxu Jia X-Patchwork-Id: 86980 X-Patchwork-Delegate: fabien.thomas@smile.fr Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F7BDFF8850 for ; Mon, 27 Apr 2026 04:57:04 +0000 (UTC) Received: from mx0b-0064b401.pphosted.com (mx0b-0064b401.pphosted.com [205.220.178.238]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.35986.1777265816439810197 for ; Sun, 26 Apr 2026 21:56:56 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@windriver.com header.s=PPS06212021 header.b=D7gZ4nyX; spf=permerror, err=parse error for token &{10 18 %{ir}.%{v}.%{d}.spf.has.pphosted.com}: invalid domain name (domain: windriver.com, ip: 205.220.178.238, mailfrom: prvs=857747364e=hongxu.jia@windriver.com) Received: from pps.filterd (m0250811.ppops.net [127.0.0.1]) by mx0a-0064b401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 63R3WndY2673312; Mon, 27 Apr 2026 04:56:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=windriver.com; h=content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=PPS06212021; bh=aQmJJG2HArLXmRdxp2KMmAb3tNkxbDHe0MocQvRrtQw=; b=D7gZ4nyXV1KF LyxzDrELWQOAaEhUFyQvvh9l0hqCULE9N7K+Vdpm6TamV74FLotgUtOA92vJVsJu O9uYMiXE0nc8HBOuvUFBSYV8yDgm/YbXpovLzVzA0C/jlAHipmyZUWW/UtPPQXmd SOGsDYkoNEKwJ5Pxe8KPMJzpgKj2Pe77uzfqWGZu19DIVMSXgALADKafu5fmNDiS CkxK/CLfMGnZNPTpiAgqk+rigPuKZC2PQOaJV5utI4PNtR46brTS8B0xWlbf9Akt 8M9G04cJ4aeOf9trc1/POsyM03LG4HtNcROwKJn9VX6ryPtOWJDwJ6jFIlRw7KzA rXuDtmHX4A== Received: from ala-exchng02.corp.ad.wrs.com (ala-exchng02.wrs.com [128.224.246.37]) by mx0a-0064b401.pphosted.com (PPS) with ESMTPS id 4drju09kwu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 27 Apr 2026 04:56:55 +0000 (GMT) Received: from ala-exchng01.corp.ad.wrs.com (10.11.224.121) by ALA-EXCHNG02.corp.ad.wrs.com (10.11.224.122) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.61; Sun, 26 Apr 2026 21:56:54 -0700 Received: from pek-lpg-core5.wrs.com (10.11.232.110) by ala-exchng01.corp.ad.wrs.com (10.11.224.121) with Microsoft SMTP Server id 15.1.2507.61 via Frontend Transport; Sun, 26 Apr 2026 21:56:53 -0700 From: Hongxu Jia To: , Subject: [scarthgap][PATCH 3/3] ovmf: fix CVE-2024-38798 Date: Mon, 27 Apr 2026 12:56:50 +0800 Message-ID: <20260427045650.2365793-3-hongxu.jia@windriver.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260427045650.2365793-1-hongxu.jia@windriver.com> References: <20260427045650.2365793-1-hongxu.jia@windriver.com> MIME-Version: 1.0 X-Authority-Analysis: v=2.4 cv=J+SaKgnS c=1 sm=1 tr=0 ts=69eeec97 cx=c_pps a=Lg6ja3A245NiLSnFpY5YKQ==:117 a=Lg6ja3A245NiLSnFpY5YKQ==:17 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10 a=VkNPw1HP01LnGYTKEx00:22 a=bi6dqmuHe4P4UrxVR6um:22 a=klDOsUkWDRETUCZYPvoE:22 a=PYnjg3YJAAAA:8 a=NEAV23lmAAAA:8 a=t7CeM3EgAAAA:8 a=c-OXHmbyAAAA:8 a=XZ9oeUmmphtA08bY2KAA:9 a=QEXdDO2ut3YA:10 a=FdTzh2GWekK77mhwV6Dw:22 a=1BV3uS847Uy0Hebj2SdW:22 X-Proofpoint-GUID: xWyHaloiKyv15PT3HOGsKSntFNWpO798 X-Proofpoint-ORIG-GUID: xWyHaloiKyv15PT3HOGsKSntFNWpO798 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNDI3MDA1MCBTYWx0ZWRfX9wsL9lRPcdiU zIXZpJnSAieZ8r8rC2ox/N+P0x46J6yOXHXDPxNUPkw2jnSN8y1hvuxFRhpUnBMNZk2VItzXvBF 7eNow+TgMxXCY6IWJNxukS0IRQHjVc+5tAxjPwfnPyTxAMvjazPMRkvBe+x/yElNF31hqAd3gki mpJH+qkbd3QqMJVM+f+rJsuhpLFsDJvVr/b0x8pbaN66Ul4uweJ9ji+8Ia+ODjdUljxFkvqWPvW dzWmVlqssg+aOPxDZitsgCCEDI9+1hHw+6mkllLANsIuXxKgEC1VOWUo2eEJbR3SZ70GkLL+C6W vNs85mtD26SdxPVOTMF5x752phlyl2F77wF04BOF0nVeB+RGvAtMacJqefU7FBQ0PGG/LCFkWTJ c2kr1gyWdkx6Y2U+xOddZBAmqd0p23uAuiH1f5VxBjS1MogUHYJuKMsXSH/lzs0R9yU5xRwumYK OT5zDErZWrTXp6/4L5g== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-04-27_01,2026-04-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 lowpriorityscore=0 suspectscore=0 adultscore=0 malwarescore=0 phishscore=0 clxscore=1011 priorityscore=1501 spamscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604270050 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 27 Apr 2026 04:57:04 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/235977 According to [1], EDK2 contains a vulnerability in BIOS where an attacker may cause “Exposure of Sensitive Information to an Unauthorized Actor” by local access. Successful exploitation of this vulnerability will lead to possible information disclosure or escalation of privilege and impact Confidentiality. Backport a patch [2] from upstream to fix CVE-2024-38798 [1] https://nvd.nist.gov/vuln/detail/CVE-2024-38798 [2] https://github.com/tianocore/edk2/commit/0cad130cb4885961da201bb9b08424b3fd3d2249 Signed-off-by: Hongxu Jia --- .../ovmf/ovmf/CVE-2024-38798.patch | 116 ++++++++++++++++++ meta/recipes-core/ovmf/ovmf_git.bb | 1 + 2 files changed, 117 insertions(+) create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2024-38798.patch diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2024-38798.patch b/meta/recipes-core/ovmf/ovmf/CVE-2024-38798.patch new file mode 100644 index 0000000000..2d0a73c7a6 --- /dev/null +++ b/meta/recipes-core/ovmf/ovmf/CVE-2024-38798.patch @@ -0,0 +1,116 @@ +From 81263e46ad8cf2a6c7d86bc51c95342d07ec31ca Mon Sep 17 00:00:00 2001 +From: Hongxu Jia +Date: Mon, 5 Jan 2026 13:04:18 +0800 +Subject: [PATCH] MdeModulePkg : Clear keyboard queue buffer after reading + +There is a possibility to retrieve user input keystroke data stored in the +queue buffer via the EFI_SIMPLE_TEXT_INPUT_PROTOCOL pointer. To prevent +exposure of the password string, clear the queue buffer by filling it +with zeros after reading. + +Signed-off-by: Nick Wang + +CVE: CVE-2024-38798 +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/0cad130cb4885961da201bb9b08424b3fd3d2249] +Signed-off-by: Hongxu Jia +--- + MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c | 2 ++ + MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c | 1 + + MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c | 2 +- + .../Universal/Console/ConSplitterDxe/ConSplitter.c | 1 + + .../Universal/Console/TerminalDxe/TerminalConIn.c | 8 ++++++-- + 5 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c +index 981309f..32757a7 100644 +--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c ++++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c +@@ -650,6 +650,8 @@ PopScancodeBufHead ( + if (Buf != NULL) { + Buf[Index] = Queue->Buffer[Queue->Head]; + } ++ ++ Queue->Buffer[Queue->Head] = 0; + } + + return EFI_SUCCESS; +diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c +index 81d3c6e..e03c88f 100644 +--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c ++++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c +@@ -51,6 +51,7 @@ PopEfikeyBufHead ( + CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA)); + } + ++ ZeroMem (&Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA)); + Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT; + return EFI_SUCCESS; + } +diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c +index b5a6459..7df1566 100644 +--- a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c ++++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c +@@ -1840,7 +1840,7 @@ Dequeue ( + } + + CopyMem (Item, Queue->Buffer[Queue->Head], ItemSize); +- ++ ZeroMem (Queue->Buffer[Queue->Head], ItemSize); + // + // Adjust the head pointer of the FIFO keyboard buffer. + // +diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c +index 0a776f3..5c1a35e 100644 +--- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c ++++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c +@@ -3537,6 +3537,7 @@ ConSplitterTextInExDequeueKey ( + &Private->KeyQueue[1], + Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA) + ); ++ ZeroMem (&Private->KeyQueue[Private->CurrentNumberOfKeys], sizeof (EFI_KEY_DATA)); + return EFI_SUCCESS; + } + +diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +index f1d0a34..8aafb4b 100644 +--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c ++++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +@@ -760,7 +760,8 @@ RawFiFoRemoveOneKey ( + return FALSE; + } + +- *Output = TerminalDevice->RawFiFo->Data[Head]; ++ *Output = TerminalDevice->RawFiFo->Data[Head]; ++ TerminalDevice->RawFiFo->Data[Head] = 0; + + TerminalDevice->RawFiFo->Head = (UINT8)((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1)); + +@@ -881,6 +882,7 @@ EfiKeyFiFoForNotifyRemoveOneKey ( + } + + CopyMem (Output, &EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY)); ++ ZeroMem (&EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY)); + + EfiKeyFiFo->Head = (UINT8)((Head + 1) % (FIFO_MAX_NUMBER + 1)); + +@@ -1032,6 +1034,7 @@ EfiKeyFiFoRemoveOneKey ( + } + + CopyMem (Output, &TerminalDevice->EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY)); ++ ZeroMem (&TerminalDevice->EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY)); + + TerminalDevice->EfiKeyFiFo->Head = (UINT8)((Head + 1) % (FIFO_MAX_NUMBER + 1)); + +@@ -1142,7 +1145,8 @@ UnicodeFiFoRemoveOneKey ( + Head = TerminalDevice->UnicodeFiFo->Head; + ASSERT (Head < FIFO_MAX_NUMBER + 1); + +- *Output = TerminalDevice->UnicodeFiFo->Data[Head]; ++ *Output = TerminalDevice->UnicodeFiFo->Data[Head]; ++ TerminalDevice->UnicodeFiFo->Data[Head] = 0; + + TerminalDevice->UnicodeFiFo->Head = (UINT8)((Head + 1) % (FIFO_MAX_NUMBER + 1)); + } +-- +2.34.1 + diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb index f0503db9fb..85b3d7c911 100644 --- a/meta/recipes-core/ovmf/ovmf_git.bb +++ b/meta/recipes-core/ovmf/ovmf_git.bb @@ -36,6 +36,7 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \ file://CVE-2025-2296-7.patch \ file://CVE-2025-2296-8.patch \ file://CVE-2025-2296-9.patch \ + file://CVE-2024-38798.patch \ " PV = "edk2-stable202402"