xsm: expose context of event channel peers
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>
Wed, 29 Feb 2012 13:48:41 +0000 (13:48 +0000)
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>
Wed, 29 Feb 2012 13:48:41 +0000 (13:48 +0000)
This hypercall allows a domain to identify the security context of a
domain that it is communicating with using the interdomain event
channel that it is using for the communication. This can be used to
augment Xen's security permissions with intra-domain security checks.

Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Committed-by: Keir Fraser <keir@xen.org>
xen/common/event_channel.c
xen/include/public/xsm/flask_op.h
xen/include/xen/event.h
xen/xsm/flask/flask_op.c

index c69d2c753e10af2e274401cf306335225ccbbb6e..17ccb84ad2f0c28c2cb1fdef671493e0f4d4d1f2 100644 (file)
 #include <public/event_channel.h>
 #include <xsm/xsm.h>
 
-#define bucket_from_port(d,p) \
-    ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
-#define port_is_valid(d,p)    \
-    (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \
-     (bucket_from_port(d,p) != NULL))
-#define evtchn_from_port(d,p) \
-    (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
-
 #define ERROR_EXIT(_errno)                                          \
     do {                                                            \
         gdprintk(XENLOG_WARNING,                                    \
index 83dcd9930aa52c32653404f8b58d6ec7453e38a2..1a251c9e0130d4c3fa11e7153ca82e1ea164682d 100644 (file)
@@ -135,6 +135,13 @@ struct xen_flask_ocontext {
     uint64_t low, high;
 };
 
+struct xen_flask_peersid {
+    /* IN */
+    evtchn_port_t evtchn;
+    /* OUT */
+    uint32_t sid;
+};
+
 struct xen_flask_op {
     uint32_t cmd;
 #define FLASK_LOAD              1
@@ -159,6 +166,7 @@ struct xen_flask_op {
 #define FLASK_MEMBER            20
 #define FLASK_ADD_OCONTEXT      21
 #define FLASK_DEL_OCONTEXT      22
+#define FLASK_GET_PEER_SID      23
     uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */
     union {
         struct xen_flask_load load;
@@ -176,6 +184,7 @@ struct xen_flask_op {
         struct xen_flask_cache_stats cache_stats;
         /* FLASK_ADD_OCONTEXT, FLASK_DEL_OCONTEXT */
         struct xen_flask_ocontext ocontext;
+        struct xen_flask_peersid peersid;
     } u;
 };
 typedef struct xen_flask_op xen_flask_op_t;
index 22fc6a3f3d1b3766dd3c8f7b778f3b1b7999cf02..11a639adff2f55274b631358c6329c9f0f2528ed 100644 (file)
@@ -70,6 +70,16 @@ int guest_enabled_event(struct vcpu *v, uint32_t virq);
 /* Notify remote end of a Xen-attached event channel.*/
 void notify_via_xen_event_channel(struct domain *ld, int lport);
 
+/* Internal event channel object accessors */
+#define bucket_from_port(d,p) \
+    ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
+#define port_is_valid(d,p)    \
+    (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \
+     (bucket_from_port(d,p) != NULL))
+#define evtchn_from_port(d,p) \
+    (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
+
+
 /* Wait on a Xen-attached event channel. */
 #define wait_on_xen_event_channel(port, condition)                      \
     do {                                                                \
index 00a0af2ab62e1d0637f4c704d5a47ffc346a5d19..bd4db3792c877b52c0f655110b36ffc6027f69d5 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <xen/errno.h>
+#include <xen/event.h>
 #include <xsm/xsm.h>
 #include <xen/guest_access.h>
 
@@ -44,6 +45,7 @@ integer_param("flask_enabled", flask_enabled);
         1UL<<FLASK_AVC_HASHSTATS | \
         1UL<<FLASK_AVC_CACHESTATS | \
         1UL<<FLASK_MEMBER | \
+        1UL<<FLASK_GET_PEER_SID | \
    0)
 
 static DEFINE_SPINLOCK(sel_sem);
@@ -541,6 +543,36 @@ static int flask_ocontext_add(struct xen_flask_ocontext *arg)
     return security_ocontext_add(arg->ocon, arg->low, arg->high, arg->sid);
 }
 
+static int flask_get_peer_sid(struct xen_flask_peersid *arg)
+{
+    int rv = -EINVAL;
+    struct domain *d = current->domain;
+    struct domain *peer;
+    struct evtchn *chn;
+    struct domain_security_struct *dsec;
+
+    spin_lock(&d->event_lock);
+
+    if ( !port_is_valid(d, arg->evtchn) )
+        goto out;
+
+    chn = evtchn_from_port(d, arg->evtchn);
+    if ( chn->state != ECS_INTERDOMAIN )
+        goto out;
+
+    peer = chn->u.interdomain.remote_dom;
+    if ( !peer )
+        goto out;
+
+    dsec = peer->ssid;
+    arg->sid = dsec->sid;
+    rv = 0;
+
+ out:
+    spin_unlock(&d->event_lock);
+    return rv;
+}
+
 long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op)
 {
     xen_flask_op_t op;
@@ -644,6 +676,10 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op)
         rv = flask_ocontext_del(&op.u.ocontext);
         break;
 
+    case FLASK_GET_PEER_SID:
+        rv = flask_get_peer_sid(&op.u.peersid);
+        break;
+
     default:
         rv = -ENOSYS;
     }