[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging-4.16] VT-d: correct ordering of operations in cleanup_domid_map()



commit 0e754e07b00f3ad644a3c05f85702bce8b4c0d5c
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Apr 5 14:43:57 2022 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Apr 5 14:43:57 2022 +0200

    VT-d: correct ordering of operations in cleanup_domid_map()
    
    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@xxxxxxxx>
    Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    master commit: d9eca7bb6c6636eb87bb17b08ba7de270f47ecd0
    master date: 2022-04-05 14:12:27 +0200
---
 xen/drivers/passthrough/vtd/iommu.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/passthrough/vtd/iommu.c 
b/xen/drivers/passthrough/vtd/iommu.c
index ead12db6a4..a1645d3372 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -152,8 +152,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
+         * ->domid_map[] reads to produce 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;
     }
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.16



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.