aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2014-10-14 05:00:18 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2014-10-23 11:24:01 -0400
commit239af7c7132a617f9dcd05da1dc92b96bc6d0645 (patch)
tree74c821845a28a43278cf4522f0871f70dcbb2ba4
parentfd8b79511349efd1f0decea920f61b93acb34a75 (diff)
x86/xen: avoid writing to freed memory after race in p2m handling
In case a race was detected during allocation of a new p2m tree element in alloc_p2m() the new allocated mid_mfn page is freed without updating the pointer to the found value in the tree. This will result in overwriting the just freed page with the mfn of the p2m leaf. Signed-off-by: Juergen Gross <jgross@suse.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
-rw-r--r--arch/x86/xen/p2m.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 9f5983b01ed9..4534320e66e4 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -566,6 +566,7 @@ static bool alloc_p2m(unsigned long pfn)
566 /* Separately check the mid mfn level */ 566 /* Separately check the mid mfn level */
567 unsigned long missing_mfn; 567 unsigned long missing_mfn;
568 unsigned long mid_mfn_mfn; 568 unsigned long mid_mfn_mfn;
569 unsigned long old_mfn;
569 570
570 mid_mfn = alloc_p2m_page(); 571 mid_mfn = alloc_p2m_page();
571 if (!mid_mfn) 572 if (!mid_mfn)
@@ -575,10 +576,13 @@ static bool alloc_p2m(unsigned long pfn)
575 576
576 missing_mfn = virt_to_mfn(p2m_mid_missing_mfn); 577 missing_mfn = virt_to_mfn(p2m_mid_missing_mfn);
577 mid_mfn_mfn = virt_to_mfn(mid_mfn); 578 mid_mfn_mfn = virt_to_mfn(mid_mfn);
578 if (cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn) != missing_mfn) 579 old_mfn = cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn);
580 if (old_mfn != missing_mfn) {
579 free_p2m_page(mid_mfn); 581 free_p2m_page(mid_mfn);
580 else 582 mid_mfn = mfn_to_virt(old_mfn);
583 } else {
581 p2m_top_mfn_p[topidx] = mid_mfn; 584 p2m_top_mfn_p[topidx] = mid_mfn;
585 }
582 } 586 }
583 587
584 if (p2m_top[topidx][mididx] == p2m_identity || 588 if (p2m_top[topidx][mididx] == p2m_identity ||