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

[Xen-devel] [PATCH 15/18] xsm/flask: add distinct SIDs for self/target access



Because the FLASK XSM module no longer checks IS_PRIV for remote domain
accesses covered by XSM permissions, domains now have the ability to
perform memory management and other functions on all domains that have
the same type. While it is possible to prevent this by only creating one
domain per type, this solution significantly limits the flexibility of
the type system.

This patch introduces a domain type transition to represent a domain
that is operating on itself. In the example policy, this is demonstrated
by creating a type with _self appended when declaring a domain type
which will be used for reflexive operations. AVCs for a domain of type
domU_t will look like the following:

scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t_self

This change also allows policy to distinguish between event channels a
domain creates to itself and event channels created between domains of
the same type.

The IS_PRIV_FOR check used for device model domains is also no longer
checked by FLASK; a similar transition is performed when the target is
set and used when the device model accesses its target domain.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 tools/flask/policy/policy/modules/xen/xen.if |  64 +++-
 tools/flask/policy/policy/modules/xen/xen.te |  13 +-
 xen/xsm/flask/flask_op.c                     |   9 +
 xen/xsm/flask/hooks.c                        | 470 +++++++++++++--------------
 xen/xsm/flask/include/objsec.h               |   2 +
 5 files changed, 289 insertions(+), 269 deletions(-)

diff --git a/tools/flask/policy/policy/modules/xen/xen.if 
b/tools/flask/policy/policy/modules/xen/xen.if
index f9bd757..796698b 100644
--- a/tools/flask/policy/policy/modules/xen/xen.if
+++ b/tools/flask/policy/policy/modules/xen/xen.if
@@ -5,15 +5,34 @@
 # Domain creation and setup
 #
 
################################################################################
+define(`declare_domain_common', `
+       allow $1 $2:grant { query setup };
+       allow $1 $2:mmu { adjust physmap map_read map_write stat pinpage 
updatemp };
+       allow $1 $2:hvm { getparam setparam };
+')
+
 # declare_domain(type, attrs...)
-#   Declare a type as a domain type, and allow basic domain setup
+#   Declare a domain type, along with associated _self and _channel types
+#   Allow the domain to perform basic operations on itself
 define(`declare_domain', `
        type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)');
+       type $1_self, domain_type, domain_self_type;
+       type_transition $1 $1:domain $1_self;
+       type $1_channel, event_type;
+       type_transition $1 domain_type:event $1_channel;
+       declare_domain_common($1, $1_self)
+')
+
+# declare_singleton_domain(type, attrs...)
+#   Declare a domain type and associated _channel types.
+#   Note: Because the domain can perform basic operations on itself and any
+#   other domain of the same type, this constructor should be used for types
+#   containing at most one domain. This is not enforced by policy.
+define(`declare_singleton_domain', `
+       type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)');
        type $1_channel, event_type;
        type_transition $1 domain_type:event $1_channel;
-       allow $1 $1:grant { query setup };
-       allow $1 $1:mmu { adjust physmap map_read map_write stat pinpage };
-       allow $1 $1:hvm { getparam setparam };
+       declare_domain_common($1, $1)
 ')
 
 # declare_build_label(type)
@@ -51,6 +70,7 @@ define(`create_domain_build_label', `
        allow $1 $2_channel:event create;
        allow $1 $2_building:domain2 relabelfrom;
        allow $1 $2:domain2 relabelto;
+       allow $2_building $2:domain transition;
 ')
 
 # manage_domain(priv, target)
@@ -101,20 +121,36 @@ define(`domain_comms', `
 ')
 
 # domain_self_comms(domain)
-#   Allow a domain types to communicate with others of its type using grants
-#   and event channels (this includes event channels to DOMID_SELF)
+#   Allow a non-singleton domain type to communicate with itself using grants
+#   and event channels
 define(`domain_self_comms', `
-       create_channel($1, $1, $1_channel)
-       allow $1 $1:grant { map_read map_write copy unmap };
+       create_channel($1, $1_self, $1_channel)
+       allow $1 $1_self:grant { map_read map_write copy unmap };
 ')
 
 # device_model(dm_dom, hvm_dom)
 #   Define how a device model domain interacts with its target
 define(`device_model', `
-       domain_comms($1, $2)
-       allow $1 $2:domain { set_target shutdown };
-       allow $1 $2:mmu { map_read map_write adjust physmap };
-       allow $1 $2:hvm { getparam setparam trackdirtyvram hvmctl irqlevel 
pciroute };
+       type $2_target, domain_type, domain_target_type;
+       type_transition $2 $1:domain $2_target;
+       allow $1 $2:domain set_target;
+
+       type_transition $2_target domain_type:event $2_channel;
+       create_channel($1, $2_target, $1_channel)
+       create_channel($2, $1, $2_channel)
+       allow $1 $2_channel:event create;
+
+       allow $1 $2_target:domain shutdown;
+       allow $1 $2_target:mmu { map_read map_write adjust physmap };
+       allow $1 $2_target:hvm { getparam setparam trackdirtyvram hvmctl 
irqlevel pciroute cacheattr };
+')
+
+# make_device_model(priv, dm_dom, hvm_dom)
+#   Allow creation of a device model and HVM domain pair
+define(`make_device_model', `
+       device_model($2, $3)
+       allow $1 $2:domain2 make_priv_for;
+       allow $1 $3:domain2 set_as_target;
 ')
 
################################################################################
 #
@@ -132,7 +168,9 @@ define(`use_device', `
 # admin_device(domain, device)
 #   Allow a device to be used and delegated by a domain
 define(`admin_device', `
-    allow $1 $2:resource { setup stat_device add_device add_irq add_iomem 
add_ioport remove_device remove_irq remove_iomem remove_ioport };
+    allow $1 $2:resource { setup stat_device add_device add_irq add_iomem 
add_ioport
+                              remove_device remove_irq remove_iomem 
remove_ioport
+                                                  plug unplug };
     allow $1 $2:hvm bind_irq;
     use_device($1, $2)
 ')
diff --git a/tools/flask/policy/policy/modules/xen/xen.te 
b/tools/flask/policy/policy/modules/xen/xen.te
index 1162153..8d33285 100644
--- a/tools/flask/policy/policy/modules/xen/xen.te
+++ b/tools/flask/policy/policy/modules/xen/xen.te
@@ -8,6 +8,8 @@
 
################################################################################
 attribute xen_type;
 attribute domain_type;
+attribute domain_self_type;
+attribute domain_target_type;
 attribute resource_type;
 attribute event_type;
 attribute mls_priv;
@@ -25,7 +27,7 @@ attribute mls_priv;
 type xen_t, xen_type, mls_priv;
 
 # Domain 0
-declare_domain(dom0_t, mls_priv);
+declare_singleton_domain(dom0_t, mls_priv);
 
 # Untracked I/O memory (pseudo-domain)
 type domio_t, xen_type;
@@ -69,7 +71,7 @@ admin_device(dom0_t, ioport_t)
 admin_device(dom0_t, iomem_t)
 allow dom0_t domio_t:mmu { map_read map_write };
 
-domain_self_comms(dom0_t)
+domain_comms(dom0_t, dom0_t)
 
 auditallow dom0_t security_t:security { load_policy setenforce setbool };
 
@@ -84,11 +86,14 @@ domain_self_comms(domU_t)
 create_domain(dom0_t, domU_t)
 manage_domain(dom0_t, domU_t)
 domain_comms(dom0_t, domU_t)
+domain_comms(domU_t, domU_t)
+domain_self_comms(domU_t)
 
 declare_domain(isolated_domU_t)
 create_domain(dom0_t, isolated_domU_t)
 manage_domain(dom0_t, isolated_domU_t)
 domain_comms(dom0_t, isolated_domU_t)
+domain_self_comms(isolated_domU_t)
 
 # Declare a boolean that denies creation of prot_domU_t domains
 gen_bool(prot_doms_locked, false)
@@ -98,6 +103,8 @@ if (!prot_doms_locked) {
 }
 domain_comms(dom0_t, prot_domU_t)
 domain_comms(domU_t, prot_domU_t)
+domain_comms(prot_domU_t, prot_domU_t)
+domain_self_comms(prot_domU_t)
 
 # domHVM_t is meant to be paired with a qemu-dm stub domain of type dm_dom_t
 declare_domain(domHVM_t)
@@ -110,7 +117,7 @@ declare_domain(dm_dom_t)
 create_domain(dom0_t, dm_dom_t)
 manage_domain(dom0_t, dm_dom_t)
 domain_comms(dom0_t, dm_dom_t)
-device_model(dm_dom_t, domHVM_t)
+make_device_model(dom0_t, dm_dom_t, domHVM_t)
 
 # nomigrate_t must be built via the nomigrate_t_building label; once built,
 # dom0 cannot read its memory.
diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
index 9c0a087..28f6f5e 100644
--- a/xen/xsm/flask/flask_op.c
+++ b/xen/xsm/flask/flask_op.c
@@ -612,6 +612,15 @@ static int flask_relabel_domain(struct xen_flask_relabel 
*arg)
         goto out;
 
     dsec->sid = arg->sid;
+    dsec->self_sid = arg->sid;
+    security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN,
+                            &dsec->self_sid);
+    if ( d->target )
+    {
+        struct domain_security_struct *tsec = d->target->ssid;
+        security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN,
+                                &dsec->target_sid);
+    }
 
  out:
     rcu_unlock_domain(d);
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index be5c3ad..dae587c 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -33,38 +33,69 @@
 
 struct xsm_operations *original_ops = NULL;
 
+static u32 domain_sid(struct domain *dom)
+{
+    struct domain_security_struct *dsec = dom->ssid;
+    return dsec->sid;
+}
+
+static u32 domain_target_sid(struct domain *src, struct domain *dst)
+{
+    struct domain_security_struct *ssec = src->ssid;
+    struct domain_security_struct *dsec = dst->ssid;
+    if (src == dst)
+        return ssec->self_sid;
+    if (src->target == dst)
+        return ssec->target_sid;
+    return dsec->sid;
+}
+
+static u32 evtchn_sid(const struct evtchn *chn)
+{
+    struct evtchn_security_struct *esec = chn->ssid;
+    return esec->sid;
+}
+
 static int domain_has_perm(struct domain *dom1, struct domain *dom2, 
                            u16 class, u32 perms)
 {
-    struct domain_security_struct *dsec1, *dsec2;
+    u32 ssid, tsid;
     struct avc_audit_data ad;
     AVC_AUDIT_DATA_INIT(&ad, NONE);
     ad.sdom = dom1;
     ad.tdom = dom2;
 
-    dsec1 = dom1->ssid;
-    dsec2 = dom2->ssid;
+    ssid = domain_sid(dom1);
+    tsid = domain_target_sid(dom1, dom2);
 
-    return avc_has_perm(dsec1->sid, dsec2->sid, class, perms, &ad);
+    return avc_has_perm(ssid, tsid, class, perms, &ad);
 }
 
-static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms)
+static int avc_current_has_perm(u32 tsid, u16 class, u32 perm,
+                                struct avc_audit_data *ad)
 {
-    struct domain_security_struct *dsec;
-    struct evtchn_security_struct *esec;
+    u32 csid = domain_sid(current->domain);
+    return avc_has_perm(csid, tsid, class, perm, ad);
+}
 
-    dsec = d->ssid;
-    esec = chn->ssid;
+static int current_has_perm(struct domain *d, u16 class, u32 perms)
+{
+    return domain_has_perm(current->domain, d, class, perms);
+}
+
+static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms)
+{
+    u32 dsid = domain_sid(d);
+    u32 esid = evtchn_sid(chn);
 
-    return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL);
+    return avc_has_perm(dsid, esid, SECCLASS_EVENT, perms, NULL);
 }
 
 static int domain_has_xen(struct domain *d, u32 perms)
 {
-    struct domain_security_struct *dsec;
-    dsec = d->ssid;
+    u32 dsid = domain_sid(d);
 
-    return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL);
+    return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL);
 }
 
 static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad)
@@ -109,14 +140,11 @@ static int flask_domain_alloc_security(struct domain *d)
     memset(dsec, 0, sizeof(struct domain_security_struct));
 
     if ( is_idle_domain(d) )
-    {
         dsec->sid = SECINITSID_XEN;
-    }
     else
-    {
         dsec->sid = SECINITSID_UNLABELED;
-    }
 
+    dsec->self_sid = dsec->sid;
     d->ssid = dsec;
 
     return 0;
@@ -136,68 +164,55 @@ static void flask_domain_free_security(struct domain *d)
 static int flask_evtchn_unbound(struct domain *d1, struct evtchn *chn, 
                                 domid_t id2)
 {
-    u32 newsid;
+    u32 sid1, sid2, newsid;
     int rc;
-    domid_t id;
     struct domain *d2;
-    struct domain_security_struct *dsec, *dsec1, *dsec2;
     struct evtchn_security_struct *esec;
 
-    dsec = current->domain->ssid;
-    dsec1 = d1->ssid;
-    esec = chn->ssid;
-
-    if ( id2 == DOMID_SELF )
-        id = current->domain->domain_id;
-    else
-        id = id2;
-
-    d2 = get_domain_by_id(id);
+    d2 = rcu_lock_domain_by_id(id2);
     if ( d2 == NULL )
         return -EPERM;
 
-    dsec2 = d2->ssid;
-    rc = security_transition_sid(dsec1->sid, dsec2->sid, SECCLASS_EVENT, 
-                                 &newsid);
+    sid1 = domain_sid(d1);
+    sid2 = domain_target_sid(d1, d2);
+    esec = chn->ssid;
+
+    rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid);
     if ( rc )
         goto out;
 
-    rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, NULL);
+    rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, NULL);
     if ( rc )
         goto out;
 
-    rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL);
+    rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, NULL);
     if ( rc )
         goto out;
-    else
-        esec->sid = newsid;
+
+    esec->sid = newsid;
 
  out:
-    put_domain(d2);
+    rcu_unlock_domain(d2);
     return rc;
 }
 
 static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1, 
                                     struct domain *d2, struct evtchn *chn2)
 {
-    u32 newsid;
+    u32 sid1, sid2, newsid, reverse_sid;
     int rc;
-    struct domain_security_struct *dsec, *dsec1, *dsec2;
-    struct evtchn_security_struct *esec1, *esec2;
+    struct evtchn_security_struct *esec1;
     struct avc_audit_data ad;
     AVC_AUDIT_DATA_INIT(&ad, NONE);
     ad.sdom = d1;
     ad.tdom = d2;
 
-    dsec = current->domain->ssid;
-    dsec1 = d1->ssid;
-    dsec2 = d2->ssid;
+    sid1 = domain_sid(d1);
+    sid2 = domain_target_sid(d1, d2);
 
     esec1 = chn1->ssid;
-    esec2 = chn2->ssid;
 
-    rc = security_transition_sid(dsec1->sid, dsec2->sid, 
-                                 SECCLASS_EVENT, &newsid);
+    rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid);
     if ( rc )
     {
         printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n",
@@ -205,15 +220,20 @@ static int flask_evtchn_interdomain(struct domain *d1, 
struct evtchn *chn1,
         return rc;
     }
 
-    rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, &ad);
+    rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, &ad);
     if ( rc )
         return rc;
 
-    rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, &ad);
+    rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, &ad);
     if ( rc )
         return rc;
 
-    rc = avc_has_perm(esec2->sid, dsec1->sid, SECCLASS_EVENT, EVENT__BIND, 
&ad);
+    /* It's possible the target domain has changed (relabel or destroy/create)
+     * since the unbound part was created; re-validate this binding now.
+     */
+    reverse_sid = evtchn_sid(chn2);
+    sid1 = domain_target_sid(d2, d1);
+    rc = avc_has_perm(reverse_sid, sid1, SECCLASS_EVENT, EVENT__BIND, &ad);
     if ( rc )
         return rc;
 
@@ -296,7 +316,6 @@ static void flask_free_security_evtchn(struct evtchn *chn)
 
 static char *flask_show_security_evtchn(struct domain *d, const struct evtchn 
*chn)
 {
-    struct evtchn_security_struct *esec;
     int irq;
     u32 sid = 0;
     char *ctx;
@@ -306,9 +325,7 @@ static char *flask_show_security_evtchn(struct domain *d, 
const struct evtchn *c
     {
     case ECS_UNBOUND:
     case ECS_INTERDOMAIN:
-        esec = chn->ssid;
-        if ( esec )
-            sid = esec->sid;
+        sid = evtchn_sid(chn);
         break;
     case ECS_PIRQ:
         irq = domain_pirq_to_irq(d, chn->u.pirq.irq);
@@ -359,11 +376,10 @@ 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)
+static int get_page_sid(struct domain *who, 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);
@@ -389,15 +405,14 @@ static int get_page_sid(struct page_info *page, u32 *sid)
 
     default:
         /*Pages are implicitly labeled by domain ownership!*/
-        dsec = d->ssid;
-        *sid = dsec ? dsec->sid : SECINITSID_UNLABELED;
+        *sid = domain_target_sid(who, d);
         break;
     }
 
     return rc;
 }
 
-static int get_mfn_sid(unsigned long mfn, u32 *sid)
+static int get_mfn_sid(struct domain *who, unsigned long mfn, u32 *sid)
 {
     int rc = 0;
     struct page_info *page;
@@ -406,7 +421,7 @@ static int get_mfn_sid(unsigned long mfn, u32 *sid)
     {
         /*mfn is valid if this is a page that Xen is tracking!*/
         page = mfn_to_page(mfn);
-        rc = get_page_sid(page, sid);
+        rc = get_page_sid(who, page, sid);
     }
     else
     {
@@ -419,12 +434,12 @@ static int get_mfn_sid(unsigned long mfn, u32 *sid)
 
 static int flask_get_pod_target(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__GETPODTARGET);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET);
 }
 
 static int flask_set_pod_target(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__SETPODTARGET);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET);
 }
 
 static int flask_memory_adjust_reservation(struct domain *d1, struct domain 
*d2)
@@ -440,15 +455,14 @@ static int flask_memory_stat_reservation(struct domain 
*d1, struct domain *d2)
 static int flask_memory_pin_page(struct domain *d, struct page_info *page)
 {
     int rc = 0;
-    u32 sid;
-    struct domain_security_struct *dsec;
-    dsec = d->ssid;
+    u32 dsid, psid;
+    dsid = domain_sid(d);
 
-    rc = get_page_sid(page, &sid);
+    rc = get_page_sid(d, page, &psid);
     if ( rc )
         return rc;
 
-    return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__PINPAGE, NULL);
+    return avc_has_perm(dsid, psid, SECCLASS_MMU, MMU__PINPAGE, NULL);
 }
 
 static int flask_console_io(struct domain *d, int cmd)
@@ -515,70 +529,65 @@ static int flask_schedop_shutdown(struct domain *d1, 
struct domain *d2)
 static void flask_security_domaininfo(struct domain *d, 
                                       struct xen_domctl_getdomaininfo *info)
 {
-    struct domain_security_struct *dsec;
-
-    dsec = d->ssid;
-    info->ssidref = dsec->sid;
+    info->ssidref = domain_sid(d);
 }
 
 static int flask_setvcpucontext(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
-                           DOMAIN__SETVCPUCONTEXT);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT);
 }
 
 static int flask_pausedomain(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__PAUSE);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__PAUSE);
 }
 
 static int flask_unpausedomain(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__UNPAUSE);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE);
 }
 
 static int flask_resumedomain(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__RESUME);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME);
 }
 
 static int flask_domain_create(struct domain *d, u32 ssidref)
 {
     int rc;
-    struct domain_security_struct *dsec1;
-    struct domain_security_struct *dsec2;
+    struct domain_security_struct *dsec = d->ssid;
     static int dom0_created = 0;
 
-    dsec1 = current->domain->ssid;
-    dsec2 = d->ssid;
-
     if ( is_idle_domain(current->domain) && !dom0_created )
     {
-        dsec2->sid = SECINITSID_DOM0;
+        dsec->sid = SECINITSID_DOM0;
         dom0_created = 1;
-        return 0;
     }
+    else
+    {
+        rc = avc_current_has_perm(ssidref, SECCLASS_DOMAIN,
+                          DOMAIN__CREATE, NULL);
+        if ( rc )
+            return rc;
 
-    rc = avc_has_perm(dsec1->sid, ssidref, SECCLASS_DOMAIN,
-                      DOMAIN__CREATE, NULL);
-    if ( rc )
-        return rc;
+        dsec->sid = ssidref;
+    }
+    dsec->self_sid = dsec->sid;
 
-    dsec2->sid = ssidref;
+    rc = security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN,
+                                 &dsec->self_sid);
 
     return rc;
 }
 
 static int flask_max_vcpus(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
-                           DOMAIN__MAX_VCPUS);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS);
 }
 
 static int flask_destroydomain(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
-                           DOMAIN__DESTROY);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY);
 }
 
 static int flask_vcpuaffinity(int cmd, struct domain *d)
@@ -597,7 +606,7 @@ static int flask_vcpuaffinity(int cmd, struct domain *d)
         return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm );
+    return current_has_perm(d, SECCLASS_DOMAIN, perm );
 }
 
 static int flask_scheduler(struct domain *d)
@@ -608,53 +617,61 @@ static int flask_scheduler(struct domain *d)
     if ( rc )
         return rc;
 
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
-                           DOMAIN__SCHEDULER);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SCHEDULER);
 }
 
 static int flask_getdomaininfo(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__GETDOMAININFO);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO);
 }
 
 static int flask_getvcpucontext(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
-                           DOMAIN__GETVCPUCONTEXT);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT);
 }
 
 static int flask_getvcpuinfo(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__GETVCPUINFO);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO);
 }
 
 static int flask_domain_settime(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__SETTIME);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETTIME);
 }
 
-static int flask_set_target(struct domain *d, struct domain *e)
+static int flask_set_target(struct domain *d, struct domain *t)
 {
     int rc;
-    rc = domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__MAKE_PRIV_FOR);
+    struct domain_security_struct *dsec, *tsec;
+    dsec = d->ssid;
+    tsec = t->ssid;
+
+    rc = current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__MAKE_PRIV_FOR);
     if ( rc )
         return rc;
-    rc = domain_has_perm(current->domain, e, SECCLASS_DOMAIN2, 
DOMAIN2__SET_AS_TARGET);
+    rc = current_has_perm(t, SECCLASS_DOMAIN2, DOMAIN2__SET_AS_TARGET);
     if ( rc )
         return rc;
-    return domain_has_perm(d, e, SECCLASS_DOMAIN, DOMAIN__SET_TARGET);
+    /* Use avc_has_perm to avoid resolving target/current SID */
+    rc = avc_has_perm(dsec->sid, tsec->sid, SECCLASS_DOMAIN, 
DOMAIN__SET_TARGET, NULL);
+    if ( rc )
+        return rc;
+
+    /* (tsec, dsec) defaults the label to tsec, as it should here */
+    rc = security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN,
+                                 &dsec->target_sid);
+    return rc;
 }
 
 static int flask_domctl(struct domain *d, int cmd)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__SET_MISC_INFO);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO);
 }
 
 static int flask_set_virq_handler(struct domain *d, uint32_t virq)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__SET_VIRQ_HANDLER);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER);
 }
 
 static int flask_tbufcontrol(void)
@@ -679,26 +696,22 @@ static int flask_sched_id(void)
 
 static int flask_setdomainmaxmem(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__SETDOMAINMAXMEM);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM);
 }
 
 static int flask_setdomainhandle(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__SETDOMAINHANDLE);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE);
 }
 
 static int flask_setdebugging(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__SETDEBUGGING);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING);
 }
 
 static int flask_debug_op(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__SETDEBUGGING);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING);
 }
 
 static int flask_debug_keys(void)
@@ -760,14 +773,12 @@ static char *flask_show_irq_sid (int irq)
 
 static int flask_map_domain_pirq (struct domain *d, int irq, void *data)
 {
-    u32 sid;
+    u32 sid, dsid;
     int rc = -EPERM;
     struct msi_info *msi = data;
-
-    struct domain_security_struct *ssec, *tsec;
     struct avc_audit_data ad;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD);
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
 
     if ( rc )
         return rc;
@@ -783,14 +794,13 @@ static int flask_map_domain_pirq (struct domain *d, int 
irq, void *data)
     if ( rc )
         return rc;
 
-    ssec = current->domain->ssid;
-    tsec = d->ssid;
+    dsid = domain_sid(d);
 
-    rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, 
&ad);
+    rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, &ad);
     if ( rc )
         return rc;
 
-    rc = avc_has_perm(tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
+    rc = avc_has_perm(dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
     return rc;
 }
 
@@ -798,16 +808,12 @@ static int flask_unmap_domain_pirq (struct domain *d, int 
irq)
 {
     u32 sid;
     int rc = -EPERM;
-
-    struct domain_security_struct *ssec;
     struct avc_audit_data ad;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, 
RESOURCE__REMOVE);
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
     if ( rc )
         return rc;
 
-    ssec = current->domain->ssid;
-
     if ( irq >= nr_irqs_gsi ) {
         /* TODO support for MSI here */
         return 0;
@@ -817,19 +823,19 @@ static int flask_unmap_domain_pirq (struct domain *d, int 
irq)
     if ( rc )
         return rc;
 
-    rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, 
&ad);
+    rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, 
&ad);
     return rc;
 }
 
 static int flask_irq_permission (struct domain *d, int pirq, uint8_t access)
 {
     /* the PIRQ number is not useful; real IRQ is checked during mapping */
-    return domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
-                           resource_to_perm(access));
+    return current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access));
 }
 
 struct iomem_has_perm_data {
-    struct domain_security_struct *ssec, *tsec;
+    u32 ssid;
+    u32 dsid;
     u32 perm;
 };
 
@@ -843,12 +849,12 @@ static int _iomem_has_perm(void *v, u32 sid, unsigned 
long start, unsigned long
     ad.range.start = start;
     ad.range.end = end;
 
-    rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, 
&ad);
+    rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad);
 
     if ( rc )
         return rc;
 
-    return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, 
RESOURCE__USE, &ad);
+    return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, 
&ad);
 }
 
 static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t 
end, uint8_t access)
@@ -856,7 +862,7 @@ static int flask_iomem_permission(struct domain *d, 
uint64_t start, uint64_t end
     struct iomem_has_perm_data data;
     int rc;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
+    rc = current_has_perm(d, SECCLASS_RESOURCE,
                          resource_to_perm(access));
     if ( rc )
         return rc;
@@ -866,18 +872,17 @@ static int flask_iomem_permission(struct domain *d, 
uint64_t start, uint64_t end
     else
         data.perm = RESOURCE__REMOVE_IOMEM;
 
-    data.ssec = current->domain->ssid;
-    data.tsec = d->ssid;
+    data.ssid = domain_sid(current->domain);
+    data.dsid = domain_sid(d);
 
     return security_iterate_iomem_sids(start, end, _iomem_has_perm, &data);
 }
 
 static int flask_pci_config_permission(struct domain *d, uint32_t machine_bdf, 
uint16_t start, uint16_t end, uint8_t access)
 {
-    u32 rsid;
+    u32 dsid, rsid;
     int rc = -EPERM;
     struct avc_audit_data ad;
-    struct domain_security_struct *ssec;
     u32 perm = RESOURCE__USE;
 
     rc = security_device_sid(machine_bdf, &rsid);
@@ -890,33 +895,24 @@ static int flask_pci_config_permission(struct domain *d, 
uint32_t machine_bdf, u
 
     AVC_AUDIT_DATA_INIT(&ad, DEV);
     ad.device = (unsigned long) machine_bdf;
-    ssec = d->ssid;
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, &ad);
+    dsid = domain_sid(d);
+    return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, perm, &ad);
 
 }
 
 static int flask_resource_plug_core(void)
 {
-    struct domain_security_struct *ssec;
-
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__PLUG, NULL);
+    return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__PLUG, NULL);
 }
 
 static int flask_resource_unplug_core(void)
 {
-    struct domain_security_struct *ssec;
-
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__UNPLUG, NULL);
+    return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__UNPLUG, NULL);
 }
 
 static int flask_resource_use_core(void)
 {
-    struct domain_security_struct *ssec;
-
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__USE, NULL);
+    return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, 
RESOURCE__USE, NULL);
 }
 
 static int flask_resource_plug_pci(uint32_t machine_bdf)
@@ -924,7 +920,6 @@ static int flask_resource_plug_pci(uint32_t machine_bdf)
     u32 rsid;
     int rc = -EPERM;
     struct avc_audit_data ad;
-    struct domain_security_struct *ssec;
 
     rc = security_device_sid(machine_bdf, &rsid);
     if ( rc )
@@ -932,8 +927,7 @@ static int flask_resource_plug_pci(uint32_t machine_bdf)
 
     AVC_AUDIT_DATA_INIT(&ad, DEV);
     ad.device = (unsigned long) machine_bdf;
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, 
&ad);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, &ad);
 }
 
 static int flask_resource_unplug_pci(uint32_t machine_bdf)
@@ -941,7 +935,6 @@ static int flask_resource_unplug_pci(uint32_t machine_bdf)
     u32 rsid;
     int rc = -EPERM;
     struct avc_audit_data ad;
-    struct domain_security_struct *ssec;
 
     rc = security_device_sid(machine_bdf, &rsid);
     if ( rc )
@@ -949,8 +942,7 @@ static int flask_resource_unplug_pci(uint32_t machine_bdf)
 
     AVC_AUDIT_DATA_INIT(&ad, DEV);
     ad.device = (unsigned long) machine_bdf;
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, 
&ad);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, 
&ad);
 }
 
 static int flask_resource_setup_pci(uint32_t machine_bdf)
@@ -958,7 +950,6 @@ static int flask_resource_setup_pci(uint32_t machine_bdf)
     u32 rsid;
     int rc = -EPERM;
     struct avc_audit_data ad;
-    struct domain_security_struct *ssec;
 
     rc = security_device_sid(machine_bdf, &rsid);
     if ( rc )
@@ -966,8 +957,7 @@ static int flask_resource_setup_pci(uint32_t machine_bdf)
 
     AVC_AUDIT_DATA_INIT(&ad, DEV);
     ad.device = (unsigned long) machine_bdf;
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, 
&ad);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad);
 }
 
 static int flask_resource_setup_gsi(int gsi)
@@ -975,22 +965,17 @@ static int flask_resource_setup_gsi(int gsi)
     u32 rsid;
     int rc = -EPERM;
     struct avc_audit_data ad;
-    struct domain_security_struct *ssec;
 
     rc = get_irq_sid(gsi, &rsid, &ad);
     if ( rc )
         return rc;
 
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, 
&ad);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad);
 }
 
 static int flask_resource_setup_misc(void)
 {
-    struct domain_security_struct *ssec;
-
-    ssec = current->domain->ssid;
-    return avc_has_perm(ssec->sid, SECINITSID_XEN, SECCLASS_RESOURCE, 
RESOURCE__SETUP, NULL);
+    return avc_current_has_perm(SECINITSID_XEN, SECCLASS_RESOURCE, 
RESOURCE__SETUP, NULL);
 }
 
 static inline int flask_page_offline(uint32_t cmd)
@@ -1058,11 +1043,12 @@ static int flask_shadow_control(struct domain *d, 
uint32_t op)
         return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_SHADOW, perm);
+    return current_has_perm(d, SECCLASS_SHADOW, perm);
 }
 
 struct ioport_has_perm_data {
-    struct domain_security_struct *ssec, *tsec;
+    u32 ssid;
+    u32 dsid;
     u32 perm;
 };
 
@@ -1076,12 +1062,12 @@ static int _ioport_has_perm(void *v, u32 sid, unsigned 
long start, unsigned long
     ad.range.start = start;
     ad.range.end = end;
 
-    rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, 
&ad);
+    rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad);
 
     if ( rc )
         return rc;
 
-    return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, 
RESOURCE__USE, &ad);
+    return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, 
&ad);
 }
 
 
@@ -1090,7 +1076,7 @@ static int flask_ioport_permission(struct domain *d, 
uint32_t start, uint32_t en
     int rc;
     struct ioport_has_perm_data data;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
+    rc = current_has_perm(d, SECCLASS_RESOURCE,
                          resource_to_perm(access));
 
     if ( rc )
@@ -1101,8 +1087,8 @@ static int flask_ioport_permission(struct domain *d, 
uint32_t start, uint32_t en
     else
         data.perm = RESOURCE__REMOVE_IOPORT;
 
-    data.ssec = current->domain->ssid;
-    data.tsec = d->ssid;
+    data.ssid = domain_sid(current->domain);
+    data.dsid = domain_sid(d);
 
     return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data);
 }
@@ -1111,46 +1097,42 @@ static int flask_getpageframeinfo(struct page_info 
*page)
 {
     int rc = 0;
     u32 tsid;
-    struct domain_security_struct *dsec;
-
-    dsec = current->domain->ssid;
 
-    rc = get_page_sid(page, &tsid);
+    rc = get_page_sid(current->domain, page, &tsid);
     if ( rc )
         return rc;
 
-    return avc_has_perm(dsec->sid, tsid, SECCLASS_MMU, MMU__PAGEINFO, NULL);   
 
+    return avc_current_has_perm(tsid, SECCLASS_MMU, MMU__PAGEINFO, NULL);
 }
 
 static int flask_getpageframeinfo_domain(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGEINFO);
+    return current_has_perm(d, SECCLASS_MMU, MMU__PAGEINFO);
 }
 
 static int flask_set_cpuid(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__SET_CPUID);
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID);
 }
 
 static int flask_gettscinfo(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__GETTSC);
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC);
 }
 
 static int flask_settscinfo(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__SETTSC);
+    return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC);
 }
 
 static int flask_getmemlist(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGELIST);
+    return current_has_perm(d, SECCLASS_MMU, MMU__PAGELIST);
 }
 
 static int flask_hypercall_init(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                           DOMAIN__HYPERCALL);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__HYPERCALL);
 }
 
 static int flask_hvmcontext(struct domain *d, uint32_t cmd)
@@ -1173,7 +1155,7 @@ static int flask_hvmcontext(struct domain *d, uint32_t 
cmd)
         return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, perm);
+    return current_has_perm(d, SECCLASS_HVM, perm);
 }
 
 static int flask_address_size(struct domain *d, uint32_t cmd)
@@ -1192,7 +1174,7 @@ static int flask_address_size(struct domain *d, uint32_t 
cmd)
         return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm);
+    return current_has_perm(d, SECCLASS_DOMAIN, perm);
 }
 
 static int flask_hvm_param(struct domain *d, unsigned long op)
@@ -1214,47 +1196,47 @@ static int flask_hvm_param(struct domain *d, unsigned 
long op)
         perm = HVM__HVMCTL;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, perm);
+    return current_has_perm(d, SECCLASS_HVM, perm);
 }
 
 static int flask_hvm_set_pci_intx_level(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCILEVEL);
+    return current_has_perm(d, SECCLASS_HVM, HVM__PCILEVEL);
 }
 
 static int flask_hvm_set_isa_irq_level(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__IRQLEVEL);
+    return current_has_perm(d, SECCLASS_HVM, HVM__IRQLEVEL);
 }
 
 static int flask_hvm_set_pci_link_route(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCIROUTE);
+    return current_has_perm(d, SECCLASS_HVM, HVM__PCIROUTE);
 }
 
 static int flask_mem_event_setup(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT);
+    return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT);
 }
 
 static int flask_mem_event_control(struct domain *d, int mode, int op)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT);
+    return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT);
 }
 
 static int flask_mem_event_op(struct domain *d, int op)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT);
+    return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT);
 }
 
 static int flask_mem_sharing(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_SHARING);
+    return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING);
 }
 
 static int flask_mem_sharing_op(struct domain *d, struct domain *cd, int op)
 {
-    int rc = domain_has_perm(current->domain, cd, SECCLASS_HVM, 
HVM__MEM_SHARING);
+    int rc = current_has_perm(cd, SECCLASS_HVM, HVM__MEM_SHARING);
     if ( rc )
         return rc;
     return domain_has_perm(d, cd, SECCLASS_HVM, HVM__SHARE_MEM);
@@ -1262,7 +1244,7 @@ static int flask_mem_sharing_op(struct domain *d, struct 
domain *cd, int op)
 
 static int flask_audit_p2m(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__AUDIT_P2M);
+    return current_has_perm(d, SECCLASS_HVM, HVM__AUDIT_P2M);
 }
 
 static int flask_apic(struct domain *d, int cmd)
@@ -1323,11 +1305,7 @@ static int flask_physinfo(void)
 
 static int flask_platform_quirk(uint32_t quirk)
 {
-    struct domain_security_struct *dsec;
-    dsec = current->domain->ssid;
-
-    return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, 
-                        XEN__QUIRK, NULL);
+    return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN, XEN__QUIRK, 
NULL);
 }
 
 static int flask_firmware_info(void)
@@ -1357,16 +1335,12 @@ static int flask_getidletime(void)
 
 static int flask_machine_memory_map(void)
 {
-    struct domain_security_struct *dsec;
-    dsec = current->domain->ssid;
-
-    return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_MMU, 
-                        MMU__MEMORYMAP, NULL);
+    return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, 
NULL);
 }
 
 static int flask_domain_memory_map(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__MEMORYMAP);
+    return current_has_perm(d, SECCLASS_MMU, MMU__MEMORYMAP);
 }
 
 static int flask_mmu_normal_update(struct domain *d, struct domain *t,
@@ -1375,8 +1349,7 @@ static int flask_mmu_normal_update(struct domain *d, 
struct domain *t,
     int rc = 0;
     u32 map_perms = MMU__MAP_READ;
     unsigned long fgfn, fmfn;
-    struct domain_security_struct *dsec;
-    u32 fsid;
+    u32 dsid, fsid;
     struct avc_audit_data ad;
     p2m_type_t p2mt;
 
@@ -1388,7 +1361,7 @@ static int flask_mmu_normal_update(struct domain *d, 
struct domain *t,
     if ( !(l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_PRESENT) )
         return 0;
 
-    dsec = d->ssid;
+    dsid = domain_sid(d);
 
     if ( l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_RW )
         map_perms |= MMU__MAP_WRITE;
@@ -1402,37 +1375,35 @@ static int flask_mmu_normal_update(struct domain *d, 
struct domain *t,
     ad.memory.pte = fpte;
     ad.memory.mfn = fmfn;
 
-    rc = get_mfn_sid(fmfn, &fsid);
+    rc = get_mfn_sid(d, fmfn, &fsid);
 
     put_gfn(f, fgfn);
 
     if ( rc )
         return rc;
 
-    return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, &ad);
+    return avc_has_perm(dsid, fsid, SECCLASS_MMU, map_perms, &ad);
 }
 
 static int flask_mmu_machphys_update(struct domain *d, unsigned long mfn)
 {
     int rc = 0;
-    u32 psid;
-    struct domain_security_struct *dsec;
-    dsec = d->ssid;
+    u32 dsid, psid;
+    dsid = domain_sid(d);
 
-    rc = get_mfn_sid(mfn, &psid);
+    rc = get_mfn_sid(d, mfn, &psid);
     if ( rc )
         return rc;
 
-    return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, MMU__UPDATEMP, NULL);
+    return avc_has_perm(dsid, psid, SECCLASS_MMU, MMU__UPDATEMP, NULL);
 }
 
 static int flask_update_va_mapping(struct domain *d, struct domain *f,
                                    l1_pgentry_t pte)
 {
     int rc = 0;
-    u32 psid;
+    u32 dsid, psid;
     u32 map_perms = MMU__MAP_READ;
-    struct domain_security_struct *dsec;
     unsigned long fgfn, fmfn;
     p2m_type_t p2mt;
 
@@ -1442,16 +1413,16 @@ static int flask_update_va_mapping(struct domain *d, 
struct domain *f,
     if ( l1e_get_flags(pte) & _PAGE_RW )
         map_perms |= MMU__MAP_WRITE;
 
-    dsec = d->ssid;
+    dsid = domain_sid(d);
     fgfn = l1e_get_pfn(pte);
     fmfn = mfn_x(get_gfn_query(f, fgfn, &p2mt));
-    rc = get_mfn_sid(fmfn, &psid);
+    rc = get_mfn_sid(d, fmfn, &psid);
     put_gfn(f, fgfn);
 
     if ( rc )
         return rc;
 
-    return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, map_perms, NULL);
+    return avc_has_perm(dsid, psid, SECCLASS_MMU, map_perms, NULL);
 }
 
 static int flask_add_to_physmap(struct domain *d1, struct domain *d2)
@@ -1466,43 +1437,40 @@ static int flask_remove_from_physmap(struct domain *d1, 
struct domain *d2)
 
 static int flask_sendtrigger(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, 
DOMAIN__TRIGGER);
+    return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER);
 }
 
 static int flask_get_device_group(uint32_t machine_bdf)
 {
     u32 rsid;
     int rc = -EPERM;
-    struct domain_security_struct *ssec = current->domain->ssid;
 
     rc = security_device_sid(machine_bdf, &rsid);
     if ( rc )
         return rc;
 
-    return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, 
RESOURCE__STAT_DEVICE, NULL);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, 
RESOURCE__STAT_DEVICE, NULL);
 }
 
 static int flask_test_assign_device(uint32_t machine_bdf)
 {
     u32 rsid;
     int rc = -EPERM;
-    struct domain_security_struct *ssec = current->domain->ssid;
 
     rc = security_device_sid(machine_bdf, &rsid);
     if ( rc )
         return rc;
 
-    return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, 
RESOURCE__STAT_DEVICE, NULL);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, 
RESOURCE__STAT_DEVICE, NULL);
 }
 
 static int flask_assign_device(struct domain *d, uint32_t machine_bdf)
 {
-    u32 rsid;
+    u32 dsid, rsid;
     int rc = -EPERM;
-    struct domain_security_struct *ssec, *tsec;
     struct avc_audit_data ad;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD);
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
     if ( rc )
         return rc;
 
@@ -1512,22 +1480,20 @@ static int flask_assign_device(struct domain *d, 
uint32_t machine_bdf)
 
     AVC_AUDIT_DATA_INIT(&ad, DEV);
     ad.device = (unsigned long) machine_bdf;
-    ssec = current->domain->ssid;
-    rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, 
RESOURCE__ADD_DEVICE, &ad);
+    rc = avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, 
&ad);
     if ( rc )
         return rc;
 
-    tsec = d->ssid;
-    return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, 
&ad);
+    dsid = domain_sid(d);
+    return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
 }
 
 static int flask_deassign_device(struct domain *d, uint32_t machine_bdf)
 {
     u32 rsid;
     int rc = -EPERM;
-    struct domain_security_struct *ssec = current->domain->ssid;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, 
RESOURCE__REMOVE);
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
     if ( rc )
         return rc;
 
@@ -1535,18 +1501,17 @@ static int flask_deassign_device(struct domain *d, 
uint32_t machine_bdf)
     if ( rc )
         return rc;
 
-    return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, 
RESOURCE__REMOVE_DEVICE, NULL);
+    return avc_current_has_perm(rsid, SECCLASS_RESOURCE, 
RESOURCE__REMOVE_DEVICE, NULL);
 }
 
 static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq 
*bind)
 {
-    u32 rsid;
+    u32 dsid, rsid;
     int rc = -EPERM;
     int irq;
-    struct domain_security_struct *ssec, *tsec;
     struct avc_audit_data ad;
 
-    rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD);
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
     if ( rc )
         return rc;
 
@@ -1556,23 +1521,22 @@ static int flask_bind_pt_irq (struct domain *d, struct 
xen_domctl_bind_pt_irq *b
     if ( rc )
         return rc;
 
-    ssec = current->domain->ssid;
-    rc = avc_has_perm(ssec->sid, rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
+    rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
     if ( rc )
         return rc;
 
-    tsec = d->ssid;
-    return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, 
&ad);
+    dsid = domain_sid(d);
+    return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
 }
 
 static int flask_unbind_pt_irq (struct domain *d, struct 
xen_domctl_bind_pt_irq *bind)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, 
RESOURCE__REMOVE);
+    return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
 }
 
 static int flask_pin_mem_cacheattr (struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__CACHEATTR);
+    return current_has_perm(d, SECCLASS_HVM, HVM__CACHEATTR);
 }
 
 static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd)
@@ -1591,7 +1555,7 @@ static int flask_ext_vcpucontext (struct domain *d, 
uint32_t cmd)
         return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm);
+    return current_has_perm(d, SECCLASS_DOMAIN, perm);
 }
 
 static int flask_vcpuextstate (struct domain *d, uint32_t cmd)
@@ -1610,7 +1574,7 @@ static int flask_vcpuextstate (struct domain *d, uint32_t 
cmd)
             return -EPERM;
     }
 
-    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm);
+    return current_has_perm(d, SECCLASS_DOMAIN, perm);
 }
 #endif
 
diff --git a/xen/xsm/flask/include/objsec.h b/xen/xsm/flask/include/objsec.h
index 4ff52be..6595dc3 100644
--- a/xen/xsm/flask/include/objsec.h
+++ b/xen/xsm/flask/include/objsec.h
@@ -19,6 +19,8 @@
 
 struct domain_security_struct {
     u32 sid;               /* current SID */
+    u32 self_sid;          /* SID for target when operating on DOMID_SELF */
+    u32 target_sid;        /* SID for device model target domain */
 };
 
 struct evtchn_security_struct {
-- 
1.7.11.2


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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