Skip to content

Commit 53d0584

Browse files
committed
iommufd: WARN if an object is aborted with an elevated refcount
If something holds a refcount then it is at risk of UAFing. For abort paths we expect the caller to never share the object with a parallel thread and to clean up any refcounts it obtained on its own. Add the missing dec inside iommufd_hwpt_paging_alloc() during error unwind by making iommufd_hw_pagetable_attach/detach() proper pairs. Link: https://patch.msgid.link/r/[email protected] Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Tested-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 4e034bf commit 53d0584

File tree

3 files changed

+7
-3
lines changed

3 files changed

+7
-3
lines changed

drivers/iommu/iommufd/device.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
711711
iopt_remove_reserved_iova(&hwpt_paging->ioas->iopt, idev->dev);
712712
mutex_unlock(&igroup->lock);
713713

714+
iommufd_hw_pagetable_put(idev->ictx, hwpt);
715+
714716
/* Caller must destroy hwpt */
715717
return hwpt;
716718
}
@@ -1057,7 +1059,6 @@ void iommufd_device_detach(struct iommufd_device *idev, ioasid_t pasid)
10571059
hwpt = iommufd_hw_pagetable_detach(idev, pasid);
10581060
if (!hwpt)
10591061
return;
1060-
iommufd_hw_pagetable_put(idev->ictx, hwpt);
10611062
refcount_dec(&idev->obj.users);
10621063
}
10631064
EXPORT_SYMBOL_NS_GPL(iommufd_device_detach, "IOMMUFD");

drivers/iommu/iommufd/iommufd_private.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,8 @@ static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
454454
if (hwpt->obj.type == IOMMUFD_OBJ_HWPT_PAGING) {
455455
struct iommufd_hwpt_paging *hwpt_paging = to_hwpt_paging(hwpt);
456456

457-
lockdep_assert_not_held(&hwpt_paging->ioas->mutex);
458-
459457
if (hwpt_paging->auto_domain) {
458+
lockdep_assert_not_held(&hwpt_paging->ioas->mutex);
460459
iommufd_object_put_and_try_destroy(ictx, &hwpt->obj);
461460
return;
462461
}

drivers/iommu/iommufd/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj)
122122
old = xas_store(&xas, NULL);
123123
xa_unlock(&ictx->objects);
124124
WARN_ON(old != XA_ZERO_ENTRY);
125+
126+
if (WARN_ON(!refcount_dec_and_test(&obj->users)))
127+
return;
128+
125129
kfree(obj);
126130
}
127131

0 commit comments

Comments
 (0)