PCI DEXT crash panics the host: IOPCIBridge::childClientCrashRecoveryGated dereferences a NULL Expansion ROM range (FB25117710)

When a PCI DriverKit extension terminates abnormally while it has its IOPCIDevice open, IOPCIFamily's child crash recovery can panic the whole host. This happens on devices whose nub publishes an Expansion ROM entry in IODeviceMemory, which is typical of GPUs and common on other PCIe cards.

What happens

IOPCIBridge::childClientCrashRecoveryGated walks the nub's IODeviceMemory array to restore BARs. For each descriptor it computes barIndex from the register number. For the ROM (config offset 0x30) that index is 8, kIOPCIRangeExpansionROM. The function then reads child->reserved->configEntry->ranges[barIndex]->start without checking for NULL. In our case ranges[8] is NULL, and the kernel takes a data abort at FAR 0.

In IOPCIFamily-726.0.5 (IOPCIBridge.cpp, around lines 7055–7085), the barIndex == kIOPCIRangeExpansionROM check comes after the dereference:

uint8_t barIndex = (addressSpace.s.registerNum - kIOPCIConfigBaseAddress0) >> 2;   // 0x30 -> 8
IOPCIRange *range = child->reserved->configEntry->ranges[barIndex];                // NULL here
uint32_t bar = child->configRead32(addressSpace.s.registerNum) & ~0xF;
if (bar != (range->start & 0xFFFFFFFF))                                            // faults
...
if (barIndex == kIOPCIRangeExpansionROM || !(kIOPCIRangeFlagBar64 & range->flags)) // too late

Environment

  • Mac Studio (M4 Max), macOS 26.7.1 (25G241), IOPCIFamily 2.9
  • PCIe GPU in a Thunderbolt 5 eGPU enclosure, third-party PCI DEXT (development-signed)
  • The nub's IODeviceMemory has four entries, the last a 128 KB Expansion ROM

Panic signature

Two panics, both with the same signature. The panicked task is the DEXT, and IOPCIFamily is the only kext in the backtrace.

Kernel data abort, ESR 0x96000006, FAR 0x0, pc = IOPCIFamily + 0x19b5c
x2 = 0x30 (ROM config offset), x23 = 0x8 (barIndex), x27 = 0x0 (range)
faulting instruction: ldr w2, [x27]

Questions

  1. Has anyone else seen host panics in crash recovery after a PCI DEXT died? Other projects document "don't kill the driver process, or crash recovery may panic the machine," and this may be the same root cause.
  2. Is there a supported way for a DEXT to avoid this? For example, can a driver keep the ROM descriptor out of the recovery path, or is avoiding DEXT crashes the only mitigation until a fix ships?

We filed this as FB25117710. If you hit the same panic, please reference that number in your own Feedback so the reports can be linked.

PCI DEXT crash panics the host: IOPCIBridge::childClientCrashRecoveryGated dereferences a NULL Expansion ROM range (FB25117710)
 
 
Q