aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/domctl.c23
-rw-r--r--xen/arch/x86/mm.c4
-rw-r--r--xen/include/xsm/xsm.h23
-rw-r--r--xen/xsm/dummy.c6
-rw-r--r--xen/xsm/flask/hooks.c189
5 files changed, 80 insertions, 165 deletions
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 135ea6eca0..97a13fba99 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -114,7 +114,7 @@ long arch_do_domctl(
page = mfn_to_page(mfn);
- ret = xsm_getpageframeinfo(page);
+ ret = xsm_getpageframeinfo(d);
if ( ret )
{
rcu_unlock_domain(d);
@@ -170,6 +170,13 @@ long arch_do_domctl(
if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
break;
+ ret = xsm_getpageframeinfo(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
if ( unlikely(num > 1024) ||
unlikely(num != domctl->u.getpageframeinfo3.num) )
{
@@ -209,8 +216,6 @@ long arch_do_domctl(
if ( unlikely(!page) ||
unlikely(is_xen_heap_page(page)) )
type = XEN_DOMCTL_PFINFO_XTAB;
- else if ( xsm_getpageframeinfo(page) != 0 )
- ;
else
{
switch( page->u.inuse.type_info & PGT_type_mask )
@@ -267,6 +272,13 @@ long arch_do_domctl(
if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
break;
+ ret = xsm_getpageframeinfo(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
if ( unlikely(num > 1024) )
{
ret = -E2BIG;
@@ -310,11 +322,6 @@ long arch_do_domctl(
if ( unlikely(!page) ||
unlikely(is_xen_heap_page(page)) )
arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
- else if ( xsm_getpageframeinfo(page) != 0 )
- {
- put_page(page);
- continue;
- }
else
{
unsigned long type = 0;
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 84820f1d69..d02fe9703d 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -3073,7 +3073,7 @@ long do_mmuext_op(
break;
}
- if ( (rc = xsm_memory_pin_page(d, page)) != 0 )
+ if ( (rc = xsm_memory_pin_page(d, pg_owner, page)) != 0 )
{
put_page_and_type(page);
okay = 0;
@@ -3643,7 +3643,7 @@ long do_mmu_update(
mfn = req.ptr >> PAGE_SHIFT;
gpfn = req.val;
- rc = xsm_mmu_machphys_update(d, mfn);
+ rc = xsm_mmu_machphys_update(d, pg_owner, mfn);
if ( rc )
break;
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index bef79df8cd..593cdbd10d 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -105,7 +105,7 @@ struct xsm_operations {
int (*set_pod_target) (struct domain *d);
int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2);
int (*memory_stat_reservation) (struct domain *d1, struct domain *d2);
- int (*memory_pin_page) (struct domain *d, struct page_info *page);
+ int (*memory_pin_page) (struct domain *d1, struct domain *d2, struct page_info *page);
int (*remove_from_physmap) (struct domain *d1, struct domain *d2);
int (*console_io) (struct domain *d, int cmd);
@@ -143,7 +143,7 @@ struct xsm_operations {
#ifdef CONFIG_X86
int (*shadow_control) (struct domain *d, uint32_t op);
- int (*getpageframeinfo) (struct page_info *page);
+ int (*getpageframeinfo) (struct domain *d);
int (*getmemlist) (struct domain *d);
int (*hypercall_init) (struct domain *d);
int (*hvmcontext) (struct domain *d, uint32_t op);
@@ -171,9 +171,8 @@ struct xsm_operations {
int (*domain_memory_map) (struct domain *d);
int (*mmu_normal_update) (struct domain *d, struct domain *t,
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_machphys_update) (struct domain *d1, struct domain *d2, unsigned long mfn);
+ int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte);
int (*add_to_physmap) (struct domain *d1, struct domain *d2);
int (*sendtrigger) (struct domain *d);
int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
@@ -455,9 +454,10 @@ static inline int xsm_memory_stat_reservation (struct domain *d1,
return xsm_call(memory_stat_reservation(d1, d2));
}
-static inline int xsm_memory_pin_page(struct domain *d, struct page_info *page)
+static inline int xsm_memory_pin_page(struct domain *d1, struct domain *d2,
+ struct page_info *page)
{
- return xsm_call(memory_pin_page(d, page));
+ return xsm_call(memory_pin_page(d1, d2, page));
}
static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2)
@@ -617,9 +617,9 @@ static inline int xsm_shadow_control (struct domain *d, uint32_t op)
return xsm_call(shadow_control(d, op));
}
-static inline int xsm_getpageframeinfo (struct page_info *page)
+static inline int xsm_getpageframeinfo (struct domain *d)
{
- return xsm_call(getpageframeinfo(page));
+ return xsm_call(getpageframeinfo(d));
}
static inline int xsm_getmemlist (struct domain *d)
@@ -753,9 +753,10 @@ static inline int xsm_mmu_normal_update (struct domain *d, struct domain *t,
return xsm_call(mmu_normal_update(d, t, f, fpte));
}
-static inline int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+static inline int xsm_mmu_machphys_update (struct domain *d1, struct domain *d2,
+ unsigned long mfn)
{
- return xsm_call(mmu_machphys_update(d, mfn));
+ return xsm_call(mmu_machphys_update(d1, d2, mfn));
}
static inline int xsm_update_va_mapping(struct domain *d, struct domain *f,
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 5d35342251..4836fc0f67 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -243,7 +243,7 @@ static int dummy_schedop_shutdown (struct domain *d1, struct domain *d2)
return 0;
}
-static int dummy_memory_pin_page(struct domain *d, struct page_info *page)
+static int dummy_memory_pin_page(struct domain *d1, struct domain *d2, struct page_info *page)
{
return 0;
}
@@ -418,7 +418,7 @@ static int dummy_shadow_control (struct domain *d, uint32_t op)
return 0;
}
-static int dummy_getpageframeinfo (struct page_info *page)
+static int dummy_getpageframeinfo (struct domain *d)
{
return 0;
}
@@ -554,7 +554,7 @@ static int dummy_mmu_normal_update (struct domain *d, struct domain *t,
return 0;
}
-static int dummy_mmu_machphys_update (struct domain *d, unsigned long mfn)
+static int dummy_mmu_machphys_update (struct domain *d, struct domain *f, unsigned long mfn)
{
return 0;
}
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index de79d66b50..8c853de6bb 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -108,15 +108,21 @@ static int flask_domain_alloc_security(struct domain *d)
memset(dsec, 0, sizeof(struct domain_security_struct));
- if ( is_idle_domain(d) )
+ dsec->create_sid = SECSID_NULL;
+ switch ( d->domain_id )
{
+ case DOMID_IDLE:
dsec->sid = SECINITSID_XEN;
dsec->create_sid = SECINITSID_DOM0;
- }
- else
- {
+ break;
+ case DOMID_XEN:
+ dsec->sid = SECINITSID_DOMXEN;
+ break;
+ case DOMID_IO:
+ dsec->sid = SECINITSID_DOMIO;
+ break;
+ default:
dsec->sid = SECINITSID_UNLABELED;
- dsec->create_sid = SECSID_NULL;
}
d->ssid = dsec;
@@ -361,64 +367,6 @@ static int flask_grant_query_size(struct domain *d1, struct domain *d2)
return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__QUERY);
}
-static int get_page_sid(struct page_info *page, u32 *sid)
-{
- int rc = 0;
- struct domain *d;
- struct domain_security_struct *dsec;
- unsigned long mfn;
-
- d = page_get_owner(page);
-
- if ( d == NULL )
- {
- mfn = page_to_mfn(page);
- rc = security_iomem_sid(mfn, sid);
- return rc;
- }
-
- switch ( d->domain_id )
- {
- case DOMID_IO:
- /*A tracked IO page?*/
- *sid = SECINITSID_DOMIO;
- break;
-
- case DOMID_XEN:
- /*A page from Xen's private heap?*/
- *sid = SECINITSID_DOMXEN;
- break;
-
- default:
- /*Pages are implicitly labeled by domain ownership!*/
- dsec = d->ssid;
- *sid = dsec ? dsec->sid : SECINITSID_UNLABELED;
- break;
- }
-
- 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_get_pod_target(struct domain *d)
{
return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET);
@@ -439,18 +387,10 @@ static int flask_memory_stat_reservation(struct domain *d1, struct domain *d2)
return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__STAT);
}
-static int flask_memory_pin_page(struct domain *d, struct page_info *page)
+static int flask_memory_pin_page(struct domain *d1, struct domain *d2,
+ struct page_info *page)
{
- int rc = 0;
- u32 sid;
- struct domain_security_struct *dsec;
- dsec = d->ssid;
-
- rc = get_page_sid(page, &sid);
- if ( rc )
- return rc;
-
- return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__PINPAGE, NULL);
+ return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PINPAGE);
}
static int flask_console_io(struct domain *d, int cmd)
@@ -1095,19 +1035,9 @@ static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t en
return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data);
}
-static int flask_getpageframeinfo(struct page_info *page)
+static int flask_getpageframeinfo(struct domain *d)
{
- int rc = 0;
- u32 tsid;
- struct domain_security_struct *dsec;
-
- dsec = current->domain->ssid;
-
- rc = get_page_sid(page, &tsid);
- if ( rc )
- return rc;
-
- return avc_has_perm(dsec->sid, tsid, SECCLASS_MMU, MMU__PAGEINFO, NULL);
+ return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGEINFO);
}
static int flask_getmemlist(struct domain *d)
@@ -1314,88 +1244,65 @@ static int flask_domain_memory_map(struct domain *d)
return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__MEMORYMAP);
}
-static int flask_mmu_normal_update(struct domain *d, struct domain *t,
- struct domain *f, intpte_t fpte)
+static int domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t pte)
{
int rc = 0;
u32 map_perms = MMU__MAP_READ;
unsigned long fgfn, fmfn;
- struct domain_security_struct *dsec;
- u32 fsid;
- struct avc_audit_data ad;
p2m_type_t p2mt;
- if (d != t)
- rc = domain_has_perm(d, t, SECCLASS_MMU, MMU__REMOTE_REMAP);
- if ( rc )
- return rc;
-
- if ( !(l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_PRESENT) )
+ if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
return 0;
- dsec = d->ssid;
-
- if ( l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_RW )
+ if ( l1e_get_flags(pte) & _PAGE_RW )
map_perms |= MMU__MAP_WRITE;
- AVC_AUDIT_DATA_INIT(&ad, MEMORY);
- fgfn = l1e_get_pfn(l1e_from_intpte(fpte));
+ fgfn = l1e_get_pfn(pte);
fmfn = mfn_x(get_gfn_query(f, fgfn, &p2mt));
-
- ad.sdom = d;
- ad.tdom = f;
- ad.memory.pte = fpte;
- ad.memory.mfn = fmfn;
-
- rc = get_mfn_sid(fmfn, &fsid);
-
put_gfn(f, fgfn);
- if ( rc )
- return rc;
+ if ( f->domain_id == DOMID_IO || !mfn_valid(fmfn) )
+ {
+ struct avc_audit_data ad;
+ struct domain_security_struct *dsec = d->ssid;
+ u32 fsid;
+ AVC_AUDIT_DATA_INIT(&ad, MEMORY);
+ ad.sdom = d;
+ ad.tdom = f;
+ ad.memory.pte = pte.l1;
+ ad.memory.mfn = fmfn;
+ rc = security_iomem_sid(fmfn, &fsid);
+ if ( rc )
+ return rc;
+ return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, &ad);
+ }
- return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, &ad);
+ return domain_has_perm(d, f, SECCLASS_MMU, map_perms);
}
-static int flask_mmu_machphys_update(struct domain *d, unsigned long mfn)
+static int flask_mmu_normal_update(struct domain *d, struct domain *t,
+ struct domain *f, intpte_t fpte)
{
int rc = 0;
- u32 psid;
- struct domain_security_struct *dsec;
- dsec = d->ssid;
- rc = get_mfn_sid(mfn, &psid);
+ if (d != t)
+ rc = domain_has_perm(d, t, SECCLASS_MMU, MMU__REMOTE_REMAP);
if ( rc )
return rc;
- return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, MMU__UPDATEMP, NULL);
+ return domain_memory_perm(d, f, l1e_from_intpte(fpte));
+}
+
+static int flask_mmu_machphys_update(struct domain *d1, struct domain *d2,
+ unsigned long mfn)
+{
+ return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__UPDATEMP);
}
static int flask_update_va_mapping(struct domain *d, struct domain *f,
l1_pgentry_t pte)
{
- int rc = 0;
- u32 psid;
- u32 map_perms = MMU__MAP_READ;
- struct page_info *page = NULL;
- struct domain_security_struct *dsec;
-
- if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
- return 0;
-
- if ( l1e_get_flags(pte) & _PAGE_RW )
- map_perms |= MMU__MAP_WRITE;
-
- dsec = d->ssid;
-
- page = get_page_from_gfn(f, l1e_get_pfn(pte), NULL, P2M_ALLOC);
- rc = get_mfn_sid(page ? page_to_mfn(page) : INVALID_MFN, &psid);
- if ( page )
- put_page(page);
- if ( rc )
- return rc;
-
- return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, map_perms, NULL);
+ return domain_memory_perm(d, f, pte);
}
static int flask_add_to_physmap(struct domain *d1, struct domain *d2)