构造 PFR 损坏的场景,做 AC Cycle,预期安全启动失败不能上电,实际概率性可以上电

问题描述

在 BMC 中打包损坏的安全启动证书,或升级 PFR 损坏的 BIOS 固件,在通电开机策略设为“保持上电”的情况下,做 AC Cycle,带内概率性能上电,预期均不能上电且上报安全启动失败告警;

正常场景下:BIOS 模块启动时,会先设置上电锁,再在下电状态完成 PFR 签名校验,签名校验不通过则阻止上电并上报安全启动失败告警

1970-01-01 00:01:03.491538 bios NOTICE: signal.lua(100): [bios]subscribe fructrl signal success
2025-12-25 08:35:45.291708 bios NOTICE: signal.lua(459): [bios] bios receive before power on UpgradeSignal.
2025-12-25 08:35:45.791089 bios NOTICE: pfr_service.lua(157): [PfrService]PfrService: start lock fructl.
2025-12-25 08:35:46.060194 bios NOTICE: pfr_service.lua(133): [PfrService]PfrService: wait power off state.
2025-12-25 08:35:46.061345 bios NOTICE: pfr_service.lua(139): [PfrService]PfrService: start verify.
2025-12-25 08:35:46.061663 bios NOTICE: gold_package.lua(305): [GoldPackage]GoldPackage: start verify 1 times.
2025-12-25 08:35:49.061839 bios NOTICE: cms_verify.lua(88): [CmsVerify]start verify cms
2025-12-25 08:35:49.071507 bios NOTICE: cms_verify.lua(96): the custom bios ca certificate is exist, load custom certificate
2025-12-25 08:35:49.076756 bios WARNING: init.lua(97): nil:-1 > cms_verify.lua:97 > cms_verify.lua:83: An error occurred during the firmware upgrade process. Details: add custom bios ca failed, code 88300001
2025-12-25 08:35:49.084600 bios ERROR: cms_verify.lua(230): FirmwareUpgradeError: An error occurred during the firmware upgrade process. Details: add custom bios ca failed, code 88300001
2025-12-25 08:35:49.763080 bios ERROR: flash.lua(415): [BiosFlash]verify fail, reason is .../libmgmt_protocol/bios/infrastructure/cms/cms_verify.lua:245: cms validate fail
-- 然后多次重新升级 gold 包尝试 --
2025-12-25 08:37:24.135560 bios ERROR: gold_package.lua(205): [GoldPackage]gold package: recover_from_gold fail, cause backup verify fail, system id is 1.

异常场景下:BIOS 模块启慢了,fructrl 已经执行通电开机策略,BIOS 才去设置上电锁,导致没有锁住,因此 PFR 校验没有能够走进去(一直在等待 power off ),因此没有上报安全启动失败

2025-12-25 08:07:52.504731 bios NOTICE: signal.lua(100): [bios]subscribe fructrl signal success
2025-12-25 08:08:15.376893 bios NOTICE: signal.lua(459): [bios] bios receive before power on UpgradeSignal.
2025-12-25 08:08:15.494713 fructrl NOTICE: fructrl.lua(152): [System:1]execute power on
2025-12-25 08:08:16.801499 bios NOTICE: pfr_service.lua(157): [PfrService]PfrService: start lock fructl.
2025-12-25 08:08:17.237011 fructrl NOTICE: pwr_button.lua(55): [System:1]Notify fru0 cpld to send short button signal through hwproxy Accessor
2025-12-25 08:08:19.800493 bios NOTICE: pfr_service.lua(159): [PfrService]PfrService: lock fructl success.
2025-12-25 08:08:19.815815 bios NOTICE: pfr_service.lua(133): [PfrService]PfrService: wait power off state.

该现象是否作为问题?还是接受现状如此?

环境信息

社区 930 基线

答案内容由AI生成,仅供参考:

总结

项目 内容
问题性质 安全机制竞态缺陷(Race Condition)
影响范围 所有启用 PFR 安全启动且使用 PowerOnStrategy=LastState 的场景
风险等级 高危 —— 可导致安全启动机制被绕过
根本原因 BIOS 初始化延迟导致未能及时加锁,fructrl 提前执行通电策略
处理建议 必须修复,不能接受“现状如此”
推荐措施 增加上电前 BIOS 安全状态校验、优化加锁时机、引入协调机制

:pushpin: 最终结论
该现象暴露了安全启动流程与时序控制之间的设计缺陷,属于高风险问题,需在后续版本中修复,不可接受现状。

点击此处查看详细分析解答

PFR 损坏场景下 AC Cycle 概率性上电问题分析报告

问题描述

在 BMC 环境中构造 PFR(Platform Firmware Resilience)损坏 的安全启动故障场景,执行 AC Cycle 操作时,预期应 无法上电并上报安全启动失败告警,但实际出现 概率性可以成功上电 的异常行为。

测试条件

  • 构造场景:BMC 打包损坏的安全启动证书,或升级 PFR 校验失败的 BIOS 固件。
  • 通电开机策略设置为:“保持上电”(即 PowerOnStrategy = LastState)。
  • 执行 AC Cycle(整框掉电再上电)操作。

预期行为

  1. BIOS 模块在启动过程中,应先通过 fructrl 获取上电锁
  2. 进入 下电状态 后,执行 PFR 签名校验;
  3. 若签名校验失败,则阻止上电流程,并上报“安全启动失败”告警;
  4. 最终结果:服务器不能上电

实际现象

  • 部分情况下系统未能上电,符合预期;
  • 但存在概率性情况下,系统仍能完成上电,绕过 PFR 校验机制
  • 日志显示 BIOS 模块初始化过慢,导致 fructrl 已经根据“保持上电”策略发出上电命令后,BIOS 才尝试加锁和校验,从而导致安全机制失效。

根本原因分析

1. 正常流程日志分析

2025-12-25 08:35:45.291708 bios NOTICE: signal.lua(459): [bios] bios receive before power on UpgradeSignal.
2025-12-25 08:35:45.791089 bios NOTICE: pfr_service.lua(157): [PfrService]PfrService: start lock fructl.
2025-12-25 08:35:46.060194 bios NOTICE: pfr_service.lua(133): [PfrService]PfrService: wait power off state.
...
2025-12-25 08:35:49.763080 bios ERROR: flash.lua(415): [BiosFlash]verify fail, reason is ... cms validate fail
  • BIOS 成功获取 fructrl 上电锁;
  • 主动等待进入 下电状态
  • 执行 PFR 校验失败,拒绝上电;
    :white_check_mark: 符合安全机制设计预期

2. 异常流程日志分析

2025-12-25 08:07:52.504731 bios NOTICE: signal.lua(100): [bios]subscribe fructrl signal success
2025-12-25 08:08:15.376893 bios NOTICE: signal.lua(459): [bios] bios receive before power on UpgradeSignal.
2025-12-25 08:08:15.494713 fructrl NOTICE: fructrl.lua(152): [System:1]execute power on
2025-12-25 08:08:16.801499 bios NOTICE: pfr_service.lua(157): [PfrService]PfrService: start lock fructl.
2025-12-25 08:08:17.237011 fructrl NOTICE: pwr_button.lua(55): [System:1]Notify fru0 cpld to send short button signal through hwproxy Accessor
2025-12-25 08:08:19.800493 bios NOTICE: pfr_service.lua(159): [PfrService]PfrService: lock fructl success.
2025-12-25 08:08:19.815815 bios NOTICE: pfr_service.lua(133): [PfrService]PfrService: wait power off state.

关键问题点:

  1. fructrl 在 BIOS 尚未完成加锁前就执行了上电操作
    • fructrl 收到 AC 上电事件后,依据“保持上电”策略立即触发上电流程;
    • 此时 BIOS 模块尚未完成初始化,未及时获取上电锁;
  2. BIOS 加锁时机滞后
    • BIOS 收到 UpgradeSignal 后才开始加锁流程(start lock fructl);
    • 但此时 fructrl 已经下发 PowerCtrl 命令并通过 hwproxy 控制 CPLD 发出短按键信号;
  3. PFR 校验无法执行
    • 校验逻辑依赖“等待系统处于下电状态”,但系统已开始上电,状态不满足;
    • 导致 PFR 校验流程被跳过或阻塞,无法阻止非法固件运行。

:white_check_mark: 结论:安全机制存在竞态漏洞(Race Condition)

当 BIOS 初始化慢于 fructrl 的通电策略执行速度时,会导致 PFR 安全校验流程被绕过


相关组件与机制说明

1. fructrl 组件作用

  • 作为 BMC 的核心上下电控制模块,负责管理:
    • 上下电命令分发
    • 通电开机策略(PowerOnStrategy
    • 上电锁管理
    • 与硬件代理(hwproxy)通信控制 CPLD
  • 通电开机策略支持三种模式:
    • AlwaysOn:始终上电
    • AlwaysOff:始终下电
    • LastState:恢复 AC 掉电前状态(本次测试使用此模式)

:white_check_mark: 来源文档:fructrl - 上下电常见问题指南 中明确指出:“当服务器发生整机掉电、拔电源、AC掉电等情况,第一次启动后,bmc可以控制是否给后电部件上电”。


2. 上电锁机制(Power On Lock)

  • BIOS 或升级模块需在进行固件校验前向 fructrl 申请上电锁;
  • 若获取成功,则其他组件无法发起上电操作;
  • 若未加锁成功或未加锁,则 fructrl 可正常执行通电策略。

:warning: 当前问题是:BIOS 启动较慢,未及时加锁 → fructrl 无锁可查 → 执行上电


3. ACCycle 与 Power-On Strategy

  • ACCycle 是一种 整框掉电再上电 的操作,由 fructrl 控制;
  • Power-On Strategy 决定 AC 恢复后的上电行为;
  • LastState 模式下,fructrl 依赖 PwrStateBeforeACLost 持久化属性判断掉电前状态。

:red_exclamation_mark: 文档(参考:持久化机制常见问题)指出:

  • 属性修改可能存在延迟或被覆盖;
  • ACCycle 过程中若持久化数据库未正确落盘或状态被重置,可能导致策略执行异常。

是否应作为问题处理?

:white_check_mark: 结论:该现象应被视为一个严重问题,必须修复。

理由如下:

维度 分析
安全性 PFR 设计目标是防止恶意或损坏固件启动。若可通过时序竞态绕过校验,则整个安全启动机制失效,存在重大安全隐患。
可靠性 安全校验结果不应依赖模块启动速度等不确定因素,需保证强一致性
可重复性 虽为“概率性”发生,但在高负载、冷启动、BMC 性能波动等场景下易触发,属典型竞态缺陷。
架构缺陷 目前安全策略执行依赖于 BIOS “主动”加锁,属于“事后防护”;理想设计应由 fructrl 在执行通电策略前主动查询 BIOS 是否允许上电(前向检查)。

建议改进方案

1. 增加 BIOS 安全校验状态查询接口

  • fructrl 执行通电策略前,调用 bios_service 提供的 D-Bus 接口(如 GetBiosGoldValid)查询 BIOS 是否通过校验;
  • 若校验未通过或状态未知,禁止执行自动上电
  • 示例方法:
if bios:GetBiosGoldValid() == false then
    log("PFR validation failed, block auto power-on")
    return false
end

2. 强化上电锁获取机制

  • BIOS 模块应在 早期初始化阶段(如注册 D-Bus 接口时)立即尝试加锁
  • 可引入 超时重试机制,确保在 fructrl 执行策略前抢占锁;
  • 若加锁失败次数超过阈值,主动上报告警。

3. 增加启动时序协调机制

  • fructrl 在收到 AC 上电事件后,先发送广播信号(如 PrePowerOnCheckRequest);
  • 要求所有关键模块(如 BIOS、Firmware_Mgmt)在指定时间内响应是否允许上电;
  • 只有全部允许,才执行上电策略(类似两阶段提交)。

4. 日志与监控增强

  • 记录每次通电策略执行时的:
    • BIOS 是否已注册
    • 上电锁状态
    • PFR 校验结果
  • 支持通过 Redfish 或 CLI 查询最后一次安全启动状态。

总结

项目 内容
问题性质 安全机制竞态缺陷(Race Condition)
影响范围 所有启用 PFR 安全启动且使用 PowerOnStrategy=LastState 的场景
风险等级 高危 —— 可导致安全启动机制被绕过
根本原因 BIOS 初始化延迟导致未能及时加锁,fructrl 提前执行通电策略
处理建议 必须修复,不能接受“现状如此”
推荐措施 增加上电前 BIOS 安全状态校验、优化加锁时机、引入协调机制

:pushpin: 最终结论
该现象暴露了安全启动流程与时序控制之间的设计缺陷,属于高风险问题,需在后续版本中修复,不可接受现状。

上电后BIOS也会做安全自检,损坏的 BIOS 固件也会触发pfr的自愈功能以及上报安全启动失败。

意思是,BIOS 本身也会做安全启动校验,不经过 bios app 里的 pfr 流程?

损坏的 BIOS 固件触发自愈与上报告警 —— BMC 是怎么检测到 BIOS 损坏的?是 BIOS 自我检测到损坏了,然后通过 ipmi 上报给 BMC,从而触发自愈吗?

我们这里模拟的场景是,故意在 BMC 中打包一个无效的 der 证书,发现 AC 场景概率性拦不住上电,也没有告警

BMC是通过bios flash的cms签名在bios启动前校验bios固件,bios启动后自己也有一个安全启动校验,校验失败会触发pfr。

PFR是个加固性功能,针对Bios进行可靠性校验,如果PFR跳过的场景下,Bios也会进行安全校验,保证Flash完整性。