CVE-2013-6400
http://xenbits.xen.org/xsa/advisory-80.html
IOMMU TLB flushing may be inadvertently suppressed
An internal flag is used to temporarily suppress IOMMU TLB flushes, in order to consolidate multiple single page flushes into one wider flush. This flag is not cleared again, on certain error paths. This can result in TLB flushes not happening when they are needed. Retaining stale TLB entries could allow guests access to memory that ought to have been revoked, or grant greater access than intended.
improper error handling (not clear internal flag)
http://xenbits.xen.org/xsa/xsa82.patch
IOMMU: clear
don’t flushoverride on error pathsBoth 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.
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4648,7 +4648,7 @@ static int xenmem_add_to_physmap(struct
{
rc = xenmem_add_to_physmap_once(d, xatp);
if ( rc < 0 )
- return rc;
+ break;
xatp->idx++;
xatp->gpfn++;
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -306,11 +306,11 @@ static int iommu_populate_page_table(str
{
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) ||
@@ -320,18 +320,20 @@ static int iommu_populate_page_table(str
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;
}
Malicious guest administrators might be able to cause host-wide denial of service, or escalate their privilege to that of the host.
DoS, privilege escalation