WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] xsm: Dynamic update to device ocontexts

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xsm: Dynamic update to device ocontexts
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 13 Nov 2009 14:05:19 -0800
Delivery-date: Fri, 13 Nov 2009 14:05:40 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1258149619 0
# Node ID b6bbc0c9e6515b60e550e21d22ca88afdeecd00f
# Parent  e39cec51aebc38fa7c464c867c21c4c3a7ffb1ef
xsm: Dynamic update to device ocontexts

Added the ability to add and delete ocontexts dynamically on a running
system.  Two new commands have been added to the xsm hypercall, add
and delete ocontext.  Twelve new library functions have been
implemented that use the hypercall commands to label and unlabel
pirqs, PCI devices, I/O ports and memory.  The base policy has been
updated so dom0 has the ability to use the hypercall commands by
default.  Items added to the list will not be present next time the
system reloads.  They will need to be added to the static policy.

Signed-off-by : George Coker <gscoker@xxxxxxxxxxxxxx>
Signed-off-by : Paul Nuzzi <pjnuzzi@xxxxxxxxxxxxxx>
---
 tools/flask/libflask/flask_op.c                |  233 +++++++++++++++++++++
 tools/flask/libflask/include/flask.h           |   19 +
 tools/flask/policy/policy/flask/access_vectors |    2 
 tools/flask/policy/policy/modules/xen/xen.te   |    2 
 xen/include/public/xsm/flask_op.h              |    4 
 xen/xsm/flask/flask_op.c                       |  103 +++++++++
 xen/xsm/flask/include/av_perm_to_string.h      |    2 
 xen/xsm/flask/include/av_permissions.h         |    2 
 xen/xsm/flask/include/security.h               |    4 
 xen/xsm/flask/ss/services.c                    |  274 +++++++++++++++++++++++++
 10 files changed, 642 insertions(+), 3 deletions(-)

diff -r e39cec51aebc -r b6bbc0c9e651 tools/flask/libflask/flask_op.c
--- a/tools/flask/libflask/flask_op.c   Fri Nov 13 21:59:20 2009 +0000
+++ b/tools/flask/libflask/flask_op.c   Fri Nov 13 22:00:19 2009 +0000
@@ -109,3 +109,236 @@ int flask_setenforce(int xc_handle, int 
 
     return 0;
 }
+
+int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *pirq_s = OCON_PIRQ_STR;
+    int size = INITCONTEXTLEN + strlen(pirq_s) + (sizeof(unsigned int)) +
+                (sizeof(char) * 3);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_ADD_OCONTEXT;
+    snprintf(buf, size, "%s %255s %u", pirq_s, scontext, pirq);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
+                      char *scontext)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *ioport = OCON_IOPORT_STR;
+    int size = INITCONTEXTLEN + strlen(ioport) +
+                (sizeof(unsigned long) * 2) + (sizeof(char) * 4);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_ADD_OCONTEXT;
+    snprintf(buf, size, "%s %255s %li %li", ioport, scontext, low, high);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
+                     char *scontext)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *iomem = OCON_IOMEM_STR;
+    int size = INITCONTEXTLEN + strlen(iomem) +
+                (sizeof(unsigned long) * 2) + (sizeof(char) * 4);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_ADD_OCONTEXT;
+    snprintf(buf, size, "%s %255s %li %li", iomem, scontext, low, high);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_add_device(int xc_handle, unsigned long device, char *scontext)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *dev = OCON_DEVICE_STR;
+    int size = INITCONTEXTLEN + strlen(dev) + (sizeof(unsigned long)) +
+                (sizeof(char) * 3);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_ADD_OCONTEXT;
+    snprintf(buf, size, "%s %255s %li", dev, scontext, device);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_del_pirq(int xc_handle, unsigned int pirq)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *pirq_s = OCON_PIRQ_STR;
+    int size = strlen(pirq_s) + (sizeof(unsigned int)) +
+                (sizeof(char) * 2);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_DEL_OCONTEXT;
+    snprintf(buf, size, "%s %u", pirq_s, pirq);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *ioport = OCON_IOPORT_STR;
+    int size = strlen(ioport) + (sizeof(unsigned long) * 2) +
+                (sizeof(char) * 3);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_DEL_OCONTEXT;
+    snprintf(buf, size, "%s %li %li", ioport, low, high);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *iomem = OCON_IOMEM_STR;
+    int size = strlen(iomem) + (sizeof(unsigned long) * 2) +
+                (sizeof(char) * 3);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_DEL_OCONTEXT;
+    snprintf(buf, size, "%s %li %li", iomem, low, high);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
+
+int flask_del_device(int xc_handle, unsigned long device)
+{
+    int err;
+    flask_op_t op;
+    char *buf;
+    char *dev = OCON_DEVICE_STR;
+    int size = strlen(dev) + (sizeof(unsigned long)) + (sizeof(char) * 2);
+
+    if ( (buf = (char *) malloc(size)) == NULL )
+        return -ENOMEM;
+    memset(buf, 0, size);
+
+    op.cmd = FLASK_DEL_OCONTEXT;
+    snprintf(buf, size, "%s %li", dev, device);
+    op.buf = buf;
+    op.size = size;
+
+    if ( (err = xc_flask_op(xc_handle, &op)) != 0 )
+    {
+        free(buf);
+        return err;
+    }
+
+    free(buf);
+    return 0;
+
+}
diff -r e39cec51aebc -r b6bbc0c9e651 tools/flask/libflask/include/flask.h
--- a/tools/flask/libflask/include/flask.h      Fri Nov 13 21:59:20 2009 +0000
+++ b/tools/flask/libflask/include/flask.h      Fri Nov 13 22:00:19 2009 +0000
@@ -20,5 +20,24 @@ int flask_sid_to_context(int xc_handle, 
 int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size);
 int flask_getenforce(int xc_handle);
 int flask_setenforce(int xc_handle, int mode);
+int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext);
+int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
+                      char *scontext);
+int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
+                     char *scontext);
+int flask_add_device(int xc_handle, unsigned long device, char *scontext);
+int flask_del_pirq(int xc_handle, unsigned int pirq);
+int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high);
+int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high);
+int flask_del_device(int xc_handle, unsigned long device);
+#define flask_add_single_ioport(x, l, s) flask_add_ioport(x, l, l, s)
+#define flask_add_single_iomem(x, l, s) flask_add_iomem(x, l, l, s)
+#define flask_del_single_ioport(x, l) flask_del_ioport(x, l, l)
+#define flask_del_single_iomem(x, l) flask_del_iomem(x, l, l);
 
+#define OCON_PIRQ_STR   "pirq"
+#define OCON_IOPORT_STR "ioport"
+#define OCON_IOMEM_STR  "iomem"
+#define OCON_DEVICE_STR "pcidevice"
+#define INITCONTEXTLEN  256
 #endif /* __FLASK_H__ */
diff -r e39cec51aebc -r b6bbc0c9e651 
tools/flask/policy/policy/flask/access_vectors
--- a/tools/flask/policy/policy/flask/access_vectors    Fri Nov 13 21:59:20 
2009 +0000
+++ b/tools/flask/policy/policy/flask/access_vectors    Fri Nov 13 22:00:19 
2009 +0000
@@ -163,4 +163,6 @@ class security
        setenforce
        setbool
        setsecparam
+        add_ocontext
+        del_ocontext
 }
diff -r e39cec51aebc -r b6bbc0c9e651 
tools/flask/policy/policy/modules/xen/xen.te
--- a/tools/flask/policy/policy/modules/xen/xen.te      Fri Nov 13 21:59:20 
2009 +0000
+++ b/tools/flask/policy/policy/modules/xen/xen.te      Fri Nov 13 22:00:19 
2009 +0000
@@ -51,7 +51,7 @@ allow dom0_t xen_t:xen firmware;
 
 allow dom0_t security_t:security {compute_av compute_create compute_member 
 check_context load_policy compute_relabel compute_user setenforce setbool
-setsecparam};
+setsecparam add_ocontext del_ocontext};
 
 create_channel(dom0_t, dom0_t, evchn0-0_t)
 allow dom0_t evchn0-0_t:event {send};
diff -r e39cec51aebc -r b6bbc0c9e651 xen/include/public/xsm/flask_op.h
--- a/xen/include/public/xsm/flask_op.h Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/include/public/xsm/flask_op.h Fri Nov 13 22:00:19 2009 +0000
@@ -31,8 +31,10 @@
 #define FLASK_AVC_HASHSTATS     18
 #define FLASK_AVC_CACHESTATS    19
 #define FLASK_MEMBER            20
+#define FLASK_ADD_OCONTEXT      21
+#define FLASK_DEL_OCONTEXT      22
 
-#define FLASK_LAST              FLASK_MEMBER
+#define FLASK_LAST              FLASK_DEL_OCONTEXT
 
 typedef struct flask_op {
     uint32_t  cmd;
diff -r e39cec51aebc -r b6bbc0c9e651 xen/xsm/flask/flask_op.c
--- a/xen/xsm/flask/flask_op.c  Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/xsm/flask/flask_op.c  Fri Nov 13 22:00:19 2009 +0000
@@ -45,7 +45,9 @@ integer_param("flask_enabled", flask_ena
         1UL<<FLASK_COMMITBOOLS | \
         1UL<<FLASK_DISABLE | \
         1UL<<FLASK_SETAVC_THRESHOLD | \
-        1UL<<FLASK_MEMBER \
+        1UL<<FLASK_MEMBER | \
+        1UL<<FLASK_ADD_OCONTEXT | \
+        1UL<<FLASK_DEL_OCONTEXT \
     )
 
 #define FLASK_COPY_OUT \
@@ -752,6 +754,93 @@ out:
     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 ( (ocontext = xmalloc_bytes(size) ) == NULL )
+        return -ENOMEM;
+
+    len = sscanf(buf, "%s %li %li", ocontext, &low, &high);
+    if ( len < 2 )
+    {
+        len = -EINVAL;
+        goto out;
+    }
+    else if ( len == 2 )
+        high = low;
+
+    if ( low > high )
+    {
+        len = -EINVAL;
+        goto out;
+    }
+
+    len = security_ocontext_del(ocontext, low, high);
+  out:
+    xfree(ocontext);
+    return len;
+}
+
+static int flask_ocontext_add(char *buf, uint32_t size)
+{
+    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;
+
+    if ( (ocontext = xmalloc_bytes(size) ) == NULL )
+    {
+        xfree(scontext);
+        return -ENOMEM;
+    }
+
+    memset(scontext, 0, size);
+    memset(ocontext, 0, size);
+
+    len = sscanf(buf, "%s %s %li %li", ocontext, scontext, &low, &high);
+    if ( len < 3 )
+    {
+        len = -EINVAL;
+        goto out;
+    }
+    else if ( len == 3 )
+        high = low;
+
+    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;
+}
+
 long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op)
 {
     flask_op_t curop, *op = &curop;
@@ -910,6 +999,18 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op
     }
     break;    
 
+    case FLASK_ADD_OCONTEXT:
+    {
+        length = flask_ocontext_add(arg, op->size);
+        break;
+    }
+
+    case FLASK_DEL_OCONTEXT:
+    {
+        length = flask_ocontext_del(arg, op->size);
+        break;
+    }
+
     default:
         length = -ENOSYS;
         break;
diff -r e39cec51aebc -r b6bbc0c9e651 xen/xsm/flask/include/av_perm_to_string.h
--- a/xen/xsm/flask/include/av_perm_to_string.h Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/xsm/flask/include/av_perm_to_string.h Fri Nov 13 22:00:19 2009 +0000
@@ -110,3 +110,5 @@
    S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce")
    S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool")
    S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam")
+   S_(SECCLASS_SECURITY, SECURITY__ADD_OCONTEXT, "add_ocontext")
+   S_(SECCLASS_SECURITY, SECURITY__DEL_OCONTEXT, "del_ocontext")
diff -r e39cec51aebc -r b6bbc0c9e651 xen/xsm/flask/include/av_permissions.h
--- a/xen/xsm/flask/include/av_permissions.h    Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/xsm/flask/include/av_permissions.h    Fri Nov 13 22:00:19 2009 +0000
@@ -118,4 +118,6 @@
 #define SECURITY__SETENFORCE                      0x00000080UL
 #define SECURITY__SETBOOL                         0x00000100UL
 #define SECURITY__SETSECPARAM                     0x00000200UL
+#define SECURITY__ADD_OCONTEXT                    0x00000400UL
+#define SECURITY__DEL_OCONTEXT                    0x00000800UL
 
diff -r e39cec51aebc -r b6bbc0c9e651 xen/xsm/flask/include/security.h
--- a/xen/xsm/flask/include/security.h  Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/xsm/flask/include/security.h  Fri Nov 13 22:00:19 2009 +0000
@@ -82,4 +82,8 @@ int security_validate_transition(u32 old
 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
                                                                     u16 
tclass);
 
+int security_ocontext_add(char *ocontext, unsigned long low,
+                           unsigned long high, u32 sid);
+
+int security_ocontext_del(char *ocontext, unsigned int low, unsigned int high);
 #endif /* _FLASK_SECURITY_H_ */
diff -r e39cec51aebc -r b6bbc0c9e651 xen/xsm/flask/ss/services.c
--- a/xen/xsm/flask/ss/services.c       Fri Nov 13 21:59:20 2009 +0000
+++ b/xen/xsm/flask/ss/services.c       Fri Nov 13 22:00:19 2009 +0000
@@ -1942,3 +1942,277 @@ out:
     xfree(bvalues);
     return rc;
 }
+
+int determine_ocontext( char *ocontext )
+{
+    if ( strcmp(ocontext, "pirq") == 0 )
+        return OCON_PIRQ;
+    else if ( strcmp(ocontext, "ioport") == 0 )
+        return OCON_IOPORT;
+    else if ( strcmp(ocontext, "iomem") == 0 )
+        return OCON_IOMEM;
+    else if ( strcmp(ocontext, "pcidevice") == 0 )
+        return OCON_DEVICE;
+    else
+        return -1;
+}
+
+int security_ocontext_add( char *ocontext, unsigned long low, unsigned long 
high
+                            ,u32 sid )
+{
+    int ret = 0;
+    int ocon = 0;
+    struct ocontext *c;
+    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));
+    add->sid[0] = sid;
+
+    POLICY_WRLOCK;
+    switch( ocon )
+    {
+    case OCON_PIRQ:
+        add->u.pirq = (u16)low;
+        if ( high != low )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
+        c = policydb.ocontexts[OCON_PIRQ];
+        while ( c )
+        {
+            if ( c->u.pirq == add->u.pirq )
+            {
+                printk("%s: Duplicate pirq %d\n", __FUNCTION__, add->u.pirq);
+                ret = -EINVAL;
+                break;
+            }
+            c = c->next;
+        }
+
+        if ( ret == 0 )
+        {
+            add->next = policydb.ocontexts[OCON_PIRQ];
+            policydb.ocontexts[OCON_PIRQ] = add;
+        }
+        break;
+
+    case OCON_IOPORT:
+        add->u.ioport.low_ioport = low;
+        add->u.ioport.high_ioport = high;
+
+        c = policydb.ocontexts[OCON_IOPORT];
+        while ( c )
+        {
+            if ( c->u.ioport.low_ioport <= add->u.ioport.high_ioport &&
+                 add->u.ioport.low_ioport <= c->u.ioport.high_ioport )
+            {
+                printk("%s: IO Port overlap with entry 0x%x - 0x%x\n",
+                       __FUNCTION__, c->u.ioport.low_ioport,
+                       c->u.ioport.high_ioport);
+                ret = -EINVAL;
+                break;
+            }
+            c = c->next;
+        }
+
+        if ( ret == 0 )
+        {
+            add->next = policydb.ocontexts[OCON_IOPORT];
+            policydb.ocontexts[OCON_IOPORT] = add;
+        }
+        break;
+
+    case OCON_IOMEM:
+        add->u.iomem.low_iomem = low;
+        add->u.iomem.high_iomem = high;
+
+        c = policydb.ocontexts[OCON_IOMEM];
+        while ( c )
+        {
+            if ( c->u.iomem.low_iomem <= add->u.iomem.high_iomem &&
+                 add->u.iomem.low_iomem <= c->u.iomem.high_iomem )
+            {
+                printk("%s: IO Memory overlap with entry 0x%x - 0x%x\n",
+                       __FUNCTION__, c->u.iomem.low_iomem,
+                       c->u.iomem.high_iomem);
+                ret = -EINVAL;
+                break;
+            }
+            c = c->next;
+        }
+
+        if ( ret == 0 )
+        {
+            add->next = policydb.ocontexts[OCON_IOMEM];
+            policydb.ocontexts[OCON_IOMEM] = add;
+        }
+        break;
+
+     case OCON_DEVICE:
+        add->u.device = low;
+        if ( high != low )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
+        c = policydb.ocontexts[OCON_DEVICE];
+        while ( c )
+        {
+            if ( c->u.device == add->u.device )
+            {
+                printk("%s: Duplicate PCI Device 0x%x\n", __FUNCTION__,
+                        add->u.device);
+                ret = -EINVAL;
+                break;
+            }
+            c = c->next;
+        }
+
+        if ( ret == 0 )
+        {
+            add->next = policydb.ocontexts[OCON_DEVICE];
+            policydb.ocontexts[OCON_DEVICE] = add;
+        }
+        break;
+
+     default:
+         ret = -EINVAL;
+    }
+    POLICY_WRUNLOCK;
+
+    if ( ret != 0 )
+        xfree(add);
+    return ret;
+}
+
+int security_ocontext_del( char *ocontext, 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 )
+    {
+    case OCON_PIRQ:
+        for ( before_c = NULL, c = policydb.ocontexts[OCON_PIRQ];
+              c; before_c = c, c = c->next )
+        {
+            if ( c->u.pirq == low )
+            {
+                if ( before_c == NULL )
+                {
+                    policydb.ocontexts[OCON_PIRQ] = c->next;
+                    xfree(c);
+                    goto out;
+                }
+                else
+                {
+                    before_c->next = c->next;
+                    xfree(c);
+                    goto out;
+                }
+            }
+        }
+
+        printk("%s: ocontext not found: pirq %d\n", __FUNCTION__, low);
+        ret = -EINVAL;
+        break;
+
+    case OCON_IOPORT:
+        for ( before_c = NULL, c = policydb.ocontexts[OCON_IOPORT];
+              c; before_c = c, c = c->next )
+        {
+            if ( c->u.ioport.low_ioport == low &&
+                 c->u.ioport.high_ioport == high )
+            {
+                if ( before_c == NULL )
+                {
+                    policydb.ocontexts[OCON_IOPORT] = c->next;
+                    xfree(c);
+                    goto out;
+                }
+                else
+                {
+                    before_c->next = c->next;
+                    xfree(c);
+                    goto out;
+                }
+            }
+        }
+
+        printk("%s: ocontext not found: ioport 0x%x - 0x%x\n", __FUNCTION__,
+                low, high);
+        ret = -EINVAL;
+        break;
+
+    case OCON_IOMEM:
+        for ( before_c = NULL, c = policydb.ocontexts[OCON_IOMEM];
+              c; before_c = c, c = c->next )
+        {
+            if ( c->u.iomem.low_iomem == low &&
+                 c->u.iomem.high_iomem == high )
+            {
+                if ( before_c == NULL )
+                {
+                    policydb.ocontexts[OCON_IOMEM] = c->next;
+                    xfree(c);
+                    goto out;
+                }
+                else
+                {
+                    before_c->next = c->next;
+                    xfree(c);
+                    goto out;
+                }
+            }
+        }
+
+        printk("%s: ocontext not found: iomem 0x%x - 0x%x\n", __FUNCTION__,
+                low, high);
+        ret = -EINVAL;
+        break;
+
+    case OCON_DEVICE:
+        for ( before_c = NULL, c = policydb.ocontexts[OCON_DEVICE];
+              c; before_c = c, c = c->next )
+        {
+            if ( c->u.device == low )
+            {
+                if ( before_c == NULL )
+                {
+                    policydb.ocontexts[OCON_DEVICE] = c->next;
+                    xfree(c);
+                    goto out;
+                }
+                else
+                {
+                    before_c->next = c->next;
+                    xfree(c);
+                    goto out;
+                }
+            }
+        }
+
+        printk("%s: ocontext not found: pcidevice 0x%x\n", __FUNCTION__, low);
+        ret = -EINVAL;
+        break;
+
+    default:
+        ret = -EINVAL;
+    }
+
+  out:
+    POLICY_WRUNLOCK;
+    return ret;
+}

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xsm: Dynamic update to device ocontexts, Xen patchbot-unstable <=