Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.8005
59ef47bd-gnttab-fix-pin-count-page-reference-ra...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 59ef47bd-gnttab-fix-pin-count-page-reference-race.patch of Package xen.8005
# Commit e008f7619dcd6d549727c9635b3f9f3c7ee483ed # Date 2017-10-24 16:01:33 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> gnttab: fix pin count / page reference race Dropping page references before decrementing pin counts is a bad idea if assumptions are being made that a non-zero pin count implies a valid page. Fix the order of operations in gnttab_copy_release_buf(), but at the same time also remove the assertion that was found to trigger: map_grant_ref() also has the potential of causing a race here, and changing the order of operations there would likely be quite a bit more involved. This is CVE-2017-15597 / XSA-236. Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -2030,7 +2030,23 @@ __acquire_grant_for_copy( { ASSERT(mfn_valid(act->frame)); *page = mfn_to_page(act->frame); - (void)page_get_owner_and_reference(*page); + td = page_get_owner_and_reference(*page); + /* + * act->pin being non-zero should guarantee the page to have a + * non-zero refcount and hence a valid owner (matching the one on + * record), with one exception: If the owning domain is dying we + * had better not make implications from pin count (map_grant_ref() + * updates pin counts before obtaining page references, for + * example). + */ + if ( td != rd || rd->is_dying ) + { + if ( td ) + put_page(*page); + *page = NULL; + rc = GNTST_bad_domain; + goto unlock_out_clear; + } } act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; @@ -2167,14 +2183,14 @@ __gnttab_copy( put_page_type(d_pg); error_out: - if ( d_pg ) - put_page(d_pg); - if ( s_pg ) - put_page(s_pg); if ( have_s_grant ) __release_grant_for_copy(sd, op->source.u.ref, 1); if ( have_d_grant ) __release_grant_for_copy(dd, op->dest.u.ref, 0); + if ( d_pg ) + put_page(d_pg); + if ( s_pg ) + put_page(s_pg); if ( sd ) rcu_unlock_domain(sd); if ( dd )
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