[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Invalid PDE entry in vmx domain will crash system.


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Li, Xin B" <xin.b.li@xxxxxxxxx>
  • Date: Thu, 12 Jan 2006 20:53:28 +0800
  • Delivery-date: Thu, 12 Jan 2006 13:00:06 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: AcYXdy7iJO2UDd7oSRyGUjHLZA8tYQ==
  • Thread-topic: Invalid PDE entry in vmx domain will crash system.

Hi Keir, we found invalid PDE entry in vmx domain will crash the whole
system, the code is in update_hl2e():

static inline void
update_hl2e(struct vcpu *v, unsigned long va)
{
    int index = l2_table_offset(va);
    unsigned long mfn;
    l2_pgentry_t gl2e = v->arch.guest_vtable[index];
    l1_pgentry_t old_hl2e, new_hl2e;
    int need_flush = 0;

    ASSERT(shadow_mode_translate(v->domain));

    old_hl2e = v->arch.hl2_vtable[index];

    if ( (l2e_get_flags(gl2e) & _PAGE_PRESENT) &&
         VALID_MFN(mfn = get_mfn_from_pfn(l2e_get_pfn(gl2e))) )
        new_hl2e = l1e_from_pfn(mfn, __PAGE_HYPERVISOR);
    else
        new_hl2e = l1e_empty();

... ...
}

Here, if there is an invalid PDE entry in VMX domain (For example, a VMX
domain only has 512M RAM, but a PDE entry is 0x40000063, the pfn is
beyond 512M RAM), so this invalid PDE entry will cause mfn =
get_mfn_from_pfn(l2e_get_pfn(gl2e)) return the invalid mfn = 0xFFFFFFFF,
and then a bad PTE is set into hl2 table, and later while trying to get
the gl1e of VMX guest, a page fault happened in Xen, and crashed the
system.

The problem here is, even there is an invalid PDE entry in VMX guest,
xen HV should not crash. We need a patch to protect Xen HV here, two
pieces of code need change:
1) if VALID_MFN(mfn = get_mfn_from_pfn(l2e_get_pfn(gl2e))) is true, this
function should fail. But seems xenlinux also uses this function, will
such change impact on xenlinux? Or only fail when it's external mode.
2) Jun suggested when accessing linear_pg_table, we should use
copy_from_user, change 
    orig_gpte = gpte = linear_pg_table[l1_linear_offset(va)];
To
    if ( !(__copy_from_user(&gpte,
&linear_pg_table[l1_linear_offset(va)],
                           sizeof(gpte)) == 0) )
    {
        printk("Bad guest PDE entry: gpde = 0x%x, va = 0x%lx\n",
               l2e_get_intpte(gpde), va);
        //fail handling...
    }

If you think it's OK, I will send a patch later.

-Xin

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.