[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH for-4.6] xen/mm: populate_physmap: validate correctly the gfn for direct mapped domain
On Tue, 2015-08-11 at 18:41 +0100, Julien Grall wrote: > Direct mapped domain has already the memory allocated 1:1, so we are > directly using the gfn as mfn to map the RAM in the guest. > > While we are validating that the page associated to the first mfn belongs > to > the domain, the subsequent MFN are not validated when the extent_order > is > 0. > > This may result to map memory region (MMIO, RAM) which doesn't belong to > the > domain. > > Although, only DOM0 on ARM is using a direct memory mapped. So it > doesn't affect any guest (at least on the upstream version) or even x86. > > Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> > > --- > Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> > Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > Cc: Jan Beulich <jbeulich@xxxxxxxx> > Cc: Keir Fraser <keir@xxxxxxx> > Cc: Tim Deegan <tim@xxxxxxx> > > This patch is a candidate for Xen 4.6 and backport to Xen 4.5 (and > maybe 4.4). > > The hypercall is used for the ballooning code and only DOM0 on ARM > is a direct mapped domain. > > The current code to validate the GFN passed by the populate physmap > hypercall has been moved in a for loop in order to validate each > GFN when the extent order is > 0. > > Without it, direct mapping domain may be able to map memory region > which doesn't belong to it. > > I think the switch to the for loop is pretty safe and contained. The > worst thing that could happen is denying mapping more often than we > use to do. Although, IIRC Linux is mostly mapping page one by one > (i.e extent order = 0). > --- > xen/common/memory.c | 30 ++++++++++++++++++------------ > 1 file changed, 18 insertions(+), 12 deletions(-) > > diff --git a/xen/common/memory.c b/xen/common/memory.c > index 61bb94c..7cc8af4 100644 > --- a/xen/common/memory.c > +++ b/xen/common/memory.c > @@ -126,22 +126,28 @@ static void populate_physmap(struct memop_args *a) > if ( is_domain_direct_mapped(d) ) > { > mfn = gpfn; > - if ( !mfn_valid(mfn) ) > + > + for ( j = 0; j < (1 << a->extent_order); j++, mfn++ ) > { > - gdprintk(XENLOG_INFO, "Invalid mfn > %#"PRI_xen_pfn"\n", > + if ( !mfn_valid(mfn) ) > + { > + gdprintk(XENLOG_INFO, "Invalid mfn > %#"PRI_xen_pfn"\n", > mfn); > - goto out; > + goto out; > + } > + > + page = mfn_to_page(mfn); > + if ( !get_page(page, d) ) > + { > + gdprintk(XENLOG_INFO, > + "mfn %#"PRI_xen_pfn" doesn't belong to > the" > + " domain\n", mfn); > + goto out; This will leak the references on any earlier pages, which will happen all the time if you are cross a boundary from RAM into e.g. MMIO or whatever. A variant of get_page which took an order argument and returned either with 0 or 1<<order refs taken would perhaps make this easier to deal with. I suppose we don't already have one of those, but you could add it. Oh, am I wrong and we do get_page then immediately put_page for every page? I suppose that is one way to check the current owner, but I think it needs a comment at least (it did before TBH, just iterating over many pages makes it seem even odder). Is that really the best way to ask if a page is owned by a given domain tho ugh? Does page_get_owner not suffice? > + } > + put_page(page); > } > > - page = mfn_to_page(mfn); > - if ( !get_page(page, d) ) > - { > - gdprintk(XENLOG_INFO, > - "mfn %#"PRI_xen_pfn" doesn't belong to the" > - " domain\n", mfn); > - goto out; > - } > - put_page(page); > + page = mfn_to_page(gpfn); > } > else > page = alloc_domheap_pages(d, a->extent_order, a > ->memflags); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |