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

[Xen-devel] [PATCH 13/23] 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>
---
 docs/misc/xsm-flask.txt                      |  43 ++-
 tools/flask/policy/policy/modules/xen/xen.if |  60 +++-
 tools/flask/policy/policy/modules/xen/xen.te |  13 +-
 xen/xsm/flask/flask_op.c                     |   9 +
 xen/xsm/flask/hooks.c                        | 422 +++++++++++++--------------
 xen/xsm/flask/include/objsec.h               |   2 +
 6 files changed, 307 insertions(+), 242 deletions(-)

diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt
index 0778a28..ff81b01 100644
--- a/docs/misc/xsm-flask.txt
+++ b/docs/misc/xsm-flask.txt
@@ -68,9 +68,43 @@ HVM domains with stubdomain device models use two types (one 
per domain):
  - dm_dom_t is the device model for a domain with type domHVM_t
 
 One disadvantage of using type enforcement to enforce isolation is that a new
-type is needed for each group of domains. In addition, it is not possible to
-allow isolated_domU_t cannot to create loopback event channels without allowing
-two domains of type isolated_domU_t to communicate with one another.
+type is needed for each group of domains. The user field can be used to address
+this for the most common case of groups that can communicate internally but not
+externally; see "Users and roles" below.
+
+Type transitions
+----------------
+
+Xen defines a number of operations such as memory mapping that are necessary 
for
+a domain to perform on itself, but are also undesirable to allow a domain to
+perform on every other domain of the same label. While it is possible to 
address
+this by only creating one domain per type, this solution significantly limits
+the flexibility of the type system. Another method to address this issue is to
+duplicate the permission names for every operation that can be performed on the
+current domain or on other domains; however, this significantly increases the
+necessary number of permissions and complicates the XSM hooks. Instead, this is
+addressed by allowing a distinct type to be used for a domain's access to
+itself. The same applies for a device model domain's access to its designated
+target, allowing the IS_PRIV_FOR checks used in Xen's DAC model to be
+implemented in FLASK.
+
+Upon domain creation (or relabel), a type transition is computed using the
+domain's label as the source and target. The result of this computation is used
+as the target when the domain accesses itself. In the example policy, this
+computed type is the result of appending _self to a domain's type: domU_t_self
+for domU_t. If no type transition rule exists, the domain will continue to use
+its own label for both the source and target. An AVC message will look like:
+
+    scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t_self
+
+A similar type transition is done when a device model domain is associated with
+its target using the set_target operation. The transition is computed with the
+target domain as the source and the device model domain as the target: this
+ordering was chosen in order to preserve the original label for the target when
+no type transition rule exists. In the example policy, these computed types are
+the result of appending _target to the domain.
+
+Type transitions are also used to compute the labels of event channels.
 
 Users and roles
 ---------------
@@ -84,7 +118,8 @@ the customer_1 user.
 Access control rules involving users and roles are defined in the policy
 constraints file (tools/flask/policy/policy/constraints). The example policy
 provides constraints that prevent different users from communicating using
-grants or event channels, while still allowing communication with dom0.
+grants or event channels, while still allowing communication with the system_u
+user where dom0 resides.
 
 Resource Policy
 ---------------
diff --git a/tools/flask/policy/policy/modules/xen/xen.if 
b/tools/flask/policy/policy/modules/xen/xen.if
index 59ba171..d630f47 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 cacheattr send_irq };
+       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 send_irq };
+')
+
+# 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;
 ')
 
################################################################################
 #
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 a5d7748..4426ab9 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 dbbf34f..a8475ea 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);
+}
 
-    return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL);
+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(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)
@@ -123,6 +154,7 @@ static int flask_domain_alloc_security(struct domain *d)
         dsec->sid = SECINITSID_UNLABELED;
     }
 
+    dsec->self_sid = dsec->sid;
     d->ssid = dsec;
 
     return 0;
@@ -142,68 +174,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_any_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",
@@ -211,15 +230,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;
 
@@ -302,7 +326,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;
@@ -312,9 +335,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);
@@ -367,12 +388,12 @@ static int flask_grant_query_size(struct domain *d1, 
struct domain *d2)
 
 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)
@@ -455,70 +476,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)
@@ -537,7 +553,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)
@@ -548,43 +564,51 @@ 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)
@@ -655,26 +679,24 @@ static int flask_domctl(struct domain *d, int cmd)
     case XEN_DOMCTL_gdbsx_pausevcpu:
     case XEN_DOMCTL_gdbsx_unpausevcpu:
     case XEN_DOMCTL_gdbsx_domstatus:
-        return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                               DOMAIN__SETDEBUGGING);
+        return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING);
 
     case XEN_DOMCTL_subscribe:
     case XEN_DOMCTL_disable_migrate:
     case XEN_DOMCTL_suppress_spurious_page_faults:
-        return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
-                               DOMAIN__SET_MISC_INFO);
+        return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO);
 
     case XEN_DOMCTL_set_cpuid:
-        return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__SET_CPUID);
+        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID);
 
     case XEN_DOMCTL_gettscinfo:
-        return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__GETTSC);
+        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC);
 
     case XEN_DOMCTL_settscinfo:
-        return domain_has_perm(current->domain, d, SECCLASS_DOMAIN2, 
DOMAIN2__SETTSC);
+        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC);
 
     case XEN_DOMCTL_audit_p2m:
-        return domain_has_perm(current->domain, d, SECCLASS_HVM, 
HVM__AUDIT_P2M);
+        return current_has_perm(d, SECCLASS_HVM, HVM__AUDIT_P2M);
 
     default:
         printk("flask_domctl: Unknown op %d\n", cmd);
@@ -716,7 +738,7 @@ static int flask_sysctl(int cmd)
 
 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)
@@ -741,20 +763,17 @@ 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_keys(void)
@@ -816,14 +835,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;
@@ -839,14 +856,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;
 }
 
@@ -854,16 +870,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;
@@ -873,19 +885,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;
 };
 
@@ -899,12 +911,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)
@@ -912,7 +924,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;
@@ -922,8 +934,8 @@ 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);
 }
@@ -935,10 +947,9 @@ static int flask_iomem_mapping(struct domain *d, uint64_t 
start, uint64_t end, u
 
 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);
@@ -951,33 +962,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)
@@ -985,7 +987,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 )
@@ -993,8 +994,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)
@@ -1002,7 +1002,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 )
@@ -1010,8 +1009,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)
@@ -1019,7 +1017,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 )
@@ -1027,8 +1024,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)
@@ -1036,22 +1032,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)
@@ -1114,11 +1105,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;
 };
 
@@ -1132,12 +1124,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);
 }
 
 static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t 
end, uint8_t access)
@@ -1145,7 +1137,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 )
@@ -1156,8 +1148,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);
 }
@@ -1169,18 +1161,17 @@ static int flask_ioport_mapping(struct domain *d, 
uint32_t start, uint32_t end,
 
 static int flask_getpageframeinfo(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_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)
@@ -1203,7 +1194,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)
@@ -1222,7 +1213,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_machine_address_size(struct domain *d, uint32_t cmd)
@@ -1263,37 +1254,37 @@ 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_hvm_inject_msi(struct domain *d)
 {
-    return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__SEND_IRQ);
+    return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ);
 }
 
 static int flask_mem_event(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_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_apic(struct domain *d, int cmd)
@@ -1355,11 +1346,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_platform_op(uint32_t op)
@@ -1421,16 +1408,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 domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t 
pte)
@@ -1453,17 +1436,17 @@ static int domain_memory_perm(struct domain *d, struct 
domain *f, l1_pgentry_t p
     if ( f->domain_id == DOMID_IO || !mfn_valid(fmfn) )
     {
         struct avc_audit_data ad;
-        struct domain_security_struct *dsec = d->ssid;
-        u32 fsid;
+        u32 dsid, fsid;
+        rc = security_iomem_sid(fmfn, &fsid);
+        if ( rc )
+            return rc;
         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);
+        dsid = domain_sid(d);
+        return avc_has_perm(dsid, fsid, SECCLASS_MMU, map_perms, &ad);
     }
 
     return domain_has_perm(d, f, SECCLASS_MMU, map_perms);
@@ -1506,43 +1489,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;
 
@@ -1552,22 +1532,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;
 
@@ -1575,18 +1553,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;
 
@@ -1596,23 +1573,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)
@@ -1631,7 +1607,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)
@@ -1650,7 +1626,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.7


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