4 检查漏洞

4 OpenEmbedded-Core (OE-Core) 中的漏洞

Yocto Project 建立了基础设施,用于跟踪和处理尚未修复的已知安全漏洞, 这些漏洞由公开的 通用漏洞披露(CVE) 数据库记录。

Yocto Project 为 OpenEmbedded-Core (OE-Core) 中的软件包维护 已知漏洞列表, 跟踪未修补 CVE 数量的变化和补丁状态。当前开发版本及每个受支持的发行版本 都提供这些信息。

安全是一个持续过程,而不是产品,因此在任何时候都可能有一些安全问题影响 OpenEmbedded-Core (OE-Core)。维护者、用户、贡献者及其他关注这些 问题的人需要调查问题,并通过更新软件组件或应用补丁来尝试修复。建议与 OpenEmbedded-Core (OE-Core) 上游维护者合作并提交修复补丁,详见 “向组件贡献修改”。

4 在构建时检查漏洞

要为正在构建的特定镜像或目标启用 CVE 安全漏洞检查,请在 Build Directory 中运行以下命令:

$ bitbake-config-build enable-fragment core/yocto/sbom-cve-check

或者在 configuration file 中添加以下语句:

OE_FRAGMENTS += "core/yocto/sbom-cve-check"

这会启用 sbom-cve-check 类,并应用其推荐设置。

CVE 数据库中包含一些较早且不完整的条目,已判定它们不影响 OpenEmbedded-Core (OE-Core)。可添加以下语句将这些条目排除在检查之外:

include conf/distro/include/cve-extra-exclusions.inc

启用 core/yocto/sbom-cve-check 片段后, BitBake 构建镜像时会尝试将每个已编译软件组件的配方名称及版本信息 映射到 CVE 数据库,并在部署目录( DEPLOY_DIR_IMAGE )中生成报告。 其中之一为 tmp/deploy/images/<machine>/<image-name>-<machine>.rootfs.sbom-cve-check.yocto.json, 包含以下内容:

  • 软件组件元数据,例如名称和版本

  • CVE 问题的元数据,例如描述和 NVD 链接

  • 每个软件组件可能影响当前版本的 CVE 列表

  • 每个 CVE 的状态:Patched、Unpatched 或 Ignored

备注

还会生成名为 <image-name>-<machine>.rootfs.sbom-cve-check.spdx.json 的报告。这是经过扩充的镜像 SPDX 文件,除上述信息外,还包含镜像 中软件包的大量其他元数据。关于 SPDX 的更多信息,见 Yocto Project 开发任务手册的 创建软件物料清单 一节。

"package" 列表中的每一项对应构建镜像中安装的一个软件包。各软件包的 "issue" 子列表中包含若干 CVE 条目,其状态可能如下:

  • Patched 表示已应用解决该安全问题的补丁文件。

  • Unpatched 表示尚未应用解决该问题的补丁,需要进一步调查。

  • Ignored 表示经过分析后决定忽略此问题,例如它只影响该软件组件在 其他操作系统平台上的使用。

例如,glibc 软件包的报告如下(已简化):

{
  "version": "1",
  "package": [
    {
      "name": "glibc",
      "layer": "core",
      "version": "2.43+git",
      "products": [
        {
          "product": "glibc",
          "cvesInRecord": "Yes"
        }
      ],
      "issue": [
        {
          "id": "CVE-2010-4756",
          "status": "Unpatched",
          "link": "https://nvd.nist.gov/vuln/detail/CVE-2010-4756",
          "summary": "The glob implementation in the GNU C Library (aka glibc or libc6) allows remote authenticated users to cause a denial of service (CPU and memory consumption) via crafted glob expressions that do not match any pathnames, as demonstrated by glob expressions in STAT commands to an FTP daemon, a different vulnerability than CVE-2010-2632.",
          "scorev2": "4.0",
          "scorev3": "0.0",
          "scorev4": "0.0",
          "modified": "2025-11-03T22:15:41.000",
          "vector": "NETWORK",
          "vectorString": "AV:N/AC:L/Au:S/C:N/I:N/A:P",
          "detail": "no-version-ranges",
          "description": "Check package version"
        },
        {
          "id": "CVE-2018-6551",
          "status": "Patched",
          "link": "https://nvd.nist.gov/vuln/detail/CVE-2018-6551",
          "summary": "The malloc implementation in the GNU C Library (aka glibc or libc6), from version 2.24 to 2.26 on powerpc, and only in version 2.26 on i386, did not properly handle malloc calls with arguments close to SIZE_MAX and could return a pointer to a heap region that is smaller than requested, eventually leading to heap corruption.",
          "scorev2": "7.5",
          "scorev3": "9.8",
          "scorev4": "0.0",
          "modified": "2024-11-21T04:10:53.000",
          "vector": "NETWORK",
          "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
          "detail": "version-not-in-range"
        },
        {
          "id": "CVE-2019-1010022",
          "status": "Ignored",
          "link": "https://nvd.nist.gov/vuln/detail/CVE-2019-1010022",
          "summary": "GNU Libc current is affected by: Mitigation bypass. The impact is: Attacker may bypass stack guard protection. The component is: nptl. The attack vector is: Exploit stack buffer overflow vulnerability and use this bypass vulnerability to bypass stack guard. NOTE: Upstream comments indicate \"this is being treated as a non-security bug and no real threat.",
          "scorev2": "7.5",
          "scorev3": "9.8",
          "scorev4": "0.0",
          "modified": "2024-11-21T04:17:55.000",
          "vector": "NETWORK",
          "vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
          "description": "Upstream glibc maintainers dispute there is any issue and have no plans to address it further. this is being treated as a non-security bug and no real threat."
        }
      ],
      "cpes": ["cpe:2.3:*:*:glibc:2.43:*:*:*:*:*:*:*"]
    }
  ]
}

构建时,sbom-cve-check 类还会针对 Unpatched 状态的 CVE 发出警告(当 SBOM_CVE_CHECK_SHOW_WARNINGS 设为 "1" 时):

WARNING: core-image-minimal-1.0-r0 do_sbom_cve_check: glibc-2.43+git: Found unpatched CVEs: CVE-2010-4756

4 修正 CVE 产品名称与版本映射

默认情况下,sbom-cve-check 查询 CVE 数据库时使用配方名称 BPN 作为 CVE 产品名称。如果映射产生误报,例如报告的某些 CVE 不属于 该软件组件,或者产生漏报,即本应影响该配方的 CVE 没有被检测到,问题可能 出在配方名称到 CVE 产品的映射。可以在配方中设置 CVE_PRODUCT 变量 修正映射。此变量定义软件组件在上游 NIST CVE 数据库 中的名称。

此变量支持按以下方式指定供应商与产品名称:

CVE_PRODUCT = "flex_project:flex westes:flex"

本例有两个可能的供应商名称:flex_project 和 westes,产品名称均为 flex。这样设置后,flex 配方只会映射到这些特定产品,而不会映射到 其他供应商的同名 flex 产品。

同样,如果配方版本 PV 与上游组件发行版本及 CVE 数据库使用的软件 版本不兼容,可通过 CVE_VERSION 变量修正。

如果 NVD 数据库中的 CVE 条目存在错误、信息缺失或不完整,建议直接修正 数据库中的信息,而不是长期在 OpenEmbedded-Core (OE-Core) 配方中 绕过问题。可通过 NVD 联系表单 反馈 CVE 条目的问题。

4 修复配方中的漏洞

如果 CVE 安全问题影响某个软件组件,可以通过更新版本、应用补丁来修复, 或通过 CVE_STATUS 变量标志将其标记为已修补。对于 OpenEmbedded-Core (OE-Core) 的 master 分支,优先更新到包含修复的 较新组件版本;如果新版本尚未发布,也可以应用补丁。

稳定分支应避免破坏 API(应用程序编程接口)或 ABI(应用程序二进制接口)。 提交更新时,如果组件的次要版本更新保持向后兼容,应优先采用。许多组件 提供向后兼容的稳定版本,Linux 内核就是一个典型例子。不过,如果新版本 会引入或可能引入不兼容变化,则应优先提取补丁并向后移植。

下面是使用补丁文件修复 CVE 安全问题的示例,来自 dunfell 的 ffmpeg 配方:

SRC_URI = "https://www.ffmpeg.org/releases/${BP}.tar.xz \
           file://mips64_cpu_detection.patch \
           file://CVE-2020-12284.patch \
           file://0001-libavutil-include-assembly-with-full-path-from-sourc.patch \
           file://CVE-2021-3566.patch \
           file://CVE-2021-38291.patch \
           file://CVE-2022-1475.patch \
           file://CVE-2022-3109.patch \
           file://CVE-2022-3341.patch \
           file://CVE-2022-48434.patch \
       "

该配方既包含一般修复,也包含安全相关修复。CVE 补丁文件按其修复的 CVE 命名。

准备补丁文件时,应从上游仓库获取原始补丁。除非没有其他来源,否则不要 使用其他发行版的补丁。

修改补丁,添加与 OE 相关的元数据。以下以 CVE-2022-3341.patch 为例。

原始 提交说明 如下:

From 9cf652cef49d74afe3d454f27d49eb1a1394951e Mon Sep 17 00:00:00 2001
From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Date: Wed, 23 Feb 2022 10:31:59 +0800
Subject: [PATCH] avformat/nutdec: Add check for avformat_new_stream

Check for failure of avformat_new_stream() and propagate
the error code.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavformat/nutdec.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

要使 sbom-cve-check 正常工作,必须在补丁文件提交说明的 CVE: 标签中标明 CVE 标识符,格式如下:

CVE: CVE-2022-3341

还必须添加 Upstream-Status: 标签并提供原始补丁链接,以及负责向后移植的 人员的签署行。如果修改了原始补丁,应在 Comments: 标签中说明。

添加这些信息后,OE-core 中的补丁文件头部如下:

From 9cf652cef49d74afe3d454f27d49eb1a1394951e Mon Sep 17 00:00:00 2001
From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Date: Wed, 23 Feb 2022 10:31:59 +0800
Subject: [PATCH] avformat/nutdec: Add check for avformat_new_stream

Check for failure of avformat_new_stream() and propagate
the error code.

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

CVE: CVE-2022-3341

Upstream-Status: Backport [https://github.com/FFmpeg/FFmpeg/commit/9cf652cef49d74afe3d454f27d49eb1a1394951e]

Comments: Refreshed Hunk
Signed-off-by: Narpat Mali <narpat.mali@windriver.com>
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
---
 libavformat/nutdec.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

建议在补丁文件名和补丁提交说明中包含 CVE 标识符,也可以在配方提交说明中 包含该标识符。

sbom-cve-check 随后会读取这些信息,并在生成的报告中将 CVE 状态改为 Patched。

如果分析表明,由于配置、平台、版本或其他原因,CVE 不影响该配方,可以 使用 CVE_STATUS 变量标志,指定映射到 Ignored 的适当原因, 将其标记为 Ignored。条目格式如下:

CVE_STATUS[CVE-2016-10642] = "cpe-incorrect: This is specific to the npm package that installs cmake, so isn't relevant to OpenEmbedded"

如前所述,如果 CVE 数据库中的数据有误,建议直接在数据库中修正; OpenEmbedded-Core (OE-Core) 使用的是 NVD。

如果多个 CVE 具有相同的状态和原因,可以通过 CVE_STATUS_GROUPS 变量共享这些设置。

分析 CVE 时,建议:

  • 查阅 CVE 数据库 中的最新信息。

  • 检查软件组件的上游开发者如何解决问题,例如应用了什么补丁、哪个上游 版本包含修复。

  • 检查 Debian 等其他 Linux 发行版如何分析和处理该问题。

  • 关注其他 Linux 发行版的安全公告。

  • 关注公开的 开源安全邮件列表, 获取 CVE 问题和包含修复的软件版本的讨论及预告。

4 实现细节

由于 sbom-cve-check 使用外部工具,其实现详见官方文档: https://sbom-cve-check.readthedocs.io/en/latest/index.html

4 Linux 内核漏洞

自 Linux 内核成为 CVE 编号授权机构(CNA)以来,相关 CVE 数量大幅增加。 安全团队必须处理这些 CVE,以满足法规和客户要求。自动识别问题有助于减少 工作量。

OpenEmbedded-Core (OE-Core) 提供两个脚本,用于分析和筛选影响 Linux 内核的 CVE:

  • openembedded-core/meta/recipes-kernel/linux/generate-cve-exclusions.py

  • openembedded-core/scripts/contrib/improve_kernel_cve_report.py

4.6.1 generate-cve-exclusions.py

更新内核配方时,需要手动运行辅助脚本,为内核配方更新 CVE_STATUS。 此脚本也可用于自定义内核。

首先需要从 CVE Project 获取最新的 CVE 信息。运行以下命令:

$ git clone https://github.com/CVEProject/cvelistV5 ~/cvelistV5

如果已经克隆仓库,则拉取最新数据:

$ git -C ~/cvelistV5 pull

然后,为所需内核版本生成 CVE_STATUS 信息:

$ ./generate-cve-exclusions.py ~/cvelistV5 <version> > cve-exclusion_<kernel_version>.inc

示例:

$ git clone https://github.com/CVEProject/cvelistV5 ~/cvelistV5
$ cd openembedded-core/meta/recipes-kernel/linux/
$ ./generate-cve-exclusions.py ~/cvelistV5 6.12.27 > ~/meta-custom/recipes-kernel/linux/cve-exclusion_6.12.inc

不要忘记在内核配方中添加以下内容:

include cve-exclusion_6.12.inc

随后,CVE 信息将自动加入 cve-check 或 vex 报告。

4.6.2 improve_kernel_cve_report.py

openembedded-core/scripts/contrib/improve_kernel_cve_report.py 脚本 利用内核 CVE 元数据及 SPDX_INCLUDE_COMPILED_SOURCES 变量,更新输出的 .sbom-cve-check.yocto.json 报告文件(报告详情见 在构建时检查漏洞 )。 它通过分析构建内核所用的文件,可减少 70% 到 80% 的 CVE 误报,并为所有内核 相关 CVE 提供详细说明。脚本与构建解耦,可以在 BitBake 环境之外运行。

该脚本以 vex 的输出为输入,结合 Linux 内核 CNA 提供的 CVE 信息,为报告文件补充更新后的 CVE 信息。

文件名可以作为参数指定。也可选用内核 SPDX 中的已编译文件列表, 忽略那些因相关文件未被编译而不受影响的 CVE。

为此,BitBake 利用调试信息提取构建二进制文件所用的源码。因此,需要在内核 中配置调试信息,以提取内核已编译文件。

如果使用 linux-yocto 配方,可在 configuration file 或 .bbappend 文件中添加以下内容来启用:

KERNEL_EXTRA_FEATURES:append = " features/debug/debug-kernel.scc"

也可以编辑内核配置,使其包含 DWARF4 调试信息。

更多信息见 Yocto Project Linux 内核开发手册的 修改配置 一节。

以下示例假定使用的内核配方为 linux-yocto,这些说明同样适用于 其他名称的内核配方。

内核源码信息保存在 tmp/pkgdata/<MACHINE>/debugsources/linux-yocto-debugsources.json.zstd 中。 要将这些信息加入 SPDX 文件,以筛除未用于编译内核的源文件,请在 configuration file 中添加以下内容:

SPDX_INCLUDE_COMPILED_SOURCES:pn-linux-yocto = "1"

最后,将 recipe-linux-yocto.spdx.json 或 linux-yocto-debugsources.json.zstd 保存在 build directory 之外。

SPDX 文件位于 tmp/deploy/spdx/<spdx_version>/<MACHINE>/recipes/recipe-linux-yocto.spdx.json

获得输入数据后,先从 https://git.kernel.org 克隆或获取最新 CVE 信息:

$ git clone https://git.kernel.org/pub/scm/linux/security/vulns.git ~/vulns

如果已检出仓库,则运行:

$ git -C ~/vulns pull

最后,参照以下示例之一运行脚本。前两个使用旧 cve-summary.json 的示例 最为准确。

  • 使用 --old-cve-report 作为输入的示例:

    $ python3 openembedded-core/scripts/contrib/improve_kernel_cve_report.py \
       --spdx tmp/deploy/spdx/3.0.1/qemux86_64/recipes/recipe-linux-yocto.spdx.json \
       --datadir ~/vulns \
       --old-cve-report build/tmp/deploy/images/<machine>/<image-name>-<machine>.rootfs.sbom-cve-check.yocto.json
    
  • 使用 --debug-sources 文件替代内核 SPDX 文件的示例:

    $ python3 openembedded-core/scripts/contrib/improve_kernel_cve_report.py \
       --debug-sources tmp/pkgdata/qemux86_64/debugsources/linux-yocto-debugsources.json.zstd \
       --datadir ~/vulns \
       --old-cve-report build/tmp/deploy/images/<machine>/<image-name>-<machine>.rootfs.sbom-cve-check.yocto.json
    
  • 使用 --kernel-version 的示例:

    $ python3 openembedded-core/scripts/contrib/improve_kernel_cve_report.py \
       --spdx tmp/deploy/spdx/3.0.1/qemux86_64/recipes/recipe-linux-yocto.spdx.json \
       --kernel-version 6.12.27 \
       --datadir ~/vulns
    

以下输出示例中,由于 CVE 相关源文件未被编译,该 CVE 的状态改为 "Ignored":

{
   "id": "CVE-2025-38384",
   "status": "Ignored",
   "detail": "not-applicable-config",
   "summary": "In the Linux kernel, the following vulnerability has been resolved (...)",
   "description": "Source code not compiled by config. {'drivers/mtd/nand/spi/core.c'}"
}

版本不在影响范围内的 CVE 输出示例:

{
   "id": "CVE-2025-40017",
   "status": "Patched",
   "detail": "fixed-version",
   "summary": "In the Linux kernel, the following vulnerability has been resolved (...)",
   "description": "only affects 6.15 onwards"
}

存在漏洞的 CVE 输出示例:

{
   "id": "CVE-2024-58093",
   "status": "Unpatched",
   "detail": "version-in-range",
   "summary": "In the Linux kernel, the following vulnerability has been resolved (...)",
   "description": "Needs backporting (fixed from 6.15)"
}

被 Linux CNA 拒绝的 CVE 输出示例:

{
   "id": "CVE-2025-38380",
   "status": "Ignored",
   "detail": "rejected",
   "summary": "In the Linux kernel, the following vulnerability has been resolved (...)",
   "description": "Rejected by CNA"
}