]> xenbits.xensource.com Git - xen.git/commitdiff
x86/shadow: fix race condition sampling the dirty vram state
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 23 Sep 2014 12:49:35 +0000 (14:49 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 23 Sep 2014 12:49:35 +0000 (14:49 +0200)
d->arch.hvm_domain.dirty_vram must be read with the domain's paging lock held.

If not, two concurrent hypercalls could both end up attempting to free
dirty_vram (the second of which will free a wild pointer), or both end up
allocating a new dirty_vram structure (the first of which will be leaked).

This is XSA-104.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Tim Deegan <tim@xen.org>
master commit: 46a49b91f1026f64430b84dd83e845a33f06415e
master date: 2014-09-23 14:31:47 +0200

xen/arch/x86/mm/shadow/common.c
xen/include/asm-x86/hvm/domain.h

index 0362c859d795ff03bc55412a7a971c91bac0758e..d259902fddc9db3b751b72a50eb4a005886e217d 100644 (file)
@@ -3601,7 +3601,7 @@ int shadow_track_dirty_vram(struct domain *d,
     int flush_tlb = 0;
     unsigned long i;
     p2m_type_t t;
-    struct sh_dirty_vram *dirty_vram = d->arch.hvm_domain.dirty_vram;
+    struct sh_dirty_vram *dirty_vram;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     if ( end_pfn < begin_pfn || end_pfn > p2m->max_mapped_pfn + 1 )
@@ -3611,6 +3611,8 @@ int shadow_track_dirty_vram(struct domain *d,
     p2m_lock(p2m_get_hostp2m(d));
     paging_lock(d);
 
+    dirty_vram = d->arch.hvm_domain.dirty_vram;
+
     if ( dirty_vram && (!nr ||
              ( begin_pfn != dirty_vram->begin_pfn
             || end_pfn   != dirty_vram->end_pfn )) )
index 27b3de50dc89304e2088e4fea70d14527accf476..863b097060edaf82fbf9e9bda9a49486ae7442b7 100644 (file)
@@ -73,7 +73,7 @@ struct hvm_domain {
     /* Memory ranges with pinned cache attributes. */
     struct list_head       pinned_cacheattr_ranges;
 
-    /* VRAM dirty support. */
+    /* VRAM dirty support.  Protect with the domain paging lock. */
     struct sh_dirty_vram *dirty_vram;
 
     /* If one of vcpus of this domain is in no_fill_mode or