[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.12] xen/page_alloc: Harden assign_pages()
commit 8e657cfe0aec6c2bf548cae98a97d2485304d4c6 Author: Julien Grall <jgrall@xxxxxxxxxx> AuthorDate: Tue Nov 23 13:35:03 2021 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Nov 23 13:35:03 2021 +0100 xen/page_alloc: Harden assign_pages() domain_tot_pages() and d->max_pages are 32-bit values. While the order should always be quite small, it would still be possible to overflow if domain_tot_pages() is near to (2^32 - 1). As this code may be called by a guest via XENMEM_increase_reservation and XENMEM_populate_physmap, we want to make sure the guest is not going to be able to allocate more than it is allowed. Rework the allocation check to avoid any possible overflow. While the check domain_tot_pages() < d->max_pages should technically not be necessary, it is probably best to have it to catch any possible inconsistencies in the future. This is CVE-2021-28706 / part of XSA-385. Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> master commit: 143501861d48e1bfef495849fd68584baac05849 master date: 2021-11-22 11:11:05 +0000 --- xen/common/grant_table.c | 7 ++++--- xen/common/page_alloc.c | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 2bc00f30a3..ee5748e74e 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -2239,7 +2239,8 @@ gnttab_transfer( * pages when it is dying. */ if ( unlikely(e->is_dying) || - unlikely(e->tot_pages >= e->max_pages) ) + unlikely(e->tot_pages >= e->max_pages) || + unlikely(!(e->tot_pages + 1)) ) { spin_unlock(&e->page_alloc_lock); @@ -2248,8 +2249,8 @@ gnttab_transfer( e->domain_id); else gdprintk(XENLOG_INFO, - "Transferee d%d has no headroom (tot %u, max %u)\n", - e->domain_id, e->tot_pages, e->max_pages); + "Transferee %pd has no headroom (tot %u, max %u)\n", + e, e->tot_pages, e->max_pages); gop.status = GNTST_general_error; goto unlock_and_copyback; diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 1dee9a05d4..3ab90aca32 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -2278,17 +2278,26 @@ int assign_pages( if ( !(memflags & MEMF_no_refcount) ) { - if ( unlikely((d->tot_pages + (1 << order)) > d->max_pages) ) + unsigned int nr = 1u << order; + + if ( unlikely(d->tot_pages > d->max_pages) ) + { + gprintk(XENLOG_INFO, "Inconsistent allocation for %pd: %u > %u\n", + d, d->tot_pages, d->max_pages); + rc = -EPERM; + goto out; + } + + if ( unlikely(nr > d->max_pages - d->tot_pages) ) { if ( !tmem_enabled() || order != 0 || d->tot_pages != d->max_pages ) - gprintk(XENLOG_INFO, "Over-allocation for domain %u: " - "%u > %u\n", d->domain_id, - d->tot_pages + (1 << order), d->max_pages); + gprintk(XENLOG_INFO, "Over-allocation for %pd: %Lu > %u\n", + d, d->tot_pages + 0ull + nr, d->max_pages); rc = -E2BIG; goto out; } - if ( unlikely(domain_adjust_tot_pages(d, 1 << order) == (1 << order)) ) + if ( unlikely(domain_adjust_tot_pages(d, nr) == nr) ) get_knownalive_domain(d); } -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.12
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |