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

Re: [Xen-devel] [PATCH] xen/xsm: Fix xsm_mmu_* and xsm_update_va_mapping hooks


  • To: Stephen Smalley <sds@xxxxxxxxxxxxx>, Xen <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Keir Fraser <keir@xxxxxxx>
  • Date: Tue, 12 Apr 2011 14:09:08 +0100
  • Cc:
  • Delivery-date: Tue, 12 Apr 2011 06:11:08 -0700
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:user-agent:date:subject:from:to:message-id:thread-topic :thread-index:in-reply-to:mime-version:content-type :content-transfer-encoding; b=gv3ycyTXkbnbRp+aUpYqNurnTcmVn+bQdhDLz4op4TU3w5TeiczTTHjrIEkBkZkt7m GDhiA3pvVrkiHi6i1zFNesZTMy655vAMoy7YkyO2abvojqFG/bxw8ABVDo5iM31cPvoo 810eef5DLeYH1JcbgbXhigsXny6cM5uU4im2Q=
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: Acv5Es6Il6TpiwpWJkK9SjjsC+JPGw==
  • Thread-topic: [Xen-devel] [PATCH] xen/xsm: Fix xsm_mmu_* and xsm_update_va_mapping hooks

On 12/04/2011 13:31, "Stephen Smalley" <sds@xxxxxxxxxxxxx> wrote:

> On Mon, 2011-03-21 at 14:57 -0400, Stephen Smalley wrote:
>> This is an attempt to properly fix the hypervisor crash previously
>> described in
>> http://marc.info/?l=xen-devel&m=128396289707362&w=2
>> 
>> In looking into this issue, I think the proper fix is to move the
>> xsm_mmu_* and xsm_update_va_mapping hook calls later in the callers,
>> after more validation has been performed and the page_info struct is
>> readily available, and pass the page_info to the hooks. This patch moves
>> the xsm_mmu_normal_update, xsm_mmu_machphys_update and
>> xsm_update_va_mapping hook calls accordingly, and updates their
>> interfaces and hook function implementations.  This appears to resolve
>> the crashes for me.  However, as I am not overly familiar with this area
>> of code, I'd appreciate any feedback or suggestions for improvement.
>> 
>> Signed-off-by:  Stephen Smalley <sds@xxxxxxxxxxxxx>
> 
> Zero replies after two postings.  Should I retry, abort, or fail?
> Seriously though - if there is something wrong with this patch, then let
> me know, and if not, can it get applied sometime?

Hi Stephen,

The patch was posted as RFC with no signed-off-by. The patch looks fine to
me as far as I understand it. Provide a Signed-off-by line and I'll append
it to the patch description and apply it.

You can send these kinds of patches without the RFC tag by the way, unless
you want to give the opportunity for other NSA people to possibly do review
via the public list.

 Thanks,
 Keir

>> ---
>> 
>>  xen/arch/x86/mm.c     |   29 ++++++++++++++++++-----------
>>  xen/include/xsm/xsm.h |   28 +++++++++++++++-------------
>>  xen/xsm/dummy.c       |   11 ++++++-----
>>  xen/xsm/flask/hooks.c |   41 ++++++++---------------------------------
>>  4 files changed, 47 insertions(+), 62 deletions(-)
>> 
>> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
>> --- a/xen/arch/x86/mm.c
>> +++ b/xen/arch/x86/mm.c
>> @@ -3448,9 +3448,6 @@
>>          {
>>              p2m_type_t p2mt;
>>  
>> -            rc = xsm_mmu_normal_update(d, pg_owner, req.val);
>> -            if ( rc )
>> -                break;
>>              rc = -EINVAL;
>>  
>>              req.ptr -= cmd;
>> @@ -3478,6 +3475,13 @@
>>                            (unsigned long)(req.ptr & ~PAGE_MASK));
>>              page = mfn_to_page(mfn);
>>  
>> +            rc = xsm_mmu_normal_update(d, req.val, page);
>> +            if ( rc ) {
>> +                unmap_domain_page_with_cache(va, &mapcache);
>> +                put_page(page);
>> +                break;
>> +            }
>> +
>>              if ( page_lock(page) )
>>              {
>>                  switch ( page->u.inuse.type_info & PGT_type_mask )
>> @@ -3640,10 +3644,6 @@
>>              mfn = req.ptr >> PAGE_SHIFT;
>>              gpfn = req.val;
>>  
>> -            rc = xsm_mmu_machphys_update(d, mfn);
>> -            if ( rc )
>> -                break;
>> -
>>              if ( unlikely(!get_page_from_pagenr(mfn, pg_owner)) )
>>              {
>>                  MEM_LOG("Could not get page for mach->phys update");
>> @@ -3658,6 +3658,10 @@
>>                  break;
>>              }
>>  
>> +            rc = xsm_mmu_machphys_update(d, mfn_to_page(mfn));
>> +            if ( rc )
>> +                break;
>> +
>>              set_gpfn_from_mfn(mfn, gpfn);
>>  
>>              paging_mark_dirty(pg_owner, mfn);
>> @@ -4272,10 +4276,6 @@
>>  
>>      perfc_incr(calls_to_update_va);
>>  
>> -    rc = xsm_update_va_mapping(d, pg_owner, val);
>> -    if ( rc )
>> -        return rc;
>> -
>>      rc = -EINVAL;
>>      pl1e = guest_map_l1e(v, va, &gl1mfn);
>>      if ( unlikely(!pl1e || !get_page_from_pagenr(gl1mfn, d)) )
>> @@ -4295,6 +4295,13 @@
>>          goto out;
>>      }
>>  
>> +    rc = xsm_update_va_mapping(d, val, gl1pg);
>> +    if ( rc ) {
>> +        page_unlock(gl1pg);
>> +        put_page(gl1pg);
>> +        goto out;
>> +    }
>> +
>>      rc = mod_l1_entry(pl1e, val, gl1mfn, 0, v, pg_owner);
>>  
>>      page_unlock(gl1pg);
>> diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
>> --- a/xen/include/xsm/xsm.h
>> +++ b/xen/include/xsm/xsm.h
>> @@ -136,11 +136,12 @@
>>      int (*getidletime) (void);
>>      int (*machine_memory_map) (void);
>>      int (*domain_memory_map) (struct domain *d);
>> -    int (*mmu_normal_update) (struct domain *d, struct domain *f,
>> -                                                                intpte_t
>> fpte);
>> -    int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
>> -    int (*update_va_mapping) (struct domain *d, struct domain *f,
>> -                                                            l1_pgentry_t
>> pte);
>> +    int (*mmu_normal_update) (struct domain *d,
>> +         intpte_t fpte, struct page_info *page);
>> +    int (*mmu_machphys_update) (struct domain *d, struct page_info *page);
>> +    int (*update_va_mapping) (struct domain *d,
>> +         l1_pgentry_t pte,
>> +         struct page_info *page);
>>      int (*add_to_physmap) (struct domain *d1, struct domain *d2);
>>      int (*sendtrigger) (struct domain *d);
>>      int (*test_assign_device) (uint32_t machine_bdf);
>> @@ -567,21 +568,22 @@
>>      return xsm_call(domain_memory_map(d));
>>  }
>>  
>> -static inline int xsm_mmu_normal_update (struct domain *d, struct domain *f,
>> -                                                                intpte_t
>> fpte)
>> +static inline int xsm_mmu_normal_update (struct domain *d,
>> +      intpte_t fpte, struct page_info *page)
>>  {
>> -    return xsm_call(mmu_normal_update(d, f, fpte));
>> +    return xsm_call(mmu_normal_update(d, fpte, page));
>>  }
>>  
>> -static inline int xsm_mmu_machphys_update (struct domain *d, unsigned long
>> mfn)
>> +static inline int xsm_mmu_machphys_update (struct domain *d, struct
>> page_info *page)
>>  {
>> -    return xsm_call(mmu_machphys_update(d, mfn));
>> +    return xsm_call(mmu_machphys_update(d, page));
>>  }
>>  
>> -static inline int xsm_update_va_mapping(struct domain *d, struct domain *f,
>> -                                                            l1_pgentry_t
>> pte)
>> +static inline int xsm_update_va_mapping(struct domain *d,
>> +     l1_pgentry_t pte,
>> +     struct page_info *page)
>>  {
>> -    return xsm_call(update_va_mapping(d, f, pte));
>> +    return xsm_call(update_va_mapping(d, pte, page));
>>  }
>>  
>>  static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2)
>> diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
>> --- a/xen/xsm/dummy.c
>> +++ b/xen/xsm/dummy.c
>> @@ -405,19 +405,20 @@
>>      return 0;
>>  }
>>  
>> -static int dummy_mmu_normal_update (struct domain *d, struct domain *f,
>> -                                                                intpte_t
>> fpte)
>> +static int dummy_mmu_normal_update (struct domain *d,
>> +        intpte_t fpte, struct page_info *page)
>>  {
>>      return 0;
>>  }
>>  
>> -static int dummy_mmu_machphys_update (struct domain *d, unsigned long mfn)
>> +static int dummy_mmu_machphys_update (struct domain *d, struct page_info
>> *page)
>>  {
>>      return 0;
>>  }
>>  
>> -static int dummy_update_va_mapping (struct domain *d, struct domain *f,
>> -                                                            l1_pgentry_t
>> pte)
>> +static int dummy_update_va_mapping (struct domain *d,
>> +        l1_pgentry_t pte,
>> +        struct page_info *page)
>>  {
>>      return 0;
>>  }
>> diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
>> --- a/xen/xsm/flask/hooks.c
>> +++ b/xen/xsm/flask/hooks.c
>> @@ -347,26 +347,6 @@
>>      return rc;
>>  }
>>  
>> -static int get_mfn_sid(unsigned long mfn, u32 *sid)
>> -{
>> -    int rc = 0;
>> -    struct page_info *page;
>> -
>> -    if ( mfn_valid(mfn) )
>> -    {
>> -        /*mfn is valid if this is a page that Xen is tracking!*/
>> -        page = mfn_to_page(mfn);
>> -        rc = get_page_sid(page, sid);
>> -    }
>> -    else
>> -    {
>> -        /*Possibly an untracked IO page?*/
>> -        rc = security_iomem_sid(mfn, sid);
>> -    }
>> -
>> -    return rc; 
>> -}
>> -
>>  static int flask_memory_adjust_reservation(struct domain *d1, struct domain
>> *d2)
>>  {
>>      return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__ADJUST);
>> @@ -1006,12 +986,11 @@
>>      return domain_has_perm(current->domain, d, SECCLASS_MMU,
>> MMU__MEMORYMAP);
>>  }
>>  
>> -static int flask_mmu_normal_update(struct domain *d, struct domain *f,
>> -                                   intpte_t fpte)
>> +static int flask_mmu_normal_update(struct domain *d,
>> +                                   intpte_t fpte, struct page_info *page)
>>  {
>>      int rc = 0;
>>      u32 map_perms = MMU__MAP_READ;
>> -    unsigned long fmfn;
>>      struct domain_security_struct *dsec;
>>      u32 fsid;
>>  
>> @@ -1020,42 +999,38 @@
>>      if ( l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_RW )
>>          map_perms |= MMU__MAP_WRITE;
>>  
>> -    fmfn = gmfn_to_mfn(f, l1e_get_pfn(l1e_from_intpte(fpte)));
>> -
>> -    rc = get_mfn_sid(fmfn, &fsid);
>> +    rc = get_page_sid(page, &fsid);
>>      if ( rc )
>>          return rc;
>>  
>>      return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, NULL);
>>  }
>>  
>> -static int flask_mmu_machphys_update(struct domain *d, unsigned long mfn)
>> +static int flask_mmu_machphys_update(struct domain *d, struct page_info
>> *page)
>>  {
>>      int rc = 0;
>>      u32 psid;
>>      struct domain_security_struct *dsec;
>>      dsec = d->ssid;
>>  
>> -    rc = get_mfn_sid(mfn, &psid);
>> +    rc = get_page_sid(page, &psid);
>>      if ( rc )
>>          return rc;
>>  
>>      return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, MMU__UPDATEMP, NULL);
>>  }
>>  
>> -static int flask_update_va_mapping(struct domain *d, struct domain *f,
>> -                                   l1_pgentry_t pte)
>> +static int flask_update_va_mapping(struct domain *d,
>> +                                   l1_pgentry_t pte, struct page_info *page)
>>  {
>>      int rc = 0;
>>      u32 psid;
>>      u32 map_perms = MMU__MAP_READ;
>> -    unsigned long mfn;
>>      struct domain_security_struct *dsec;
>>  
>>      dsec = d->ssid;
>>  
>> -    mfn = gmfn_to_mfn(f, l1e_get_pfn(pte));
>> -    rc = get_mfn_sid(mfn, &psid);
>> +    rc = get_page_sid(page, &psid);
>>      if ( rc )
>>          return rc;
>>  
>> 



_______________________________________________
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®.