]> xenbits.xensource.com Git - people/tklengyel/xen.git/commitdiff
VT-d: correct ordering of operations in cleanup_domid_map()
authorJan Beulich <jbeulich@suse.com>
Tue, 5 Apr 2022 12:12:27 +0000 (14:12 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 5 Apr 2022 12:12:27 +0000 (14:12 +0200)
The function may be called without any locks held (leaving aside the
domctl one, which we surely don't want to depend on here), so needs to
play safe wrt other accesses to domid_map[] and domid_bitmap[]. This is
to avoid context_set_domain_id()'s writing of domid_map[] to be reset to
zero right away in the case of it racing the freeing of a DID.

For the interaction with context_set_domain_id() and did_to_domain_id()
see the code comment.

{check_,}cleanup_domid_map() are called with pcidevs_lock held or during
domain cleanup only (and pcidevs_lock is also held around
context_set_domain_id()), i.e. racing calls with the same (dom, iommu)
tuple cannot occur.

domain_iommu_domid(), besides its use by cleanup_domid_map(), has its
result used only to control flushing, and hence a stale result would
only lead to a stray extra flush.

This is CVE-2022-26357 / XSA-399.

Fixes: b9c20c78789f ("VT-d: per-iommu domain-id")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
xen/drivers/passthrough/vtd/iommu.c

index 82b485e7d40d012e3af8fa6b844da1fe62e73e4d..c466eef56ec8a68d7cab810783342f9893903e11 100644 (file)
@@ -175,8 +175,14 @@ static void cleanup_domid_map(struct domain *domain, struct vtd_iommu *iommu)
 
     if ( iommu_domid >= 0 )
     {
+        /*
+         * Update domid_map[] /before/ domid_bitmap[] to avoid a race with
+         * context_set_domain_id(), setting the slot to DOMID_INVALID for
+         * did_to_domain_id() to return a suitable value while the bit is
+         * still set.
+         */
+        iommu->domid_map[iommu_domid] = DOMID_INVALID;
         clear_bit(iommu_domid, iommu->domid_bitmap);
-        iommu->domid_map[iommu_domid] = 0;
     }
 }