[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 2/4] xen: grant_table: implement grant_table_soft_reset()
When soft reset is being performed we need to replace all actively granted pages with empty pages to prevent possible future memory corruption as the newly started kernel won't be aware of these granted pages. We make the tot_pages < max_pages assumption here: previously granted pages need to belong to someone and we don't want to implement possible DoS by reassigning them to the grantee/anonymous domain/xen/.. (the malicious guest will be able to consume all host's memory). Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> --- xen/common/grant_table.c | 62 +++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/grant_table.h | 6 +++++ 2 files changed, 68 insertions(+) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index dfb45f8..815d5f3 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -3120,6 +3120,68 @@ gnttab_release_mappings( } } +int grant_table_soft_reset(struct domain *d) +{ + struct grant_table *gt = d->grant_table; + struct active_grant_entry *act; + grant_ref_t ref; + unsigned long mfn_new; + struct page_info *page, *new_page; + int ret = 0; + + spin_lock(>->lock); + + for ( ref = 0; ref != nr_grant_entries(gt); ref++ ) + { + act = &active_entry(gt, ref); + if ( !act->pin ) + continue; + + page = mfn_to_page(act->frame); + if ( !page || !get_page(page, d) ) + { + printk(XENLOG_G_ERR "Dom%d's grant frame %lx (gfn %lx) is invalid", + d->domain_id, act->gfn, act->frame); + ret = -EINVAL; + break; + } + + /* + * Here we assume the domain has tot_pages < max_pages. Previously + * granted page will still belong to us until it is unmapped from + * grantee. + */ + new_page = alloc_domheap_page(d, 0); + if ( !new_page ) + { + printk(XENLOG_G_ERR "Failed to alloc a page to replace" + " Dom%d's grant frame %lx\n", d->domain_id, act->frame); + ret = -ENOMEM; + put_page(page); + break; + } + mfn_new = page_to_mfn(new_page); + guest_remove_page(d, act->gfn); + + if ( guest_physmap_add_page(d, act->gfn, mfn_new, 0) ) + { + printk(XENLOG_G_ERR "Failed to replace Dom%d's grant frame %lx" + " with new MFN %lx\n", d->domain_id, act->frame, mfn_new); + ret = -EFAULT; + } + + gnttab_flush_tlb(d); + + put_page(new_page); + put_page(page); + + if (ret) + break; + } + + spin_unlock(>->lock); + return ret; +} void grant_table_destroy( diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 32f5786..3f58c54 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -95,6 +95,12 @@ int grant_table_create( void grant_table_destroy( struct domain *d); +/* + * Replace all granted pages with empty pages for a domain to prevent possible + * future memory corruption in case of soft reset. + */ +int grant_table_soft_reset(struct domain *d); + /* Domain death release of granted mappings of other domains' memory. */ void gnttab_release_mappings( -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |