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

[Xen-devel] [PATCH 3/4] flask: Update flask_op hypercall structure



Instead of placing string parsing inside the hypervisor, use binary
structures like other Xen hypercalls do.

This patch also removes libflask; if the old flask_* namespace is needed
for longer backwards compatability (it was noted as deprecated in July
2010), a shim redirecting to the proper xc_flask_* calls can be created.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 tools/libxc/xc_flask.c            |  471 +++++++---------
 tools/libxc/xc_private.h          |    2 +
 tools/libxc/xenctrl.h             |    4 +-
 xen/include/public/xsm/flask_op.h |  146 +++++-
 xen/xsm/flask/avc.c               |   13 +-
 xen/xsm/flask/flask_op.c          | 1128 +++++++++++--------------------------
 xen/xsm/flask/include/avc.h       |    3 +-
 xen/xsm/flask/include/security.h  |    4 +-
 xen/xsm/flask/ss/services.c       |   11 +-
 9 files changed, 683 insertions(+), 1099 deletions(-)

diff --git a/tools/libxc/xc_flask.c b/tools/libxc/xc_flask.c
index d268098..80c5a2d 100644
--- a/tools/libxc/xc_flask.c
+++ b/tools/libxc/xc_flask.c
@@ -30,18 +30,21 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 
-#define OCON_PIRQ_STR   "pirq"
-#define OCON_IOPORT_STR "ioport"
-#define OCON_IOMEM_STR  "iomem"
-#define OCON_DEVICE_STR "pcidevice"
+#define OCON_ISID    0    /* initial SIDs */
+#define OCON_PIRQ    1    /* physical irqs */
+#define OCON_IOPORT  2    /* io ports */
+#define OCON_IOMEM   3    /* io memory */
+#define OCON_DEVICE  4    /* pci devices */
 #define INITCONTEXTLEN  256
 
-int xc_flask_op(xc_interface *xch, flask_op_t *op)
+int xc_flask_op(xc_interface *xch, xen_flask_op_t *op)
 {
     int ret = -1;
     DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
+    op->interface_version = XEN_FLASK_INTERFACE_VERSION;
+
     if ( xc_hypercall_bounce_pre(xch, op) )
     {
         PERROR("Could not bounce memory for flask op hypercall");
@@ -63,402 +66,360 @@ int xc_flask_op(xc_interface *xch, flask_op_t *op)
     return ret;
 }
 
-int xc_flask_load(xc_interface *xc_handle, char *buf, uint32_t size)
+int xc_flask_load(xc_interface *xch, char *buf, uint32_t size)
 {
     int err;
-    flask_op_t op;
-    
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+    if ( xc_hypercall_bounce_pre(xch, buf) )
+    {
+        PERROR("Could not bounce memory for flask op hypercall");
+        return -1;
+    }
+
     op.cmd = FLASK_LOAD;
-    op.buf = buf;
-    op.size = size;
+    op.u.load.size = size;
+    set_xen_guest_handle(op.u.load.buffer, buf);
     
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
+    err = xc_flask_op(xch, &op);
 
-    return 0;
+    xc_hypercall_bounce_post(xch, buf);
+
+    return err;
 }
 
-int xc_flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, 
uint32_t *sid)
+int xc_flask_context_to_sid(xc_interface *xch, char *buf, uint32_t size, 
uint32_t *sid)
 {
     int err;
-    flask_op_t op;
-    
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+    if ( xc_hypercall_bounce_pre(xch, buf) )
+    {
+        PERROR("Could not bounce memory for flask op hypercall");
+        return -1;
+    }
+
     op.cmd = FLASK_CONTEXT_TO_SID;
-    op.buf = buf;
-    op.size = size;
+    op.u.sid_context.size = size;
+    set_xen_guest_handle(op.u.sid_context.context, buf);
     
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-    
-    sscanf(buf, "%u", sid);
+    err = xc_flask_op(xch, &op);
 
-    return 0;
+    if ( !err )
+        *sid = op.u.sid_context.sid;
+
+    xc_hypercall_bounce_post(xch, buf);
+
+    return err;
 }
 
-int xc_flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, 
uint32_t size)
+int xc_flask_sid_to_context(xc_interface *xch, int sid, char *buf, uint32_t 
size)
 {
     int err;
-    flask_op_t op;
-    
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(buf, size, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+    if ( xc_hypercall_bounce_pre(xch, buf) )
+    {
+        PERROR("Could not bounce memory for flask op hypercall");
+        return -1;
+    }
+
     op.cmd = FLASK_SID_TO_CONTEXT;
-    op.buf = buf;
-    op.size = size;
+    op.u.sid_context.sid = sid;
+    op.u.sid_context.size = size;
+    set_xen_guest_handle(op.u.sid_context.context, buf);
     
-    snprintf(buf, size, "%u", sid);
+    err = xc_flask_op(xch, &op);
 
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-
-    return 0;
+    xc_hypercall_bounce_post(xch, buf);
+   
+    return err;
 }
 
-int xc_flask_getenforce(xc_interface *xc_handle)
+int xc_flask_getenforce(xc_interface *xch)
 {
-    int err;
-    flask_op_t op;
-    char buf[20];            
-    int size = 20;
-    int mode;
- 
+    DECLARE_FLASK_OP;
     op.cmd = FLASK_GETENFORCE;
-    op.buf = buf;
-    op.size = size;
     
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-
-    sscanf(buf, "%i", &mode);
-
-    return mode;
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_setenforce(xc_interface *xc_handle, int mode)
+int xc_flask_setenforce(xc_interface *xch, int mode)
 {
-    int err;
-    flask_op_t op;
-    char buf[20];
-    int size = 20; 
- 
+    DECLARE_FLASK_OP;
     op.cmd = FLASK_SETENFORCE;
-    op.buf = buf;
-    op.size = size;
+    op.u.enforce.enforcing = mode;
    
-    snprintf(buf, size, "%i", mode);
- 
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-
-    return 0;
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_getbool_byid(xc_interface *xc_handle, int id, char *name, 
uint32_t size, int *curr, int *pend)
+int xc_flask_getbool_byid(xc_interface *xch, int id, char *name, uint32_t 
size, int *curr, int *pend)
 {
-    flask_op_t op;
-    char buf[255];
     int rv;
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(name, size, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+    if ( xc_hypercall_bounce_pre(xch, name) )
+    {
+        PERROR("Could not bounce memory for flask op hypercall");
+        return -1;
+    }
 
-    op.cmd = FLASK_GETBOOL2;
-    op.buf = buf;
-    op.size = 255;
+    op.cmd = FLASK_GETBOOL;
+    op.u.boolean.bool_id = id;
+    op.u.boolean.size = size;
+    set_xen_guest_handle(op.u.boolean.name, name);
 
-    snprintf(buf, sizeof buf, "%i", id);
+    rv = xc_flask_op(xch, &op);
 
-    rv = xc_flask_op(xc_handle, &op);
+    xc_hypercall_bounce_post(xch, name);
 
     if ( rv )
         return rv;
     
-    sscanf(buf, "%i %i %s", curr, pend, name);
+    if ( curr )
+        *curr = op.u.boolean.enforcing;
+    if ( pend )
+        *pend = op.u.boolean.pending;
 
     return rv;
 }
 
-int xc_flask_getbool_byname(xc_interface *xc_handle, char *name, int *curr, 
int *pend)
+int xc_flask_getbool_byname(xc_interface *xch, char *name, int *curr, int 
*pend)
 {
-    flask_op_t op;
-    char buf[255];
     int rv;
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(name, strlen(name), 
XC_HYPERCALL_BUFFER_BOUNCE_IN);
 
-    op.cmd = FLASK_GETBOOL_NAMED;
-    op.buf = buf;
-    op.size = 255;
+    op.cmd = FLASK_GETBOOL;
+    op.u.boolean.bool_id = -1;
+    op.u.boolean.size = strlen(name);
+    set_xen_guest_handle(op.u.boolean.name, name);
 
-    strncpy(buf, name, op.size);
+    rv = xc_flask_op(xch, &op);
 
-    rv = xc_flask_op(xc_handle, &op);
+    xc_hypercall_bounce_post(xch, name);
 
     if ( rv )
         return rv;
     
-    sscanf(buf, "%i %i", curr, pend);
+    if ( curr )
+        *curr = op.u.boolean.enforcing;
+    if ( pend )
+        *pend = op.u.boolean.pending;
 
     return rv;
 }
 
-int xc_flask_setbool(xc_interface *xc_handle, char *name, int value, int 
commit)
+int xc_flask_setbool(xc_interface *xch, char *name, int value, int commit)
 {
-    flask_op_t op;
-    char buf[255];
-    int size = 255;
+    int rv;
+    DECLARE_FLASK_OP;
+    DECLARE_HYPERCALL_BOUNCE(name, strlen(name), 
XC_HYPERCALL_BUFFER_BOUNCE_IN);
 
-    op.cmd = FLASK_SETBOOL_NAMED;
-    op.buf = buf;
-    op.size = size;
+    op.cmd = FLASK_SETBOOL;
+    op.u.boolean.bool_id = -1;
+    op.u.boolean.new_value = value;
+    op.u.boolean.commit = 1;
+    op.u.boolean.size = strlen(name);
+    set_xen_guest_handle(op.u.boolean.name, name);
 
-    snprintf(buf, size, "%s %i %i", name, value, commit);
+    rv = xc_flask_op(xch, &op);
 
-    return xc_flask_op(xc_handle, &op);
+    xc_hypercall_bounce_post(xch, name);
+
+    return rv;
 }
 
-static int xc_flask_add(xc_interface *xc_handle, char *cat, char *arg, char 
*scontext)
+
+static int xc_flask_add(xc_interface *xch, uint32_t ocon, uint64_t low, 
uint64_t high, char *scontext)
 {
-    char buf[512];
-    flask_op_t op;
+    uint32_t sid;
+    int err;
+    DECLARE_FLASK_OP;
+
+    err = xc_flask_context_to_sid(xch, scontext, strlen(scontext), &sid);
+    if ( err )
+        return err;
 
-    memset(buf, 0, 512);
-    snprintf(buf, 512, "%s %255s %s", cat, scontext, arg);
     op.cmd = FLASK_ADD_OCONTEXT;
-    op.buf = buf;
-    op.size = 512;
+    op.u.ocontext.ocon = ocon;
+    op.u.ocontext.sid = sid;
+    op.u.ocontext.low = low;
+    op.u.ocontext.high = high;
     
-    return xc_flask_op(xc_handle, &op);
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char 
*scontext)
+int xc_flask_add_pirq(xc_interface *xch, unsigned int pirq, char *scontext)
 {
-    char arg[16];
-
-    snprintf(arg, 16, "%u", pirq);
-    return xc_flask_add(xc_handle, OCON_PIRQ_STR, arg, scontext);
+    return xc_flask_add(xch, OCON_PIRQ, pirq, pirq, scontext);
 }
 
-int xc_flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned 
long high,
+int xc_flask_add_ioport(xc_interface *xch, unsigned long low, unsigned long 
high,
                       char *scontext)
 {
-    char arg[64];
-
-    snprintf(arg, 64, "%lu %lu", low, high);
-    return xc_flask_add(xc_handle, OCON_IOPORT_STR, arg, scontext);
+    return xc_flask_add(xch, OCON_IOPORT, low, high, scontext);
 }
 
-int xc_flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned 
long high,
+int xc_flask_add_iomem(xc_interface *xch, unsigned long low, unsigned long 
high,
                      char *scontext)
 {
-    char arg[64];
-
-    snprintf(arg, 64, "%lu %lu", low, high);
-    return xc_flask_add(xc_handle, OCON_IOMEM_STR, arg, scontext);
+    return xc_flask_add(xch, OCON_IOMEM, low, high, scontext);
 }
 
-int xc_flask_add_device(xc_interface *xc_handle, unsigned long device, char 
*scontext)
+int xc_flask_add_device(xc_interface *xch, unsigned long device, char 
*scontext)
 {
-    char arg[32];
-
-    snprintf(arg, 32, "%lu", device);
-    return xc_flask_add(xc_handle, OCON_DEVICE_STR, arg, scontext);
+    return xc_flask_add(xch, OCON_DEVICE, device, device, scontext);
 }
 
-static int xc_flask_del(xc_interface *xc_handle, char *cat, char *arg)
+static int xc_flask_del(xc_interface *xch, uint32_t ocon, uint64_t low, 
uint64_t high)
 {
-    char buf[256];
-    flask_op_t op;
+    DECLARE_FLASK_OP;
 
-    memset(buf, 0, 256);
-    snprintf(buf, 256, "%s %s", cat, arg);
     op.cmd = FLASK_DEL_OCONTEXT;
-    op.buf = buf;
-    op.size = 256;
+    op.u.ocontext.ocon = ocon;
+    op.u.ocontext.low = low;
+    op.u.ocontext.high = high;
     
-    return xc_flask_op(xc_handle, &op);
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_del_pirq(xc_interface *xc_handle, unsigned int pirq)
+int xc_flask_del_pirq(xc_interface *xch, unsigned int pirq)
 {
-    char arg[16];
-
-    snprintf(arg, 16, "%u", pirq);
-    return xc_flask_del(xc_handle, OCON_PIRQ_STR, arg);
+    return xc_flask_del(xch, OCON_PIRQ, pirq, pirq);
 }
 
-int xc_flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned 
long high)
+int xc_flask_del_ioport(xc_interface *xch, unsigned long low, unsigned long 
high)
 {
-    char arg[64];
-
-    snprintf(arg, 64, "%lu %lu", low, high);
-    return xc_flask_del(xc_handle, OCON_IOPORT_STR, arg);
+    return xc_flask_del(xch, OCON_IOPORT, low, high);
 }
 
-int xc_flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned 
long high)
+int xc_flask_del_iomem(xc_interface *xch, unsigned long low, unsigned long 
high)
 {
-    char arg[64];
-
-    snprintf(arg, 64, "%lu %lu", low, high);
-    return xc_flask_del(xc_handle, OCON_IOMEM_STR, arg);
+    return xc_flask_del(xch, OCON_IOMEM, low, high);
 }
 
-int xc_flask_del_device(xc_interface *xc_handle, unsigned long device)
+int xc_flask_del_device(xc_interface *xch, unsigned long device)
 {
-    char arg[32];
-
-    snprintf(arg, 32, "%lu", device);
-    return xc_flask_del(xc_handle, OCON_DEVICE_STR, arg);
+    return xc_flask_del(xch, OCON_DEVICE, device, device);
 }
 
-int xc_flask_access(xc_interface *xc_handle, const char *scon, const char 
*tcon,
+int xc_flask_access(xc_interface *xch, const char *scon, const char *tcon,
                 uint16_t tclass, uint32_t req,
                 uint32_t *allowed, uint32_t *decided,
                 uint32_t *auditallow, uint32_t *auditdeny,
                 uint32_t *seqno)
 {
-/* maximum number of digits in a 16-bit decimal number: */
-#define MAX_SHORT_DEC_LEN 5
-
-    char *buf;
-    int bufLen;
+    DECLARE_FLASK_OP;
     int err;
-    flask_op_t op;
-    uint32_t dummy_allowed;
-    uint32_t dummy_decided;
-    uint32_t dummy_auditallow;
-    uint32_t dummy_auditdeny;
-    uint32_t dummy_seqno;
-  
-    if (!allowed)
-        allowed = &dummy_allowed;
-    if (!decided)
-        decided = &dummy_decided;
-    if (!auditallow)
-        auditallow = &dummy_auditallow;
-    if (!auditdeny)
-        auditdeny = &dummy_auditdeny;
-    if (!seqno)
-        seqno = &dummy_seqno;
-
-    if (!scon)
-        return -EINVAL;
-    if (!tcon)
-        return -EINVAL;
-
-    bufLen = strlen(scon) + 1 + strlen(tcon) + 1 +
-        MAX_SHORT_DEC_LEN + 1 +
-        sizeof(req)*2 + 1;
-    buf = malloc(bufLen);
-    snprintf(buf, bufLen, "%s %s %hu %x", scon, tcon, tclass, req);
+
+    err = xc_flask_context_to_sid(xch, (char*)scon, strlen(scon), 
&op.u.access.ssid);
+    if ( err )
+        return err;
+    err = xc_flask_context_to_sid(xch, (char*)tcon, strlen(tcon), 
&op.u.access.tsid);
+    if ( err )
+        return err;
 
     op.cmd = FLASK_ACCESS;
-    op.buf = buf;
-    op.size = strlen(buf)+1;
+    op.u.access.tclass = tclass;
+    op.u.access.req = req;
     
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-    {
-        free(buf);
+    err = xc_flask_op(xch, &op);
+
+    if ( err )
         return err;
-    }
-   
-    if (sscanf(op.buf, "%x %x %x %x %u",
-               allowed, decided,
-               auditallow, auditdeny,
-               seqno) != 5) {
-        err = -EILSEQ;
-    }
 
-    err = ((*allowed & req) == req)? 0 : -EPERM;
+    if ( allowed )
+        *allowed = op.u.access.allowed;
+    if ( decided )
+        *decided = 0xffffffff;
+    if ( auditallow )
+        *auditallow = op.u.access.audit_allow;
+    if ( auditdeny )
+        *auditdeny = op.u.access.audit_deny;
+    if ( seqno )
+        *seqno = op.u.access.seqno;
 
-    return err;
+    if ( (op.u.access.allowed & req) != req )
+        err = -EPERM;
 
+    return err;
 }
 
-int xc_flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size)
+int xc_flask_avc_hashstats(xc_interface *xch, char *buf, int size)
 {
     int err;
-    flask_op_t op;
+    DECLARE_FLASK_OP;
   
     op.cmd = FLASK_AVC_HASHSTATS;
-    op.buf = buf;
-    op.size = size;
   
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-    {
-        free(buf);
-        return err;
-    }
+    err = xc_flask_op(xch, &op);
 
-    return 0;
+    snprintf(buf, size,
+             "entries: %d\nbuckets used: %d/%d\nlongest chain: %d\n",
+             op.u.hash_stats.entries, op.u.hash_stats.buckets_used,
+             op.u.hash_stats.buckets_total, op.u.hash_stats.max_chain_len);
+
+    return err;
 }
 
-int xc_flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size)
+int xc_flask_avc_cachestats(xc_interface *xch, char *buf, int size)
 {
-    int err;
-    flask_op_t op;
+    int err, n;
+    int i = 0;
+    DECLARE_FLASK_OP;
+
+    n = snprintf(buf, size, "lookups hits misses allocations reclaims 
frees\n");
+    buf += n;
+    size -= n;
   
     op.cmd = FLASK_AVC_CACHESTATS;
-    op.buf = buf;
-    op.size = size;
-  
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    while ( size > 0 )
     {
-        free(buf);
-        return err;
+        op.u.cache_stats.cpu = i;
+        err = xc_flask_op(xch, &op);
+        if ( err && errno == ENOENT )
+            return 0;
+        if ( err )
+            return err;
+        n = snprintf(buf, size, "%u %u %u %u %u %u\n",
+                     op.u.cache_stats.lookups, op.u.cache_stats.hits,
+                     op.u.cache_stats.misses, op.u.cache_stats.allocations,
+                     op.u.cache_stats.reclaims, op.u.cache_stats.frees);
+        buf += n;
+        size -= n;
+        i++;
     }
 
     return 0;
 }
 
-int xc_flask_policyvers(xc_interface *xc_handle, char *buf, int size)
+int xc_flask_policyvers(xc_interface *xch)
 {
-    int err;
-    flask_op_t op;
-  
+    DECLARE_FLASK_OP;
     op.cmd = FLASK_POLICYVERS;
-    op.buf = buf;
-    op.size = size;
-
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-    {
-        free(buf);
-        return err;
-    }
 
-    return 0;
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_getavc_threshold(xc_interface *xc_handle)
+int xc_flask_getavc_threshold(xc_interface *xch)
 {
-    int err;
-    flask_op_t op;
-    char buf[20];            
-    int size = 20;
-    int threshold;
- 
+    DECLARE_FLASK_OP;
     op.cmd = FLASK_GETAVC_THRESHOLD;
-    op.buf = buf;
-    op.size = size;
     
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-
-    sscanf(buf, "%i", &threshold);
-
-    return threshold;
+    return xc_flask_op(xch, &op);
 }
 
-int xc_flask_setavc_threshold(xc_interface *xc_handle, int threshold)
+int xc_flask_setavc_threshold(xc_interface *xch, int threshold)
 {
-    int err;
-    flask_op_t op;
-    char buf[20];            
-    int size = 20;
- 
+    DECLARE_FLASK_OP;
     op.cmd = FLASK_SETAVC_THRESHOLD;
-    op.buf = buf;
-    op.size = size;
+    op.u.setavc_threshold.threshold = threshold;
 
-    snprintf(buf, size, "%i", threshold);
- 
-    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
-        return err;
-
-    return 0;
+    return xc_flask_op(xch, &op);
 }
 
 /*
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 3687561..7b83ef3 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -42,11 +42,13 @@
 #define DECLARE_DOMCTL struct xen_domctl domctl = { 0 }
 #define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 }
 #define DECLARE_PHYSDEV_OP struct physdev_op physdev_op = { 0 }
+#define DECLARE_FLASK_OP struct xen_flask_op op = { 0 }
 #else
 #define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
 #define DECLARE_DOMCTL struct xen_domctl domctl
 #define DECLARE_SYSCTL struct xen_sysctl sysctl
 #define DECLARE_PHYSDEV_OP struct physdev_op physdev_op
+#define DECLARE_FLASK_OP struct xen_flask_op op
 #endif
 
 #undef PAGE_SHIFT
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 1e7c32b..6b3202e 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -1328,7 +1328,7 @@ int xc_sysctl(xc_interface *xch, struct xen_sysctl 
*sysctl);
 
 int xc_version(xc_interface *xch, int cmd, void *arg);
 
-int xc_flask_op(xc_interface *xch, flask_op_t *op);
+int xc_flask_op(xc_interface *xch, xen_flask_op_t *op);
 
 /*
  * Subscribe to state changes in a domain via evtchn.
@@ -1976,7 +1976,7 @@ int xc_flask_access(xc_interface *xc_handle, const char 
*scon, const char *tcon,
                   uint32_t *auditallow, uint32_t *auditdeny,
                   uint32_t *seqno);
 int xc_flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size);
-int xc_flask_policyvers(xc_interface *xc_handle, char *buf, int size);
+int xc_flask_policyvers(xc_interface *xc_handle);
 int xc_flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size);
 int xc_flask_getavc_threshold(xc_interface *xc_handle);
 int xc_flask_setavc_threshold(xc_interface *xc_handle, int threshold);
diff --git a/xen/include/public/xsm/flask_op.h 
b/xen/include/public/xsm/flask_op.h
index 416ac08..83dcd99 100644
--- a/xen/include/public/xsm/flask_op.h
+++ b/xen/include/public/xsm/flask_op.h
@@ -25,6 +25,118 @@
 #ifndef __FLASK_OP_H__
 #define __FLASK_OP_H__
 
+#define XEN_FLASK_INTERFACE_VERSION 1
+
+struct xen_flask_load {
+    XEN_GUEST_HANDLE(char) buffer;
+    uint32_t size;
+};
+
+struct xen_flask_setenforce {
+    uint32_t enforcing;
+};
+
+struct xen_flask_sid_context {
+    /* IN/OUT: sid to convert to/from string */
+    uint32_t sid;
+    /* IN: size of the context buffer
+     * OUT: actual size of the output context string
+     */
+    uint32_t size;
+    XEN_GUEST_HANDLE(char) context;
+};
+
+struct xen_flask_access {
+    /* IN: access request */
+    uint32_t ssid;
+    uint32_t tsid;
+    uint32_t tclass;
+    uint32_t req;
+    /* OUT: AVC data */
+    uint32_t allowed;
+    uint32_t audit_allow;
+    uint32_t audit_deny;
+    uint32_t seqno;
+};
+
+struct xen_flask_transition {
+    /* IN: transition SIDs and class */
+    uint32_t ssid;
+    uint32_t tsid;
+    uint32_t tclass;
+    /* OUT: new SID */
+    uint32_t newsid;
+};
+
+struct xen_flask_userlist {
+    /* IN: starting SID for list */
+    uint32_t start_sid;
+    /* IN: size of user string and output buffer
+     * OUT: number of SIDs returned */
+    uint32_t size;
+    union {
+        /* IN: user to enumerate SIDs */
+        XEN_GUEST_HANDLE(char) user;
+        /* OUT: SID list */
+        XEN_GUEST_HANDLE(uint32) sids;
+    } u;
+};
+
+struct xen_flask_boolean {
+    /* IN/OUT: numeric identifier for boolean [GET/SET]
+     * If -1, name will be used and bool_id will be filled in. */
+    uint32_t bool_id;
+    /* OUT: current enforcing value of boolean [GET/SET] */
+    uint8_t enforcing;
+    /* OUT: pending value of boolean [GET/SET] */
+    uint8_t pending;
+    /* IN: new value of boolean [SET] */
+    uint8_t new_value;
+    /* IN: commit new value instead of only setting pending [SET] */
+    uint8_t commit;
+    /* IN: size of boolean name buffer [GET/SET]
+     * OUT: actual size of name [GET only] */
+    uint32_t size;
+    /* IN: if bool_id is -1, used to find boolean [GET/SET]
+     * OUT: textual name of boolean [GET only]
+     */
+    XEN_GUEST_HANDLE(char) name;
+};
+
+struct xen_flask_setavc_threshold {
+    /* IN */
+    uint32_t threshold;
+};
+
+struct xen_flask_hash_stats {
+    /* OUT */
+    uint32_t entries;
+    uint32_t buckets_used;
+    uint32_t buckets_total;
+    uint32_t max_chain_len;
+};
+
+struct xen_flask_cache_stats {
+    /* IN */
+    uint32_t cpu;
+    /* OUT */
+    uint32_t lookups;
+    uint32_t hits;
+    uint32_t misses;
+    uint32_t allocations;
+    uint32_t reclaims;
+    uint32_t frees;
+};
+
+struct xen_flask_ocontext {
+    /* IN */
+    uint32_t ocon;
+    uint32_t sid;
+    uint64_t low, high;
+};
+
+struct xen_flask_op {
+    uint32_t cmd;
 #define FLASK_LOAD              1
 #define FLASK_GETENFORCE        2
 #define FLASK_SETENFORCE        3
@@ -47,18 +159,26 @@
 #define FLASK_MEMBER            20
 #define FLASK_ADD_OCONTEXT      21
 #define FLASK_DEL_OCONTEXT      22
-#define FLASK_GETBOOL_NAMED     23
-#define FLASK_GETBOOL2          24
-#define FLASK_SETBOOL_NAMED     25
-
-#define FLASK_LAST              FLASK_SETBOOL_NAMED
-
-typedef struct flask_op {
-    uint32_t  cmd;
-    uint32_t  size;
-    char      *buf;
-} flask_op_t;
-
-DEFINE_XEN_GUEST_HANDLE(flask_op_t);
+    uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */
+    union {
+        struct xen_flask_load load;
+        struct xen_flask_setenforce enforce;
+        /* FLASK_CONTEXT_TO_SID and FLASK_SID_TO_CONTEXT */
+        struct xen_flask_sid_context sid_context;
+        struct xen_flask_access access;
+        /* FLASK_CREATE, FLASK_RELABEL, FLASK_MEMBER */
+        struct xen_flask_transition transition;
+        struct xen_flask_userlist userlist;
+        /* FLASK_GETBOOL, FLASK_SETBOOL */
+        struct xen_flask_boolean boolean;
+        struct xen_flask_setavc_threshold setavc_threshold;
+        struct xen_flask_hash_stats hash_stats;
+        struct xen_flask_cache_stats cache_stats;
+        /* FLASK_ADD_OCONTEXT, FLASK_DEL_OCONTEXT */
+        struct xen_flask_ocontext ocontext;
+    } u;
+};
+typedef struct xen_flask_op xen_flask_op_t;
+DEFINE_XEN_GUEST_HANDLE(xen_flask_op_t);
 
 #endif
diff --git a/xen/xsm/flask/avc.c b/xen/xsm/flask/avc.c
index 3a60a3a..74f160d 100644
--- a/xen/xsm/flask/avc.c
+++ b/xen/xsm/flask/avc.c
@@ -28,6 +28,7 @@
 #include <xen/rcupdate.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
+#include <public/xsm/flask_op.h>
 
 #include "avc.h"
 #include "avc_ss.h"
@@ -251,7 +252,7 @@ void __init avc_init(void)
     printk("AVC INITIALIZED\n");
 }
 
-int avc_get_hash_stats(char *buf, uint32_t size)
+int avc_get_hash_stats(struct xen_flask_hash_stats *arg)
 {
     int i, chain_len, max_chain_len, slots_used;
     struct avc_node *node;
@@ -279,10 +280,12 @@ int avc_get_hash_stats(char *buf, uint32_t size)
 
     rcu_read_unlock(&avc_rcu_lock);
     
-    return snprintf(buf, size, "entries: %d\nbuckets used: %d/%d\n"
-                    "longest chain: %d\n",
-                    atomic_read(&avc_cache.active_nodes),
-                    slots_used, AVC_CACHE_SLOTS, max_chain_len);
+    arg->entries = atomic_read(&avc_cache.active_nodes);
+    arg->buckets_used = slots_used;
+    arg->buckets_total = AVC_CACHE_SLOTS;
+    arg->max_chain_len = max_chain_len;
+
+    return 0;
 }
 
 static void avc_node_free(struct rcu_head *rhead)
diff --git a/xen/xsm/flask/flask_op.c b/xen/xsm/flask/flask_op.c
index 64d9ec5..00a0af2 100644
--- a/xen/xsm/flask/flask_op.c
+++ b/xen/xsm/flask/flask_op.c
@@ -30,48 +30,21 @@ integer_param("flask_enabled", flask_enabled);
 #endif
 
 #define MAX_POLICY_SIZE 0x4000000
-#define FLASK_COPY_IN \
-    ( \
-        1UL<<FLASK_LOAD | \
-        1UL<<FLASK_SETENFORCE | \
-        1UL<<FLASK_CONTEXT_TO_SID | \
-        1UL<<FLASK_SID_TO_CONTEXT | \
-        1UL<<FLASK_ACCESS | \
-        1UL<<FLASK_CREATE | \
-        1UL<<FLASK_RELABEL | \
-        1UL<<FLASK_USER | \
-        1UL<<FLASK_GETBOOL | \
-        1UL<<FLASK_SETBOOL | \
-        1UL<<FLASK_COMMITBOOLS | \
-        1UL<<FLASK_DISABLE | \
-        1UL<<FLASK_SETAVC_THRESHOLD | \
-        1UL<<FLASK_MEMBER | \
-        1UL<<FLASK_ADD_OCONTEXT | \
-        1UL<<FLASK_DEL_OCONTEXT | \
-        1UL<<FLASK_GETBOOL_NAMED | \
-        1UL<<FLASK_GETBOOL2 | \
-        1UL<<FLASK_SETBOOL_NAMED \
-    )
 
 #define FLASK_COPY_OUT \
     ( \
-        1UL<<FLASK_GETENFORCE | \
         1UL<<FLASK_CONTEXT_TO_SID | \
         1UL<<FLASK_SID_TO_CONTEXT | \
         1UL<<FLASK_ACCESS | \
         1UL<<FLASK_CREATE | \
         1UL<<FLASK_RELABEL | \
         1UL<<FLASK_USER | \
-        1UL<<FLASK_POLICYVERS | \
         1UL<<FLASK_GETBOOL | \
-        1UL<<FLASK_MLS | \
-        1UL<<FLASK_GETAVC_THRESHOLD | \
+        1UL<<FLASK_SETBOOL | \
         1UL<<FLASK_AVC_HASHSTATS | \
         1UL<<FLASK_AVC_CACHESTATS | \
         1UL<<FLASK_MEMBER | \
-        1UL<<FLASK_GETBOOL_NAMED | \
-        1UL<<FLASK_GETBOOL2 \
-    )
+   0)
 
 static DEFINE_SPINLOCK(sel_sem);
 
@@ -96,412 +69,186 @@ static int domain_has_security(struct domain *d, u32 
perms)
                         perms, NULL);
 }
 
-static int flask_security_user(char *buf, uint32_t size)
-{
-    char *page = NULL;
-    char *con, *user, *ptr;
-    u32 sid, *sids;
-    int length;
-    char *newcon;
-    int i, rc;
-    u32 len, nsids;
-        
-    length = domain_has_security(current->domain, SECURITY__COMPUTE_USER);
-    if ( length )
-        return length;
-            
-    length = -ENOMEM;
-    con = xmalloc_array(char, size+1);
-    if ( !con )
-        return length;
-    memset(con, 0, size+1);
-    
-    user = xmalloc_array(char, size+1);
-    if ( !user )
-        goto out;
-    memset(user, 0, size+1);
-    
-    length = -ENOMEM;
-    page = xmalloc_bytes(PAGE_SIZE);
-    if ( !page )
-        goto out2;
-    memset(page, 0, PAGE_SIZE);
-
-    length = -EINVAL;
-    if ( sscanf(buf, "%s %s", con, user) != 2 )
-        goto out2;
-
-    length = security_context_to_sid(con, strlen(con)+1, &sid);
-    if ( length < 0 )
-        goto out2;
-            
-    length = security_get_user_sids(sid, user, &sids, &nsids);
-    if ( length < 0 )
-        goto out2;
-    
-    length = snprintf(page, PAGE_SIZE, "%u", nsids) + 1;
-    ptr = page + length;
-    for ( i = 0; i < nsids; i++ )
-    {
-        rc = security_sid_to_context(sids[i], &newcon, &len);
-        if ( rc )
-        {
-            length = rc;
-            goto out3;
-        }
-        if ( (length + len) >= PAGE_SIZE )
-        {
-            xfree(newcon);
-            length = -ERANGE;
-            goto out3;
-        }
-        memcpy(ptr, newcon, len);
-        xfree(newcon);
-        ptr += len;
-        length += len;
-    }
-    
-    if ( length > size )
-    {
-        printk( "%s:  context size (%u) exceeds payload "
-                "max\n", __FUNCTION__, length);
-        length = -ERANGE;
-        goto out3;
-    }
-
-    memset(buf, 0, size);
-    memcpy(buf, page, length);
-        
- out3:
-    xfree(sids);
- out2:
-    if ( page )
-        xfree(page);
-    xfree(user);
- out:
-    xfree(con);
-    return length;
-}
-
-static int flask_security_relabel(char *buf, uint32_t size)
+static int flask_copyin_string(XEN_GUEST_HANDLE(char) u_buf, char **buf, 
uint32_t size)
 {
-    char *scon, *tcon;
-    u32 ssid, tsid, newsid;
-    u16 tclass;
-    int length;
-    char *newcon;
-    u32 len;
+    char *tmp = xmalloc_bytes(size + 1);
+    if ( !tmp )
+        return -ENOMEM;
 
-    length = domain_has_security(current->domain, SECURITY__COMPUTE_RELABEL);
-    if ( length )
-        return length;
-            
-    length = -ENOMEM;
-    scon = xmalloc_array(char, size+1);
-    if ( !scon )
-        return length;
-    memset(scon, 0, size+1);
-        
-    tcon = xmalloc_array(char, size+1);
-    if ( !tcon )
-        goto out;
-    memset(tcon, 0, size+1);
-        
-    length = -EINVAL;
-    if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 )
-        goto out2;
-            
-    length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-    if ( length < 0 )
-        goto out2;
-    length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-    if ( length < 0 )
-        goto out2;
-            
-    length = security_change_sid(ssid, tsid, tclass, &newsid);
-    if ( length < 0 )
-        goto out2;
-            
-    length = security_sid_to_context(newsid, &newcon, &len);
-    if ( length < 0 )
-        goto out2;
-            
-    if ( len > size )
+    if ( copy_from_guest(tmp, u_buf, size) )
     {
-        printk( "%s:  context size (%u) exceeds payload "
-                "max\n", __FUNCTION__, len);
-        length = -ERANGE;
-        goto out3;
+        xfree(tmp);
+        return -EFAULT;
     }
+    tmp[size] = 0;
 
-    memset(buf, 0, size);
-    memcpy(buf, newcon, len);
-    length = len;
-
- out3:
-    xfree(newcon);
- out2:
-    xfree(tcon);
- out:
-    xfree(scon);
-    return length;
+    *buf = tmp;
+    return 0;
 }
 
-static int flask_security_create(char *buf, uint32_t size)
+static int flask_security_user(struct xen_flask_userlist *arg)
 {
-    char *scon, *tcon;
-    u32 ssid, tsid, newsid;
-    u16 tclass;
-    int length;
-    char *newcon;
-    u32 len;
+    char *user;
+    u32 *sids;
+    u32 nsids;
+    int rv;
 
-    length = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE);
-    if ( length )
-        return length;
+    rv = domain_has_security(current->domain, SECURITY__COMPUTE_USER);
+    if ( rv )
+        return rv;
 
-    length = -ENOMEM;
-    scon = xmalloc_array(char, size+1);
-    if ( !scon )
-        return length;
-    memset(scon, 0, size+1);
+    rv = flask_copyin_string(arg->u.user, &user, arg->size);
+    if ( rv )
+        return rv;
 
-    tcon = xmalloc_array(char, size+1);
-    if ( !tcon )
+    rv = security_get_user_sids(arg->start_sid, user, &sids, &nsids);
+    if ( rv < 0 )
         goto out;
-    memset(tcon, 0, size+1);
-
-    length = -EINVAL;
-    if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 )
-        goto out2;
-
-    length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-    if ( length < 0 )
-        goto out2;
 
-    length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-    if ( length < 0 )
-        goto out2;
+    if ( nsids * sizeof(sids[0]) > arg->size )
+        nsids = arg->size / sizeof(sids[0]);
 
-    length = security_transition_sid(ssid, tsid, tclass, &newsid);
-    if ( length < 0 )
-        goto out2;
+    arg->size = nsids;
 
-    length = security_sid_to_context(newsid, &newcon, &len);
-    if ( length < 0 )    
-        goto out2;
-
-    if ( len > size )
-    {
-        printk( "%s:  context size (%u) exceeds payload "
-                "max\n", __FUNCTION__, len);
-        length = -ERANGE;
-        goto out3;
-    }
+    if ( copy_to_guest(arg->u.sids, sids, nsids) )
+        rv = -EFAULT;
 
-    memset(buf, 0, size);
-    memcpy(buf, newcon, len);
-    length = len;
-        
- out3:
-    xfree(newcon);
- out2:
-    xfree(tcon);
+    xfree(sids);
  out:
-    xfree(scon);
-    return length;
+    xfree(user);
+    return rv;
 }
 
-static int flask_security_access(char *buf, uint32_t size)
+static int flask_security_relabel(struct xen_flask_transition *arg)
 {
-    char *scon, *tcon;
-    u32 ssid, tsid;
-    u16 tclass;
-    u32 req;
-    struct av_decision avd;
-    int length;
+    int rv;
 
-    length = domain_has_security(current->domain, SECURITY__COMPUTE_AV);
-    if ( length )
-        return length;
-
-    length = -ENOMEM;
-    scon = xmalloc_array(char, size+1);
-    if (!scon)
-        return length;
-    memset(scon, 0, size+1);
-
-    tcon = xmalloc_array(char, size+1);
-    if ( !tcon )
-        goto out;
-    memset( tcon, 0, size+1 );
-
-    length = -EINVAL;
-    if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
-        goto out2;
-
-    length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-    if ( length < 0 )
-        goto out2;
-
-    length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-    if ( length < 0 )
-        goto out2;
+    rv = domain_has_security(current->domain, SECURITY__COMPUTE_RELABEL);
+    if ( rv )
+        return rv;
 
-    length = security_compute_av(ssid, tsid, tclass, req, &avd);
-    if ( length < 0 )
-        goto out2;
+    rv = security_change_sid(arg->ssid, arg->tsid, arg->tclass, &arg->newsid);
 
-    memset(buf, 0, size);
-    length = snprintf(buf, size, "%x %x %x %x %u", 
-                      avd.allowed, 0xffffffff,
-                      avd.auditallow, avd.auditdeny, 
-                      avd.seqno);
-                
- out2:
-    xfree(tcon);
- out:
-    xfree(scon);
-    return length;
+    return rv;
 }
 
-static int flask_security_member(char *buf, uint32_t size)
+static int flask_security_create(struct xen_flask_transition *arg)
 {
-    char *scon, *tcon;
-    u32 ssid, tsid, newsid;
-    u16 tclass;
-    int length;
-    char *newcon;
-    u32 len;
+    int rv;
 
-    length = domain_has_security(current->domain, SECURITY__COMPUTE_MEMBER);
-    if ( length )
-        return length;
+    rv = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE);
+    if ( rv )
+        return rv;
 
-    length = -ENOMEM;
-    scon = xmalloc_array(char, size+1);
-    if ( !scon )
-        return length;
-    memset(scon, 0, size+1);
+    rv = security_transition_sid(arg->ssid, arg->tsid, arg->tclass, 
&arg->newsid);
 
-    tcon = xmalloc_array(char, size+1);
-    if ( !tcon )
-        goto out;
-    memset(tcon, 0, size+1);
+    return rv;
+}
 
-    length = -EINVAL;
-    if ( sscanf(buf, "%s, %s, %hu", scon, tcon, &tclass) != 3 )
-        goto out2;
+static int flask_security_access(struct xen_flask_access *arg)
+{
+    struct av_decision avd;
+    int rv;
 
-    length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
-    if ( length < 0 )
-        goto out2;
+    rv = domain_has_security(current->domain, SECURITY__COMPUTE_AV);
+    if ( rv )
+        return rv;
 
-    length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
-    if ( length < 0 )
-        goto out2;
+    rv = security_compute_av(arg->ssid, arg->tsid, arg->tclass, arg->req, 
&avd);
+    if ( rv < 0 )
+        return rv;
 
-    length = security_member_sid(ssid, tsid, tclass, &newsid);
-    if ( length < 0 )
-        goto out2;
+    arg->allowed = avd.allowed;
+    arg->audit_allow = avd.auditallow;
+    arg->audit_deny = avd.auditdeny;
+    arg->seqno = avd.seqno;
+                
+    return rv;
+}
 
-    length = security_sid_to_context(newsid, &newcon, &len);
-    if ( length < 0 )
-        goto out2;
+static int flask_security_member(struct xen_flask_transition *arg)
+{
+    int rv;
 
-    if ( len > size )
-    {
-        printk("%s:  context size (%u) exceeds payload "
-               "max\n", __FUNCTION__, len);
-        length = -ERANGE;
-        goto out3;
-    }
+    rv = domain_has_security(current->domain, SECURITY__COMPUTE_MEMBER);
+    if ( rv )
+        return rv;
 
-    memset(buf, 0, size);
-    memcpy(buf, newcon, len);
-    length = len;
+    rv = security_member_sid(arg->ssid, arg->tsid, arg->tclass, &arg->newsid);
 
- out3:
-    xfree(newcon);
- out2:
-    xfree(tcon);
- out:
-    xfree(scon);
-    return length;
+    return rv;
 }
 
-static int flask_security_setenforce(char *buf, uint32_t count)
+static int flask_security_setenforce(struct xen_flask_setenforce *arg)
 {
-    int length;
-    int new_value;
+    int enforce = !!(arg->enforcing);
+    int rv;
 
-    if ( sscanf(buf, "%d", &new_value) != 1 )
-        return -EINVAL;
+    if ( enforce == flask_enforcing )
+        return 0;
 
-    if ( new_value != flask_enforcing )
-    {
-        length = domain_has_security(current->domain, SECURITY__SETENFORCE);
-        if ( length )
-            goto out;
-        flask_enforcing = new_value;
-        if ( flask_enforcing )
-            avc_ss_reset(0);
-    }
-    length = count;
+    rv = domain_has_security(current->domain, SECURITY__SETENFORCE);
+    if ( rv )
+        return rv;
 
- out:
-    return length;
+    flask_enforcing = enforce;
+
+    if ( flask_enforcing )
+        avc_ss_reset(0);
+
+    return 0;
 }
 
-static int flask_security_context(char *buf, uint32_t count)
+static int flask_security_context(struct xen_flask_sid_context *arg)
 {
-    u32 sid;
-    int length;
+    int rv;
+    char *buf;
 
-    length = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT);
-    if ( length )
-        goto out;
+    rv = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT);
+    if ( rv )
+        return rv;
 
-    length = security_context_to_sid(buf, count, &sid);
-    if ( length < 0 )
-        goto out;
+    rv = flask_copyin_string(arg->context, &buf, arg->size);
+    if ( rv )
+        return rv;
 
-    memset(buf, 0, count);
-    length = snprintf(buf, count, "%u", sid);
+    rv = security_context_to_sid(buf, arg->size, &arg->sid);
+    if ( rv < 0 )
+        goto out;
 
  out:
-    return length;
+    xfree(buf);
+
+    return rv;
 }
 
-static int flask_security_sid(char *buf, uint32_t count)
+static int flask_security_sid(struct xen_flask_sid_context *arg)
 {
+    int rv;
     char *context;
-    u32 sid;
     u32 len;
-    int length;
 
-    length = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT);
-    if ( length )
-        goto out;
+    rv = domain_has_security(current->domain, SECURITY__CHECK_CONTEXT);
+    if ( rv )
+        return rv;
 
-    if ( sscanf(buf, "%u", &sid) != 1 )
-        goto out;
+    rv = security_sid_to_context(arg->sid, &context, &len);
+    if ( rv < 0 )
+        return rv;
 
-    length = security_sid_to_context(sid, &context, &len);
-    if ( length < 0 )
-        goto out;
+    rv = 0;
 
-    if ( len > count )
-        return -ERANGE; 
+    if ( len > arg->size )
+        rv = -ERANGE;
 
-    memset(buf, 0, count);
-    memcpy(buf, context, len);
-    length = len;
+    arg->size = len;
+
+    if ( !rv && copy_to_guest(arg->context, context, len) )
+        rv = -EFAULT;
 
     xfree(context);
 
- out:
-    return length;
+    return rv;
 }
 
 int flask_disable(void)
@@ -530,229 +277,154 @@ int flask_disable(void)
     return 0;
 }
 
-static int flask_security_disable(char *buf, uint32_t count)
-{
-    int length;
-    int new_value;
-
-    length = -EINVAL;
-    if ( sscanf(buf, "%d", &new_value) != 1 )
-        goto out;
-
-    if ( new_value )
-    {
-        length = flask_disable();
-        if ( length < 0 )
-            goto out;
-    }
-
-    length = count;
-
- out:
-    return length;
-}
-
-static int flask_security_setavc_threshold(char *buf, uint32_t count)
+static int flask_security_setavc_threshold(struct xen_flask_setavc_threshold 
*arg)
 {
-    int ret;
-    int new_value;
-
-    if ( sscanf(buf, "%u", &new_value) != 1 )
-    {
-        ret = -EINVAL;
-        goto out;
-    }
+    int rv = 0;
 
-    if ( new_value != avc_cache_threshold )
+    if ( arg->threshold != avc_cache_threshold )
     {
-        ret = domain_has_security(current->domain, SECURITY__SETSECPARAM);
-        if ( ret )
+        rv = domain_has_security(current->domain, SECURITY__SETSECPARAM);
+        if ( rv )
             goto out;
-        avc_cache_threshold = new_value;
+        avc_cache_threshold = arg->threshold;
     }
-    ret = count;
 
  out:
-    return ret;
+    return rv;
 }
 
-static int flask_security_set_bool(char *buf, uint32_t count)
+static int flask_security_resolve_bool(struct xen_flask_boolean *arg)
 {
-    int length = -EFAULT;
-    unsigned int i, new_value;
-
-    spin_lock(&sel_sem);
-
-    length = domain_has_security(current->domain, SECURITY__SETBOOL);
-    if ( length )
-        goto out;
-
-    length = -EINVAL;
-    if ( sscanf(buf, "%d %d", &i, &new_value) != 2 )
-        goto out;
+    char *name;
+    int rv;
 
-    if (!bool_pending_values)
-        flask_security_make_bools();
+    if ( arg->bool_id != -1 )
+        return 0;
 
-    if ( i >= bool_num )
-        goto out;
+    rv = flask_copyin_string(arg->name, &name, arg->size);
+    if ( rv )
+        return rv;
 
-    if ( new_value )
-        new_value = 1;
+    arg->bool_id = security_find_bool(name);
+    arg->size = 0;
 
-    bool_pending_values[i] = new_value;
-    length = count;
+    xfree(name);
 
- out:
-    spin_unlock(&sel_sem);
-    return length;
+    return 0;
 }
 
-static int flask_security_set_bool_name(char *buf, uint32_t count)
+static int flask_security_set_bool(struct xen_flask_boolean *arg)
 {
-    int rv, num;
-    int i, new_value, commit;
-    int *values = NULL;
-    char *name;
-    
-    name = xmalloc_bytes(count);
-    if ( name == NULL )
-        return -ENOMEM;
+    int rv;
 
-    spin_lock(&sel_sem);
+    rv = flask_security_resolve_bool(arg);
+    if ( rv )
+        return rv;
 
     rv = domain_has_security(current->domain, SECURITY__SETBOOL);
     if ( rv )
-        goto out;
-    
-    rv = -EINVAL;
-    if ( sscanf(buf, "%s %d %d", name, &new_value, &commit) != 3 )
-        goto out;
+        return rv;
 
-    i = security_find_bool(name);
-    if ( i < 0 )
-        goto out;
+    spin_lock(&sel_sem);
 
-    if ( new_value )
-        new_value = 1;
+    if ( arg->commit )
+    {
+        int num;
+        int *values;
 
-    if ( commit ) {
         rv = security_get_bools(&num, NULL, &values);
         if ( rv != 0 )
             goto out;
-        values[i] = new_value;
-        if (bool_pending_values)
-            bool_pending_values[i] = new_value;
+
+        if ( arg->bool_id >= num )
+        {
+            rv = -ENOENT;
+            goto out;
+        }
+        values[arg->bool_id] = !!(arg->new_value);
+
+        arg->enforcing = arg->pending = !!(arg->new_value);
+
+        if ( bool_pending_values )
+            bool_pending_values[arg->bool_id] = !!(arg->new_value);
+
         rv = security_set_bools(num, values);
         xfree(values);
-    } else {
-        if (!bool_pending_values)
+    }
+    else
+    {
+        if ( !bool_pending_values )
             flask_security_make_bools();
 
-        bool_pending_values[i] = new_value;
-        rv = count;
+        if ( arg->bool_id >= bool_num )
+            goto out;
+
+        bool_pending_values[arg->bool_id] = !!(arg->new_value);
+        arg->pending = !!(arg->new_value);
+        arg->enforcing = security_get_bool_value(arg->bool_id);
+
+        rv = 0;
     }
 
  out:
-    xfree(name);
     spin_unlock(&sel_sem);
     return rv;
 }
 
-static int flask_security_commit_bools(char *buf, uint32_t count)
+static int flask_security_commit_bools(void)
 {
-    int length = -EFAULT;
-    int new_value;
+    int rv;
 
     spin_lock(&sel_sem);
 
-    length = domain_has_security(current->domain, SECURITY__SETBOOL);
-    if ( length )
-        goto out;
-
-    length = -EINVAL;
-    if ( sscanf(buf, "%d", &new_value) != 1 )
+    rv = domain_has_security(current->domain, SECURITY__SETBOOL);
+    if ( rv )
         goto out;
 
-    if ( new_value && bool_pending_values )
-        security_set_bools(bool_num, bool_pending_values);
+    if ( bool_pending_values )
+        rv = security_set_bools(bool_num, bool_pending_values);
     
-    length = count;
-
  out:
     spin_unlock(&sel_sem);
-    return length;
+    return rv;
 }
 
-static int flask_security_get_bool(char *buf, uint32_t count, int named)
+static int flask_security_get_bool(struct xen_flask_boolean *arg)
 {
-    int length;
-    int i, cur_enforcing, pend_enforcing;
-    char* name = NULL;
-    
-    spin_lock(&sel_sem);
-    
-    length = -EINVAL;
-    if ( sscanf(buf, "%d", &i) != 1 )
-        goto out;
+    int rv;
 
-    cur_enforcing = security_get_bool_value(i);
-    if ( cur_enforcing < 0 )
-    {
-        length = cur_enforcing;
-        goto out;
-    }
+    rv = flask_security_resolve_bool(arg);
+    if ( rv )
+        return rv;
 
-    if ( bool_pending_values )
-        pend_enforcing = bool_pending_values[i];
-    else
-        pend_enforcing = cur_enforcing;
+    spin_lock(&sel_sem);
 
-    if ( named )
-        name = security_get_bool_name(i);
-    if ( named && !name )
+    rv = security_get_bool_value(arg->bool_id);
+    if ( rv < 0 )
         goto out;
 
-    memset(buf, 0, count);
-    if ( named )
-        length = snprintf(buf, count, "%d %d %s", cur_enforcing,
-                          pend_enforcing, name);
-    else
-        length = snprintf(buf, count, "%d %d", cur_enforcing,
-                          pend_enforcing);
+    arg->enforcing = rv;
 
- out:
-    xfree(name);
-    spin_unlock(&sel_sem);
-    return length;
-}
+    if ( bool_pending_values )
+        arg->pending = bool_pending_values[arg->bool_id];
+    else
+        arg->pending = rv;
 
-static int flask_security_get_bool_name(char *buf, uint32_t count)
-{
-    int rv = -ENOENT;
-    int i, cur_enforcing, pend_enforcing;
-    
-    spin_lock(&sel_sem);
-    
-    i = security_find_bool(buf);
-    if ( i < 0 )
-        goto out;
+    rv = 0;
 
-    cur_enforcing = security_get_bool_value(i);
-    if ( cur_enforcing < 0 )
+    if ( arg->size )
     {
-        rv = cur_enforcing;
-        goto out;
+        char *nameout = security_get_bool_name(arg->bool_id);
+        size_t nameout_len = strlen(nameout);
+        if ( nameout_len > arg->size )
+            rv = -ERANGE;
+        arg->size = nameout_len;
+ 
+        if ( !rv && copy_to_guest(arg->name, nameout, nameout_len) )
+            rv = -EFAULT;
+        xfree(nameout);
     }
 
-    if ( bool_pending_values )
-        pend_enforcing = bool_pending_values[i];
-    else
-        pend_enforcing = cur_enforcing;
-
-    memset(buf, 0, count);
-    rv = snprintf(buf, count, "%d %d", cur_enforcing, pend_enforcing);
-
  out:
     spin_unlock(&sel_sem);
     return rv;
@@ -779,380 +451,212 @@ static int flask_security_make_bools(void)
 
 #ifdef FLASK_AVC_STATS
 
-static int flask_security_avc_cachestats(char *buf, uint32_t count)
+static int flask_security_avc_cachestats(struct xen_flask_cache_stats *arg)
 {
-    char *page = NULL;
-    int len = 0;
-    int length = 0;
-    int cpu;
     struct avc_cache_stats *st;
 
-    page = (char *)xmalloc_bytes(PAGE_SIZE);
-    if ( !page )
-        return -ENOMEM;
-    memset(page, 0, PAGE_SIZE);
+    if ( arg->cpu > nr_cpu_ids )
+        return -ENOENT;
+    if ( !cpu_online(arg->cpu) )
+        return -ENOENT;
 
-    len = snprintf(page, PAGE_SIZE, "lookups hits misses allocations reclaims "
-                   "frees\n");
-    if ( len > count ) {
-        length = -EINVAL;
-        goto out;
-    }
-    
-    memcpy(buf, page, len);
-    buf += len;
-    length += len;
-    count -= len;
+    st = &per_cpu(avc_cache_stats, arg->cpu);
 
-    for_each_online_cpu ( cpu )
-    {
-        st = &per_cpu(avc_cache_stats, cpu);
+    arg->lookups = st->lookups;
+    arg->hits = st->hits;
+    arg->misses = st->misses;
+    arg->allocations = st->allocations;
+    arg->reclaims = st->reclaims;
+    arg->frees = st->frees;
 
-        len = snprintf(page, PAGE_SIZE, "%u %u %u %u %u %u\n", st->lookups,
-                       st->hits, st->misses, st->allocations,
-                       st->reclaims, st->frees);
-        if ( len > count ) {
-            length = -EINVAL;
-            goto out;
-        }
-        memcpy(buf, page, len);
-        buf += len;
-        length += len;
-        count -= len;
-    }
-
- out:
-    xfree(page);    
-    return length;
+    return 0;
 }
 
 #endif
 
-static int flask_security_load(char *buf, uint32_t count)
+static int flask_security_load(struct xen_flask_load *load)
 {
     int ret;
-    int length;
-
-    spin_lock(&sel_sem);
+    void *buf = NULL;
 
-    length = domain_has_security(current->domain, SECURITY__LOAD_POLICY);
-    if ( length )
-        goto out;
-
-    length = security_load_policy(buf, count);
-    if ( length )
-        goto out;
-
-    ret = flask_security_make_bools();
+    ret = domain_has_security(current->domain, SECURITY__LOAD_POLICY);
     if ( ret )
-        length = ret;
-    else
-        length = count;
+        return ret;
 
- out:
-    spin_unlock(&sel_sem);
-    return length;
-}
-
-static int flask_ocontext_del(char *buf, uint32_t size)
-{
-    int len = 0;
-    char *ocontext;
-    unsigned long low  = 0;
-    unsigned long high = 0;
-
-    len = domain_has_security(current->domain, SECURITY__DEL_OCONTEXT);
-    if ( len )
-        return len;
+    if ( load->size > MAX_POLICY_SIZE )
+        return -EINVAL;
 
-    if ( (ocontext = xmalloc_bytes(size) ) == NULL )
+    buf = xmalloc_bytes(load->size);
+    if ( !buf )
         return -ENOMEM;
 
-    len = sscanf(buf, "%s %lu %lu", ocontext, &low, &high);
-    if ( len < 2 )
+    if ( copy_from_guest(buf, load->buffer, load->size) )
     {
-        len = -EINVAL;
-        goto out;
+        ret = -EFAULT;
+        goto out_free;
     }
-    else if ( len == 2 )
-        high = low;
 
-    if ( low > high )
-    {
-        len = -EINVAL;
+    spin_lock(&sel_sem);
+
+    ret = security_load_policy(buf, load->size);
+    if ( ret )
         goto out;
-    }
 
-    len = security_ocontext_del(ocontext, low, high);
+    xfree(bool_pending_values);
+    bool_pending_values = NULL;
+    ret = 0;
+
  out:
-    xfree(ocontext);
-    return len;
+    spin_unlock(&sel_sem);
+ out_free:
+    xfree(buf);
+    return ret;
 }
 
-static int flask_ocontext_add(char *buf, uint32_t size)
+static int flask_ocontext_del(struct xen_flask_ocontext *arg)
 {
-    int len = 0;
-    u32 sid = 0;
-    unsigned long low  = 0;
-    unsigned long high = 0;
-    char *scontext;
-    char *ocontext;
-
-    len = domain_has_security(current->domain, SECURITY__ADD_OCONTEXT);
-    if ( len )
-        return len;
-
-    if ( (scontext = xmalloc_bytes(size) ) == NULL )
-        return -ENOMEM;
+    int rv;
 
-    if ( (ocontext = xmalloc_bytes(size) ) == NULL )
-    {
-        xfree(scontext);
-        return -ENOMEM;
-    }
-
-    memset(scontext, 0, size);
-    memset(ocontext, 0, size);
+    if ( arg->low > arg->high )
+        return -EINVAL;
 
-    len = sscanf(buf, "%s %s %lu %lu", ocontext, scontext, &low, &high);
-    if ( len < 3 )
-    {
-        len = -EINVAL;
-        goto out;
-    }
-    else if ( len == 3 )
-        high = low;
+    rv = domain_has_security(current->domain, SECURITY__DEL_OCONTEXT);
+    if ( rv )
+        return rv;
 
-    if ( low > high )
-    {
-        len = -EINVAL;
-        goto out;
-    }
-    len = security_context_to_sid(scontext, strlen(scontext)+1, &sid);
-    if ( len < 0 )
-    {
-        len = -EINVAL;
-        goto out;
-    }
-    len = security_ocontext_add(ocontext, low, high, sid);
- out:
-    xfree(ocontext);
-    xfree(scontext);
-    return len;
+    return security_ocontext_del(arg->ocon, arg->low, arg->high);
 }
 
-long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op)
+static int flask_ocontext_add(struct xen_flask_ocontext *arg)
 {
-    flask_op_t curop, *op = &curop;
-    int rc = 0;
-    int length = 0;
-    char *arg = NULL;
+    int rv;
 
-    if ( copy_from_guest(op, u_flask_op, 1) )
-        return -EFAULT;
-
-    if ( op->cmd > FLASK_LAST)
+    if ( arg->low > arg->high )
         return -EINVAL;
 
-    if ( op->size > MAX_POLICY_SIZE )
-        return -EINVAL;
+    rv = domain_has_security(current->domain, SECURITY__ADD_OCONTEXT);
+    if ( rv )
+        return rv;
 
-    if ( (op->buf == NULL && op->size != 0) || 
-         (op->buf != NULL && op->size == 0) )
-        return -EINVAL;
+    return security_ocontext_add(arg->ocon, arg->low, arg->high, arg->sid);
+}
 
-    arg = xmalloc_bytes(op->size + 1);
-    if ( !arg )
-        return -ENOMEM;
+long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op)
+{
+    xen_flask_op_t op;
+    int rv;
 
-    memset(arg, 0, op->size + 1);
+    if ( copy_from_guest(&op, u_flask_op, 1) )
+        return -EFAULT;
 
-    if ( (FLASK_COPY_IN&(1UL<<op->cmd)) && op->buf != NULL && 
-         copy_from_guest(arg, guest_handle_from_ptr(op->buf, char), op->size) )
-    {
-        rc = -EFAULT;
-        goto out;
-    }
+    if ( op.interface_version != XEN_FLASK_INTERFACE_VERSION )
+        return -ENOSYS;
 
-    switch ( op->cmd )
+    switch ( op.cmd )
     {
-
     case FLASK_LOAD:
-    {
-        length = flask_security_load(arg, op->size);
-    }
-    break;
-    
+        rv = flask_security_load(&op.u.load);
+        break;
+
     case FLASK_GETENFORCE:
-    {
-        length = snprintf(arg, op->size, "%d", flask_enforcing);
-    }
-    break;    
+        rv = flask_enforcing;
+        break;
 
     case FLASK_SETENFORCE:
-    {
-        length = flask_security_setenforce(arg, op->size);
-    }
-    break;    
+        rv = flask_security_setenforce(&op.u.enforce);
+        break;
 
     case FLASK_CONTEXT_TO_SID:
-    {
-        length = flask_security_context(arg, op->size);
-    }
-    break;    
+        rv = flask_security_context(&op.u.sid_context);
+        break;
 
     case FLASK_SID_TO_CONTEXT:
-    {
-        length = flask_security_sid(arg, op->size);
-    }
-    break; 
+        rv = flask_security_sid(&op.u.sid_context);
+        break;
 
     case FLASK_ACCESS:
-    {
-        length = flask_security_access(arg, op->size);
-    }
-    break;    
+        rv = flask_security_access(&op.u.access);
+        break;
 
     case FLASK_CREATE:
-    {
-        length = flask_security_create(arg, op->size);
-    }
-    break;    
+        rv = flask_security_create(&op.u.transition);
+        break;
 
     case FLASK_RELABEL:
-    {
-        length = flask_security_relabel(arg, op->size);
-    }
-    break;
+        rv = flask_security_relabel(&op.u.transition);
+        break;
 
     case FLASK_USER:
-    {
-        length = flask_security_user(arg, op->size);
-    }
-    break;    
+        rv = flask_security_user(&op.u.userlist);
+        break;
 
     case FLASK_POLICYVERS:
-    {
-        length = snprintf(arg, op->size, "%d", POLICYDB_VERSION_MAX);
-    }
-    break;    
+        rv = POLICYDB_VERSION_MAX;
+        break;
 
     case FLASK_GETBOOL:
-    {
-        length = flask_security_get_bool(arg, op->size, 0);
-    }
-    break;
+        rv = flask_security_get_bool(&op.u.boolean);
+        break;
 
     case FLASK_SETBOOL:
-    {
-        length = flask_security_set_bool(arg, op->size);
-    }
-    break;
+        rv = flask_security_set_bool(&op.u.boolean);
+        break;
 
     case FLASK_COMMITBOOLS:
-    {
-        length = flask_security_commit_bools(arg, op->size);
-    }
-    break;
+        rv = flask_security_commit_bools();
+        break;
 
     case FLASK_MLS:
-    {
-        length = snprintf(arg, op->size, "%d", flask_mls_enabled);
-    }
-    break;    
+        rv = flask_mls_enabled;
+        break;    
 
     case FLASK_DISABLE:
-    {
-        length = flask_security_disable(arg, op->size);
-    }
-    break;    
+        rv = flask_disable();
+        break;
 
     case FLASK_GETAVC_THRESHOLD:
-    {
-        length = snprintf(arg, op->size, "%d", avc_cache_threshold);
-    }
-    break;
+        rv = avc_cache_threshold;
+        break;
 
     case FLASK_SETAVC_THRESHOLD:
-    {
-        length = flask_security_setavc_threshold(arg, op->size);
-    }
-    break;
+        rv = flask_security_setavc_threshold(&op.u.setavc_threshold);
+        break;
 
     case FLASK_AVC_HASHSTATS:
-    {
-        length = avc_get_hash_stats(arg, op->size);
-    }
-    break;
+        rv = avc_get_hash_stats(&op.u.hash_stats);
+        break;
 
-#ifdef FLASK_AVC_STATS    
+#ifdef FLASK_AVC_STATS
     case FLASK_AVC_CACHESTATS:
-    {
-        length = flask_security_avc_cachestats(arg, op->size);
-    }
-    break;
+        rv = flask_security_avc_cachestats(&op.u.cache_stats);
+        break;
 #endif
 
     case FLASK_MEMBER:
-    {
-        length = flask_security_member(arg, op->size);
-    }
-    break;    
+        rv = flask_security_member(&op.u.transition);
+        break;
 
     case FLASK_ADD_OCONTEXT:
-    {
-        length = flask_ocontext_add(arg, op->size);
+        rv = flask_ocontext_add(&op.u.ocontext);
         break;
-    }
 
     case FLASK_DEL_OCONTEXT:
-    {
-        length = flask_ocontext_del(arg, op->size);
+        rv = flask_ocontext_del(&op.u.ocontext);
         break;
-    }
-
-    case FLASK_GETBOOL_NAMED:
-    {
-        length = flask_security_get_bool_name(arg, op->size);
-    }
-    break;
-
-    case FLASK_GETBOOL2:
-    {
-        length = flask_security_get_bool(arg, op->size, 1);
-    }
-    break;
-
-    case FLASK_SETBOOL_NAMED:
-    {
-        length = flask_security_set_bool_name(arg, op->size);
-    }
-    break;
 
     default:
-        length = -ENOSYS;
-        break;
-
+        rv = -ENOSYS;
     }
 
-    if ( length < 0 )
-    {
-        rc = length;
+    if ( rv < 0 )
         goto out;
-    }
-    
-    if ( (FLASK_COPY_OUT&(1UL<<op->cmd)) && op->buf != NULL && 
-         copy_to_guest(guest_handle_from_ptr(op->buf, char), arg, op->size) )
+
+    if ( (FLASK_COPY_OUT&(1UL<<op.cmd)) )
     {
-        rc = -EFAULT;
-        goto out;
+        if ( copy_to_guest(u_flask_op, &op, 1) )
+            rv = -EFAULT;
     }
 
-    op->size = length;
-    if ( copy_to_guest(u_flask_op, op, 1) )
-        rc = -EFAULT;
-
  out:
-    xfree(arg);
-    return rc;
+    return rv;
 }
diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h
index 8fffbb6..0f62891 100644
--- a/xen/xsm/flask/include/avc.h
+++ b/xen/xsm/flask/include/avc.h
@@ -104,7 +104,8 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, 
u32 tsid,
                                     u32 ssid, u32 tsid, u16 tclass, u32 perms);
 
 /* Exported to selinuxfs */
-int avc_get_hash_stats(char *buf, uint32_t size);
+struct xen_flask_hash_stats;
+int avc_get_hash_stats(struct xen_flask_hash_stats *arg);
 extern unsigned int avc_cache_threshold;
 
 #ifdef FLASK_AVC_STATS
diff --git a/xen/xsm/flask/include/security.h b/xen/xsm/flask/include/security.h
index 67ca6d0..348f018 100644
--- a/xen/xsm/flask/include/security.h
+++ b/xen/xsm/flask/include/security.h
@@ -90,8 +90,8 @@ int security_iterate_iomem_sids(unsigned long start, unsigned 
long end,
 int security_iterate_ioport_sids(u32 start, u32 end,
                                 security_iterate_fn fn, void *data);
 
-int security_ocontext_add(char *ocontext, unsigned long low,
+int security_ocontext_add(u32 ocontext, unsigned long low,
                            unsigned long high, u32 sid);
 
-int security_ocontext_del(char *ocontext, unsigned int low, unsigned int high);
+int security_ocontext_del(u32 ocontext, unsigned int low, unsigned int high);
 #endif /* _FLASK_SECURITY_H_ */
diff --git a/xen/xsm/flask/ss/services.c b/xen/xsm/flask/ss/services.c
index 0189baf..363f586 100644
--- a/xen/xsm/flask/ss/services.c
+++ b/xen/xsm/flask/ss/services.c
@@ -2097,17 +2097,14 @@ int determine_ocontext( char *ocontext )
         return -1;
 }
 
-int security_ocontext_add( char *ocontext, unsigned long low, unsigned long 
high
+int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
                             ,u32 sid )
 {
     int ret = 0;
-    int ocon = 0;
     struct ocontext *c;
     struct ocontext *prev;
     struct ocontext *add;
 
-    if ( (ocon = determine_ocontext(ocontext)) < 0 )
-        return -EINVAL;
     if ( (add = xmalloc(struct ocontext)) == NULL )
         return -ENOMEM;
     memset(add, 0, sizeof(struct ocontext));
@@ -2254,15 +2251,11 @@ int security_ocontext_add( char *ocontext, unsigned 
long low, unsigned long high
     return ret;
 }
 
-int security_ocontext_del( char *ocontext, unsigned int low, unsigned int high 
)
+int security_ocontext_del( u32 ocon, unsigned int low, unsigned int high )
 {
     int ret = 0;
-    int ocon = 0;
     struct ocontext *c, *before_c;
 
-    if ( (ocon = determine_ocontext(ocontext)) < 0 )
-        return -EINVAL;
-
     POLICY_WRLOCK;
     switch( ocon )
     {
-- 
1.7.7.6


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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