x86/HVM: restrict HVMOP_set_mem_type Permitting arbitrary type changes here has the potential of creating present P2M (and hence EPT/NPT/IOMMU) entries pointing to an invalid MFN (INVALID_MFN truncated to the respective hardware structure field's width). This would become a problem the latest when something real sat at the end of the physical address space; I'm suspecting though that other things might break with such bogus entries. Along with that drop a bogus (and otherwise becoming stale) log message. Afaict the similar operation in p2m_set_mem_access() is safe. This is XSA-92. Signed-off-by: Jan Beulich Reviewed-by: Tim Deegan --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3666,13 +3666,9 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = -EINVAL; goto param_fail4; } - if ( p2m_is_grant(t) ) - { - gdprintk(XENLOG_WARNING, - "type for pfn 0x%lx changed to grant while " - "we were working?\n", pfn); + if ( !p2m_is_ram(t) && + (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) ) goto param_fail4; - } else { nt = p2m_change_type(p2m, pfn, t, memtype[a.hvmmem_type]); --- a/xen/include/asm-x86/p2m.h +++ b/xen/include/asm-x86/p2m.h @@ -134,6 +134,13 @@ typedef enum { | p2m_to_mask(p2m_ram_paging_in) \ | p2m_to_mask(p2m_ram_shared)) +/* Types that represent a physmap hole. */ +#define P2M_HOLE_TYPES (p2m_to_mask(p2m_mmio_dm) \ + | p2m_to_mask(p2m_invalid) \ + | p2m_to_mask(p2m_ram_paging_in_start) \ + | p2m_to_mask(p2m_ram_paging_in) \ + | p2m_to_mask(p2m_ram_paged)) + /* Grant mapping types, which map to a real machine frame in another * VM */ #define P2M_GRANT_TYPES (p2m_to_mask(p2m_grant_map_rw) \ @@ -170,6 +177,7 @@ typedef enum { /* Useful predicates */ #define p2m_is_ram(_t) (p2m_to_mask(_t) & P2M_RAM_TYPES) +#define p2m_is_hole(_t) (p2m_to_mask(_t) & P2M_HOLE_TYPES) #define p2m_is_mmio(_t) (p2m_to_mask(_t) & P2M_MMIO_TYPES) #define p2m_is_readonly(_t) (p2m_to_mask(_t) & P2M_RO_TYPES) #define p2m_is_magic(_t) (p2m_to_mask(_t) & P2M_MAGIC_TYPES)