]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iommu/vt-d: Fix RB-tree corruption in probe error path
authorPranjal Shrivastava <praan@google.com>
Thu, 4 Jun 2026 06:03:10 +0000 (14:03 +0800)
committerJoerg Roedel <joerg.roedel@amd.com>
Thu, 4 Jun 2026 07:21:50 +0000 (09:21 +0200)
The info->node RB-tree member is zero-initialized via kzalloc. If
a device does not support ATS, the device_rbtree_insert() call is
skipped. If a subsequent probe step fails, the error path jumps to
device_rbtree_remove(), which misinterprets the zeroed node as
a tree root and corrupts the device RB-tree.

Fix this by explicitly initializing the RB-node as empty using
RB_CLEAR_NODE() during initialization and guarding the removal with
RB_EMPTY_NODE().

Fixes: 4f1492efb495 ("iommu/vt-d: Revert ATS timing change to fix boot failure")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260525205628.CD4431F000E9@smtp.kernel.org/
Suggested-by: Baolu Lu <baolu.lu@linux.intel.com>
Signed-off-by: Pranjal Shrivastava <praan@google.com>
Link: https://lore.kernel.org/r/20260531170254.60493-2-praan@google.com
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
drivers/iommu/intel/iommu.c

index c3d18cd77d2f1ac8d4c14bae24b411565b5af06a..2702e9aa22413b51350871140ab415bcd8ee8411 100644 (file)
@@ -157,7 +157,10 @@ static void device_rbtree_remove(struct device_domain_info *info)
        unsigned long flags;
 
        spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
-       rb_erase(&info->node, &iommu->device_rbtree);
+       if (!RB_EMPTY_NODE(&info->node)) {
+               rb_erase(&info->node, &iommu->device_rbtree);
+               RB_CLEAR_NODE(&info->node);
+       }
        spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
 }
 
@@ -3254,6 +3257,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 
        info->dev = dev;
        info->iommu = iommu;
+       RB_CLEAR_NODE(&info->node);
        if (dev_is_pci(dev)) {
                if (ecap_dev_iotlb_support(iommu->ecap) &&
                    pci_ats_supported(pdev) &&