#18527·esp-idf

spi_bus_lock: 在 bg_exit_core 中对 lock->acquiring_dev 的 TOCTOU 竞争导致空指针引用崩溃 (IDFGH-17600)

作者: tinkerbug创建于 2026年4月28日更新于 2026年9月17日
标签Status: Reviewing

环境

  • ESP-IDF: v5.3.2(在v.5.3中也存在种族和主人,经核实)
  • 目标:ESP32-S3
  • 崩溃模式: Guru 冥想, 禁入
  • 可复制性:概率 -- -- 每几分钟一次重大SPI活动

错误

在“组件/esp hw support/spi bus lock.c:bg exit core()”中,“可挥发性”指针`lock->access dev'被多次读取,而不跳动:

页:1 如果( 锁定- > 获取 dev) { // L547 如果( 状态 & DEV BG MASK( 锁- > 获取 dev) ) { // L548 — 重读 . . . . . . . . 否则 恢复 dev in isr(lock->access dev, do pent); ///L554 — 重读 ret = 真实; {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


`Access-dev'被宣布为`活性',因此每个读取都读入内存——但在多核心的ESP32-S3上,指针可以在L547和L548(或L554)之间被另一个同时完成的SPI ISR清除. 发生这种情况时,"DEV BG MASK(NULL)"会去引用"NULL-"mask" (offset 8)和"resume dev in isr(NULL,.)"会去引用"NULL-" semphr" (offset 0).

已观察到崩溃签名

古鲁冥想错误:核心0恐慌" (LoadProhibited). PC: bg exit core (spi bus lock.c:548) EXCVADDR: 0x00000008 (英语). spi bus lock bg exit (spi bus lock.c:778) (英语). spi intr (spi master.c: 1015) (英语). xt lowint1 (英语). esp pm impl waiti (pm impl.c: 1047) (英语). esp v 应用程序IdleHook 棱镜任务


在L554(EXCVADDR=0x00000)单独运行时观察的同名签名.

建议改正

在条件的顶端缓存可变指针一次:

页:1
spi bus lock dev t *dev=(spi bus lock dev t *) lock->access dev; (中文(简体) ).
如果(dev){则
如果( 状态 & DEV  BG  MASK( dev)) {
bUS LOCK DEBUG EXECUTE CHECK(时钟->acq dev bg active); 2.
ret = 虚假;
否则
恢复 dev in isr(dev, do fut);
ret = 真实;
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?

复制背景

LoRa SX126x over SPI2(RadioLib + EspHal,2 Hz TX/RX,频繁设置Frequentency呼叫),NimBLE GATT服务器,SDMMC,PM与外勤部启用. CPU在wati时,崩溃总是在 SPI ISR 补全路径内. 没有最小的再生器——失败率每几分钟一次混合SPI/BLE活性. 很高兴收集更多的诊断.

内容来源: espressif/esp-idf