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

[Xen-changelog] [xen master] IOMMU: clear "don't flush" override on error paths



commit 552b7fcb9a70f1d4dd0e0cd5fb4d3d9da410104a
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Dec 10 16:10:37 2013 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Dec 10 16:10:37 2013 +0100

    IOMMU: clear "don't flush" override on error paths
    
    Both xenmem_add_to_physmap() and iommu_populate_page_table() each have
    an error path that fails to clear that flag, thus suppressing further
    flushes on the respective pCPU.
    
    In iommu_populate_page_table() also slightly re-arrange code to avoid
    the false impression of the flag in question being guarded by a
    domain's page_alloc_lock.
    
    This is CVE-2013-6400 / XSA-80.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 xen/arch/x86/mm.c               |    2 +-
 xen/drivers/passthrough/iommu.c |   24 +++++++++++++-----------
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 6c26026..dd42bde 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4648,7 +4648,7 @@ static int xenmem_add_to_physmap(struct domain *d,
         {
             rc = xenmem_add_to_physmap_once(d, xatp);
             if ( rc < 0 )
-                return rc;
+                break;
 
             xatp->idx++;
             xatp->gpfn++;
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index bdc7261..d3dd683 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -322,11 +322,11 @@ static int iommu_populate_page_table(struct domain *d)
 {
     struct hvm_iommu *hd = domain_hvm_iommu(d);
     struct page_info *page;
-    int rc;
+    int rc = 0;
 
+    this_cpu(iommu_dont_flush_iotlb) = 1;
     spin_lock(&d->page_alloc_lock);
 
-    this_cpu(iommu_dont_flush_iotlb) = 1;
     page_list_for_each ( page, &d->page_list )
     {
         if ( is_hvm_domain(d) ||
@@ -336,18 +336,20 @@ static int iommu_populate_page_table(struct domain *d)
             rc = hd->platform_ops->map_page(
                 d, mfn_to_gmfn(d, page_to_mfn(page)), page_to_mfn(page),
                 IOMMUF_readable|IOMMUF_writable);
-            if (rc)
-            {
-                spin_unlock(&d->page_alloc_lock);
-                hd->platform_ops->teardown(d);
-                return rc;
-            }
+            if ( rc )
+                break;
         }
     }
-    this_cpu(iommu_dont_flush_iotlb) = 0;
-    iommu_iotlb_flush_all(d);
+
     spin_unlock(&d->page_alloc_lock);
-    return 0;
+    this_cpu(iommu_dont_flush_iotlb) = 0;
+
+    if ( !rc )
+        iommu_iotlb_flush_all(d);
+    else
+        hd->platform_ops->teardown(d);
+
+    return rc;
 }
 
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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