Re: iommu: PCI reset helpers' lock-free entry reads race the iommu_device_unregister() traversal -> group use-after-free or NULL deref inside the reset path

From: Nicolin Chen

Date: Thu Oct 22 2026 - 12:32:43 EST


On Thu, Oct 22, 2026 at 10:05:04PM +0800, 徐晗翔 wrote:
> The PCI reset IOMMU helpers read pdev->dev.iommu_group and
> dev->iommu before taking any lock, and the whole PCI reset body
> (FLR alone sleeps 100ms) runs between their prepare and done halves
> -- meanwhile the iommu_device_unregister() traversal can tear the
> device's group away entirely, so the helper's post-reset half locks
> an already-freed group (use-after-free spinlock) or walks
> &NULL->devices (NULL deref oops).

Unplugging an IOMMU instance while a device behind it is still
alive? That doesn't sound like a reasonable use case to me.

> The kernel's own comment above
> these helpers states the contract -- "callers must ensure there will
> be no racy iommu_release_device() call, which otherwise would UAF the
> dev->iommu_group pointer" (drivers/iommu/iommu.c:4027-4032) -- but
> the unregister traversal is precisely an iommu_release_device()
> source that no reset-path caller can ensure against: it takes no
> device lock, so the device_lock the reset path holds (which does
> serialize device_del) protects nothing here.

The contract in the kdocs literally means iommu_release_device()
must not be called during a reset. So, iommu_device_unregister()
invoking iommu_release_device() violates that contract.

Nicolin