[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Xen Security Advisory 154 (CVE-2016-2270) - x86: inconsistent cachability flags on guest mappings
On Wed, 2017-01-25 at 07:21 -0700, Jan Beulich wrote: > > If there wasn't INVALID_MFN to be taken care of, the !mfn_valid() > check could simply move down, and be combined with the > direct_mmio one. As discussed on IRC, once we fix the overflow with order > 0, I think INVALID_MFN is OK. Not that it should ever really happen, AFAICT. This seems to do the right thing for my MMIO WC test. I haven't actually combined the !mfn_valid() check with the direct_mmio one. Under what circumstances does that make sense anyway? For now in the patch below I've left it *forcing* UC, unlike the direct_mmio path which lets the guest use WC. But really, shouldn't the '!direct_mmio && !mfn_valid()' case just return an error? Note that as well as using a mask for 'order' I've attempted to consolidate the unlikely rangeset_overlaps_range() and rangeset_contains_range() calls, on the assumption that the former will *always* be true if the latter is, so we only need one of them in the fast path through the function. diff --git a/xen/arch/x86/hvm/mtrr.c b/xen/arch/x86/hvm/mtrr.c index 709759c..09c2f5c 100644 --- a/xen/arch/x86/hvm/mtrr.c +++ b/xen/arch/x86/hvm/mtrr.c @@ -773,20 +773,24 @@ int epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn, if ( v->domain != d ) v = d->vcpu ? d->vcpu[0] : NULL; - if ( !mfn_valid(mfn_x(mfn)) || - rangeset_contains_range(mmio_ro_ranges, mfn_x(mfn), - mfn_x(mfn) + (1UL << order) - 1) ) + /* INVALID_MFN should never happen here, but if it does then this + * should do the right thing instead of exploding */ + if ( unlikely(rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn), + mfn_x(mfn) | ((1UL << order) - 1))) ) { - *ipat = 1; - return MTRR_TYPE_UNCACHABLE; + if ( rangeset_contains_range(mmio_ro_ranges, mfn_x(mfn), + mfn_x(mfn) | ((1UL << order) - 1)) ) + { + *ipat = 1; + return MTRR_TYPE_UNCACHABLE; + } + /* Overlaps mmio_ro_ranges but is not entirely contained. No. */ + return -1; } - if ( rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn), - mfn_x(mfn) + (1UL << order) - 1) ) - return -1; - if ( direct_mmio ) { + /* Again, INVALID_MFN should do the right thing here. */ if ( (mfn_x(mfn) ^ d->arch.hvm_domain.vmx.apic_access_mfn) >> order ) return MTRR_TYPE_UNCACHABLE; if ( order ) @@ -795,6 +799,12 @@ int epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn, return MTRR_TYPE_WRBACK; } + if ( unlikely(!mfn_valid(mfn_x(mfn))) ) + { + *ipat = 1; + return MTRR_TYPE_UNCACHABLE; + } + if ( !need_iommu(d) && !cache_flush_permitted(d) ) { *ipat = 1; Attachment:
smime.p7s _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |