From 1ee8a8048fe8ea7ba5b3240f12f11986af26f452 Mon Sep 17 00:00:00 2001 From: Alexandru Stefan ISAILA Date: Mon, 23 Dec 2019 14:04:31 +0000 Subject: [PATCH 4/4] x86/mm: Use nospec_clip() to check guest-supplied values. This patch aims to sanitize indexes, potentially guest provided values, for altp2m_eptp[] and altp2m_p2m[] arrays. Based on a patch by Alexandru Isaila . Signed-off-by: George Dunlap --- xen/arch/x86/mm/mem_access.c | 6 +++--- xen/arch/x86/mm/p2m.c | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c index 320b9fe621..5b4a4f43ef 100644 --- a/xen/arch/x86/mm/mem_access.c +++ b/xen/arch/x86/mm/mem_access.c @@ -366,7 +366,7 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr, #ifdef CONFIG_HVM if ( altp2m_idx ) { - if ( altp2m_idx >= MAX_ALTP2M || + if ( nospec_clip(altp2m_idx, MAX_ALTP2M) || d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) return -EINVAL; @@ -425,7 +425,7 @@ long p2m_set_mem_access_multi(struct domain *d, #ifdef CONFIG_HVM if ( altp2m_idx ) { - if ( altp2m_idx >= MAX_ALTP2M || + if ( nospec_clip(altp2m_idx, MAX_ALTP2M) || d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) return -EINVAL; @@ -491,7 +491,7 @@ int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access, } else if ( altp2m_idx ) /* altp2m view 0 is treated as the hostp2m */ { - if ( altp2m_idx >= MAX_ALTP2M || + if ( nospec_clip(altp2m_idx, MAX_ALTP2M) || d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) return -EINVAL; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index b9f8948130..4f93f410c8 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -2571,7 +2571,7 @@ int p2m_init_altp2m_by_id(struct domain *d, unsigned int idx) { int rc = -EINVAL; - if ( idx >= MAX_ALTP2M ) + if ( nospec_clip(idx, MAX_ALTP2M) ) return rc; altp2m_list_lock(d); @@ -2612,7 +2612,7 @@ int p2m_destroy_altp2m_by_id(struct domain *d, unsigned int idx) struct p2m_domain *p2m; int rc = -EBUSY; - if ( !idx || idx >= MAX_ALTP2M ) + if ( !idx || nospec_clip(idx, MAX_ALTP2M) ) return rc; rc = domain_pause_except_self(d); @@ -2686,7 +2686,8 @@ int p2m_change_altp2m_gfn(struct domain *d, unsigned int idx, mfn_t mfn; int rc = -EINVAL; - if ( idx >= MAX_ALTP2M || d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) + if ( nospec_clip(idx, MAX_ALTP2M) || + d->arch.altp2m_eptp[idx] == mfn_x(INVALID_MFN) ) return rc; hp2m = p2m_get_hostp2m(d); @@ -3029,7 +3030,7 @@ int p2m_set_suppress_ve(struct domain *d, gfn_t gfn, bool suppress_ve, if ( altp2m_idx > 0 ) { - if ( altp2m_idx >= MAX_ALTP2M || + if ( nospec_clip(altp2m_idx, MAX_ALTP2M) || d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) return -EINVAL; @@ -3072,7 +3073,7 @@ int p2m_get_suppress_ve(struct domain *d, gfn_t gfn, bool *suppress_ve, if ( altp2m_idx > 0 ) { - if ( altp2m_idx >= MAX_ALTP2M || + if ( nospec_clip(altp2m_idx, MAX_ALTP2M) || d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) return -EINVAL; -- 2.24.0