2. 固件组件构成与分类

固件不是一块“铁板”,而是由多种来源、多种形态、多种授权方式的组件拼装而成的软件集合。要治理固件供应链,第一步不是扫描,而是建立一套能落到每个文件、每个符号、每个版本上的分类框架。分类的目的不是学术归档,而是决定“先查谁、先修谁、谁能替换、谁只能缓解”。

从工程视角看,固件中的组件可以按“交付形态”和“来源与可控性”两个维度交叉划分。交付形态决定我们能否直接读取、替换或重链接;来源与可控性决定漏洞披露、补丁节奏和合规义务。下面这张图给出本节的核心分类骨架与治理优先级映射。

固件组件分类与治理优先级映射 形态维度 × 来源维度 → 可治理动作与优先级 交付形态(能否直接处理) 二进制组件 .bin / .elf / .hex / .a 无源码,靠符号与字符串识别 开源组件 有源码与许可证,可重编译 SBOM 可追溯到版本与 commit 第三方库 厂商以库/包形式交付 常带封装与版本号,接口固定 驱动与微码 .ko / .sys / .fw / microcode 与硬件强绑定,常为二进制 来源与可控性 自研 / 内部构建 可控,可改代码、可重签 上游开源社区 可跟进 CVE,但需适配与验证 商业供应商 依赖合同、NDA、补丁窗口 芯片原厂 / 固件黑盒 不可改,只能缓解或隔离 遗留 / 无维护 无补丁来源,风险最高 治理优先级与动作 P0 立即处置 黑盒微码/驱动 + 已知高危 CVE 动作:隔离、禁用、向原厂索要补丁 P1 计划修复 第三方库/商业组件,有补丁但需验证 动作:排期升级、回归测试、重签 P2 持续跟踪 开源组件,版本可追溯、可重编译 动作:纳入 SBOM、定期比对 CVE P3 基线管理 自研/内部构建,可控但需防退化 动作:代码审计、构建可复现 优先级 = 可利用性 × 暴露面 × 可修复性

一、二进制组件:先识别,再定位

二进制组件是固件中最难“看穿”的部分,包括可执行文件、静态库、动态库以及被剥离符号的裸二进制。治理的第一步是识别:用 file 判断架构与类型,用 strings 提取版本字符串、编译器和第三方库特征,用 readelf -d 或 objdump -T 查看动态依赖与导出符号。例如,一个 libupnp.so.1.6.19 的版本字符串可以直接映射到已知 CVE 列表;而一个被 strip 过的 bluetoothd 则需要通过字符串中的 BlueZ 版本号反推。

二进制组件的治理优先级通常较高,因为它既可能包含开源代码的旧版本,又无法直接替换源码。实际做法是:先建立“二进制—来源—版本”映射表,再对无法映射的组件标记为“未知来源”,按 P0 或 P1 处理。

二、开源组件:SBOM 是治理底座

开源组件是固件中数量最多、版本最杂的一类。治理的核心是 SBOM(软件物料清单)。一个可用的 SBOM 至少应包含组件名、版本、许可证、上游 URL、引入方式(静态链接/动态链接/源码复制)和文件路径。以 Yocto 构建为例,buildhistory 和 create-spdx 可以自动生成 SPDX 文档;对于手工集成的开源库,则需要在 recipes 中显式声明 SRC_URI 与 SRCREV。

开源组件的治理优先级取决于“是否可重编译”和“是否仍在维护”。仍在维护且可重编译的组件,纳入 P2 持续跟踪;已停止维护但被静态链接进关键路径的组件,应提升到 P1,并评估替换或隔离方案。

三、第三方库:合同与接口双约束

第三方库通常以二进制包或源码包形式由供应商交付,带有明确的版本号和接口约定。治理难点在于:供应商可能只提供补丁而不提供源码,或者补丁窗口与产品发布节奏不匹配。此时需要建立“供应商—组件—补丁状态”台账,记录每个库的当前版本、已知漏洞、供应商响应时间和合同约定的支持周期。

一个实用的判断规则是:如果第三方库的漏洞可利用性高且暴露在外部接口上,即使供应商尚未发布补丁,也应先通过输入校验、访问控制或功能降级进行缓解,并同步启动供应商升级流程。

四、驱动与微码:与硬件强绑定,治理靠隔离

驱动和微码是固件中最特殊的一类。驱动通常以 .ko(Linux)或 .sys(Windows)形式存在,微码则是 CPU、GPU、网卡等芯片内部运行的固件。它们的共同特点是:与硬件强绑定、通常为二进制、修改风险极高。治理策略不是“替换”,而是“隔离与缓解”:关闭不必要的驱动、限制设备访问权限、在虚拟化环境中隔离高风险设备、及时跟进芯片原厂的微码更新。

例如,某网卡微码存在 DMA 越界风险,若无法立即更新微码,可先在驱动层启用 IOMMU 并限制该设备的 DMA 范围,将风险从 P0 降到 P1,同时向原厂索要修复版本。

五、分类落地:一张可执行的判定表

把上述分类落到日常治理中,可以用下面这张判定表快速决定优先级。表中“可利用性”按 CVSS 可利用性指标粗分,“暴露面”按组件是否处理外部输入判断,“可修复性”按是否有可用补丁或缓解手段判断。

组件类型 典型形态 可利用性 暴露面 可修复性 建议优先级
二进制组件(未知来源) .bin / strip 后的 .so 高 高 低 P0
微码 / 黑盒驱动 .fw / .ko(闭源) 中高 中 低(依赖原厂) P0/P1
第三方库(有补丁) .a / .so / 源码包 中 中高 中 P1
开源组件(可重编译) 源码 + 构建脚本 中 中 高 P2
自研组件 内部仓库 + 构建流水线 低中 视功能而定 高 P3
实操提示:分类不是一次性的。每次固件构建、每次供应商交付、每次 CVE 披露,都应触发一次“组件—版本—优先级”的重新评估。建议把分类结果直接写入 SBOM 的扩展字段,例如 governance:priority 和 governance:action,让治理动作可查询、可审计。

总结来说,固件组件分类的关键不是把组件放进哪个盒子,而是回答三个问题:它是什么形态、它来自哪里、我们能不能改。形态决定识别手段,来源决定补丁路径,可控性决定治理动作。把这三个问题回答清楚,优先级自然浮现,后续的漏洞管理、SBOM 维护和供应商协同才有稳定的起点。