Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.6712
xsa247-2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa247-2.patch of Package xen.6712
From 6a483ec69f93597aa5edd7e6979cd297c1294edb Mon Sep 17 00:00:00 2001 From: George Dunlap <george.dunlap@citrix.com> Date: Fri, 10 Nov 2017 16:53:55 +0000 Subject: [PATCH 2/2] p2m: Check return value of p2m_set_entry() when decreasing reservation If the entire range specified to p2m_pod_decrease_reservation() is marked populate-on-demand, then it will make a single p2m_set_entry() call, reducing its PoD entry count. Unfortunately, in the right circumstances, this p2m_set_entry() call may fail. It that case, repeated calls to decrease_reservation() may cause p2m->pod.entry_count to fall below zero, potentially tripping over BUG_ON()s to the contrary. Instead, check to see if the entry succeeded, and return false if not. The caller will then call guest_remove_page() on the gfns, which will return -EINVAL upon finding no valid memory there to return. Unfortunately if the order > 0, the entry may have partially changed. A domain_crash() is probably the safest thing in that case. Other p2m_set_entry() calls in the same function should be fine, because they are writing the entry at its current order. Nonetheless, check the return value and crash if our assumption turns otu to be wrong. This is part of XSA-247. Signed-off-by: George Dunlap <george.dunlap@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- v2: Crash the domain if we're not sure it's safe (or if we think it can't happen) --- xen/arch/x86/mm/p2m-pod.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) Index: xen-4.5.5-testing/xen/arch/x86/mm/p2m-pod.c =================================================================== --- xen-4.5.5-testing.orig/xen/arch/x86/mm/p2m-pod.c +++ xen-4.5.5-testing/xen/arch/x86/mm/p2m-pod.c @@ -560,11 +560,23 @@ recount: if ( !nonpod ) { - /* All PoD: Mark the whole region invalid and tell caller - * we're done. */ - p2m_set_entry(p2m, gpfn, _mfn(INVALID_MFN), order, p2m_invalid, - p2m->default_access); - p2m->pod.entry_count-=(1<<order); + /* + * All PoD: Mark the whole region invalid and tell caller + * we're done. + */ + if ( p2m_set_entry(p2m, gpfn, _mfn(INVALID_MFN), order, p2m_invalid, + p2m->default_access) ) + { + /* + * If this fails, we can't tell how much of the range was changed. + * Best to crash the domain unless we're sure a partial change is + * impossible. + */ + if ( order != 0 ) + domain_crash(d); + goto out_unlock; + } + p2m->pod.entry_count -= 1UL << order; BUG_ON(p2m->pod.entry_count < 0); ret = 1; goto out_entry_check; @@ -596,8 +608,14 @@ recount: mfn = p2m->get_entry(p2m, gpfn + i, &t, &a, 0, NULL); if ( t == p2m_populate_on_demand ) { - p2m_set_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid, - p2m->default_access); + /* This shouldn't be able to fail */ + if ( p2m_set_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, + p2m_invalid, p2m->default_access) ) + { + ASSERT_UNREACHABLE(); + domain_crash(d); + goto out_unlock; + } p2m->pod.entry_count--; BUG_ON(p2m->pod.entry_count < 0); pod--; @@ -610,8 +628,14 @@ recount: page = mfn_to_page(mfn); - p2m_set_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, p2m_invalid, - p2m->default_access); + /* This shouldn't be able to fail */ + if ( p2m_set_entry(p2m, gpfn + i, _mfn(INVALID_MFN), 0, + p2m_invalid, p2m->default_access) ) + { + ASSERT_UNREACHABLE(); + domain_crash(d); + goto out_unlock; + } set_gpfn_from_mfn(mfn_x(mfn), INVALID_M2P_ENTRY); p2m_pod_cache_add(p2m, page, 0);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor