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] This patch to the Xen access control module (ACM) and to

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] This patch to the Xen access control module (ACM) and tools:
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 21 Oct 2005 18:54:22 +0000
Delivery-date: Fri, 21 Oct 2005 18:53:17 +0000
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 1e40bed176d461512bdeb660bac797e8d41726ba
# Parent  6f5b94da963a9651814ecd1d112db5e5082f5c81
This patch to the Xen access control module (ACM) and tools:

  1. adapts ACM hooks to the slightly changed event channel structure
  2. introduces an ACM_GETDECISION command, which enables authorized 
domains to retrieve policy decisions regarding the sharing of resources 
(STE policy) from the Xen hypervisor
  3. includes cleanup (warnings I found when applying  analysis tools such 
as beam or flawfinder to the ACM code)

 The get_decision function is useful to enforce:
   *  the security policy on network traffic  in the network backends in 
domain 0; currently there is no enforcement in Dom0 and all packets flow 
freely
   *  the security policy in block device backends to control which 
domains can access which vdisk resources

I have added a small test program that shows how to use the get_decision 
ACM interface call, it is in tools/security/get_decision.c and will be 
compiled together with the policy tools. As usual, the ACM is unconfigured 
until you switch on a security policy on in Config.mk.

Signed-off: Reiner Sailer <sailer@xxxxxxxxxx>

diff -r 6f5b94da963a -r 1e40bed176d4 tools/security/Makefile
--- a/tools/security/Makefile   Thu Oct 20 18:37:41 2005
+++ b/tools/security/Makefile   Thu Oct 20 20:37:15 2005
@@ -43,6 +43,7 @@
 build: mk-symlinks
        $(MAKE) secpol_tool
        $(MAKE) secpol_xml2bin
+       $(MAKE) get_decision
        chmod 700 ./setlabel.sh
        chmod 700 ./updategrub.sh
        chmod 700 ./getlabel.sh
diff -r 6f5b94da963a -r 1e40bed176d4 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Thu Oct 20 18:37:41 2005
+++ b/tools/security/secpol_tool.c      Thu Oct 20 20:37:15 2005
@@ -67,7 +67,7 @@
                         (unsigned long) hypercall);
 }
 
-static inline int do_acm_op(int xc_handle, acm_op_t * op)
+static inline int do_acm_op(int xc_handle, struct acm_op * op)
 {
     int ret = -1;
     privcmd_hypercall_t hypercall;
@@ -275,10 +275,10 @@
 /******************************* get policy ******************************/
 
 #define PULL_CACHE_SIZE                8192
-u8 pull_buffer[PULL_CACHE_SIZE];
+uint8_t pull_buffer[PULL_CACHE_SIZE];
 int acm_domain_getpolicy(int xc_handle)
 {
-    acm_op_t op;
+    struct acm_op op;
     int ret;
 
     memset(pull_buffer, 0x00, sizeof(pull_buffer));
@@ -299,7 +299,7 @@
     struct stat mystat;
     int ret, fd;
     off_t len;
-    u8 *buffer;
+    uint8_t *buffer;
 
     if ((ret = stat(filename, &mystat)))
     {
@@ -321,7 +321,7 @@
     }
     if (len == read(fd, buffer, len))
     {
-        acm_op_t op;
+        struct acm_op op;
         /* dump it and then push it down into xen/acm */
         acm_dump_policy_buffer(buffer, len);
         op.cmd = ACM_SETPOLICY;
@@ -368,8 +368,8 @@
 #define PULL_STATS_SIZE                8192
 int acm_domain_dumpstats(int xc_handle)
 {
-    u8 stats_buffer[PULL_STATS_SIZE];
-    acm_op_t op;
+    uint8_t stats_buffer[PULL_STATS_SIZE];
+    struct acm_op op;
     int ret;
     struct acm_stats_buffer *stats;
 
@@ -442,7 +442,7 @@
     /* this includes header and a set of types */
     #define MAX_SSIDBUFFER  2000
     int ret, i;
-    acm_op_t op;
+    struct acm_op op;
     struct acm_ssid_buffer *hdr;
     unsigned char *buf;
        int nice_print = 1;
diff -r 6f5b94da963a -r 1e40bed176d4 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c   Thu Oct 20 18:37:41 2005
+++ b/xen/acm/acm_chinesewall_hooks.c   Thu Oct 20 20:37:15 2005
@@ -26,7 +26,10 @@
  *    in which case all types of a new domain must be conflict-free
  *    with all types of already running domains.
  *
+ * indent -i4 -kr -nut
+ *
  */
+
 #include <xen/config.h>
 #include <xen/errno.h>
 #include <xen/types.h>
@@ -48,270 +51,333 @@
  */
 int acm_init_chwall_policy(void)
 {
-       /* minimal startup policy; policy write-locked already */
-       chwall_bin_pol.max_types = 1;
-       chwall_bin_pol.max_ssidrefs = 2;
-       chwall_bin_pol.max_conflictsets = 1;
-       chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 
chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
-       chwall_bin_pol.conflict_sets = (domaintype_t 
*)xmalloc_array(domaintype_t, 
chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
-       chwall_bin_pol.running_types = (domaintype_t 
*)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
-       chwall_bin_pol.conflict_aggregate_set = (domaintype_t 
*)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
-       
-       if ((chwall_bin_pol.conflict_sets == NULL) || 
(chwall_bin_pol.running_types == NULL) ||
-           (chwall_bin_pol.ssidrefs == NULL) || 
(chwall_bin_pol.conflict_aggregate_set == NULL))
-               return ACM_INIT_SSID_ERROR;
-
-       /* initialize state */
-       memset((void *)chwall_bin_pol.ssidrefs, 0, 
chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t));
-       memset((void *)chwall_bin_pol.conflict_sets, 0, 
chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t));
-       memset((void *)chwall_bin_pol.running_types, 0, 
chwall_bin_pol.max_types*sizeof(domaintype_t));
-       memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, 
chwall_bin_pol.max_types*sizeof(domaintype_t));        
-       return ACM_OK;
-}
-
-static int
-chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
-{
-       struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
-       traceprintk("%s.\n", __func__);
-       if (chwall_ssidp == NULL)
-               return ACM_INIT_SSID_ERROR;
-       /* 
-        * depending on wheter chwall is primary or secondary, get the 
respective
-        * part of the global ssidref (same way we'll get the partial ssid 
pointer)
-        */
-       chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, 
ssidref);
-       if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) ||
-           (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)) {
-               printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset 
(0).\n",
-                       __func__, chwall_ssidp->chwall_ssidref);
-               xfree(chwall_ssidp);
-               return ACM_INIT_SSID_ERROR;
-       }
-       (*chwall_ssid) = chwall_ssidp;
-       printkd("%s: determined chwall_ssidref to %x.\n", 
-              __func__, chwall_ssidp->chwall_ssidref);
-       return ACM_OK;
-}
-
-static void
-chwall_free_domain_ssid(void *chwall_ssid)
-{
-       traceprintk("%s.\n", __func__);
-       if (chwall_ssid != NULL)
-               xfree(chwall_ssid);
-       return;
+    /* minimal startup policy; policy write-locked already */
+    chwall_bin_pol.max_types = 1;
+    chwall_bin_pol.max_ssidrefs = 2;
+    chwall_bin_pol.max_conflictsets = 1;
+    chwall_bin_pol.ssidrefs =
+        (domaintype_t *) xmalloc_array(domaintype_t,
+                                       chwall_bin_pol.max_ssidrefs *
+                                       chwall_bin_pol.max_types);
+    chwall_bin_pol.conflict_sets =
+        (domaintype_t *) xmalloc_array(domaintype_t,
+                                       chwall_bin_pol.max_conflictsets *
+                                       chwall_bin_pol.max_types);
+    chwall_bin_pol.running_types =
+        (domaintype_t *) xmalloc_array(domaintype_t,
+                                       chwall_bin_pol.max_types);
+    chwall_bin_pol.conflict_aggregate_set =
+        (domaintype_t *) xmalloc_array(domaintype_t,
+                                       chwall_bin_pol.max_types);
+
+    if ((chwall_bin_pol.conflict_sets == NULL)
+        || (chwall_bin_pol.running_types == NULL)
+        || (chwall_bin_pol.ssidrefs == NULL)
+        || (chwall_bin_pol.conflict_aggregate_set == NULL))
+        return ACM_INIT_SSID_ERROR;
+
+    /* initialize state */
+    memset((void *) chwall_bin_pol.ssidrefs, 0,
+           chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types *
+           sizeof(domaintype_t));
+    memset((void *) chwall_bin_pol.conflict_sets, 0,
+           chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types *
+           sizeof(domaintype_t));
+    memset((void *) chwall_bin_pol.running_types, 0,
+           chwall_bin_pol.max_types * sizeof(domaintype_t));
+    memset((void *) chwall_bin_pol.conflict_aggregate_set, 0,
+           chwall_bin_pol.max_types * sizeof(domaintype_t));
+    return ACM_OK;
+}
+
+static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+{
+    struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
+    traceprintk("%s.\n", __func__);
+    if (chwall_ssidp == NULL)
+        return ACM_INIT_SSID_ERROR;
+
+    chwall_ssidp->chwall_ssidref =
+        GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+
+    if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
+        || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID))
+    {
+        printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset 
(0).\n",
+                __func__, chwall_ssidp->chwall_ssidref);
+        xfree(chwall_ssidp);
+        return ACM_INIT_SSID_ERROR;
+    }
+    (*chwall_ssid) = chwall_ssidp;
+    printkd("%s: determined chwall_ssidref to %x.\n",
+            __func__, chwall_ssidp->chwall_ssidref);
+    return ACM_OK;
+}
+
+static void chwall_free_domain_ssid(void *chwall_ssid)
+{
+    traceprintk("%s.\n", __func__);
+    if (chwall_ssid != NULL)
+        xfree(chwall_ssid);
+    return;
 }
 
 
 /* dump chinese wall cache; policy read-locked already */
-static int
-chwall_dump_policy(u8 *buf, u16 buf_size) {    
-     struct acm_chwall_policy_buffer *chwall_buf = (struct 
acm_chwall_policy_buffer *)buf;
-     int ret = 0;
-
-     chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types);
-     chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs);
-     chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
-     chwall_buf->chwall_ssid_offset = htonl(sizeof(struct 
acm_chwall_policy_buffer));
-     chwall_buf->chwall_max_conflictsets = 
htonl(chwall_bin_pol.max_conflictsets);
-     chwall_buf->chwall_conflict_sets_offset =
-            htonl(
-                  ntohl(chwall_buf->chwall_ssid_offset) +
-                  sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * 
-                  chwall_bin_pol.max_types);
-
-     chwall_buf->chwall_running_types_offset = 
-            htonl(
-                  ntohl(chwall_buf->chwall_conflict_sets_offset) +
-                  sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
-                  chwall_bin_pol.max_types);
-
-     chwall_buf->chwall_conflict_aggregate_offset =
-            htonl(
-                  ntohl(chwall_buf->chwall_running_types_offset) +
-                  sizeof(domaintype_t) * chwall_bin_pol.max_types);
-
-     ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) +
-            sizeof(domaintype_t) * chwall_bin_pol.max_types;
-
-     /* now copy buffers over */
-     arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_ssid_offset)),
-             chwall_bin_pol.ssidrefs,
-             chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
-
-     arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_sets_offset)),
-             chwall_bin_pol.conflict_sets,
-             chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
-
-     arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_running_types_offset)),
-             chwall_bin_pol.running_types,
-             chwall_bin_pol.max_types);
-
-     arrcpy16((u16 *)(buf + 
ntohl(chwall_buf->chwall_conflict_aggregate_offset)),
-             chwall_bin_pol.conflict_aggregate_set,
-             chwall_bin_pol.max_types);
-     return ret;
+static int chwall_dump_policy(u8 * buf, u32 buf_size)
+{
+    struct acm_chwall_policy_buffer *chwall_buf =
+        (struct acm_chwall_policy_buffer *) buf;
+    int ret = 0;
+
+    if (buf_size < sizeof(struct acm_chwall_policy_buffer))
+        return -EINVAL;
+
+    chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types);
+    chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs);
+    chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+    chwall_buf->chwall_ssid_offset =
+        htonl(sizeof(struct acm_chwall_policy_buffer));
+    chwall_buf->chwall_max_conflictsets =
+        htonl(chwall_bin_pol.max_conflictsets);
+    chwall_buf->chwall_conflict_sets_offset =
+        htonl(ntohl(chwall_buf->chwall_ssid_offset) +
+              sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs *
+              chwall_bin_pol.max_types);
+    chwall_buf->chwall_running_types_offset =
+        htonl(ntohl(chwall_buf->chwall_conflict_sets_offset) +
+              sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
+              chwall_bin_pol.max_types);
+    chwall_buf->chwall_conflict_aggregate_offset =
+        htonl(ntohl(chwall_buf->chwall_running_types_offset) +
+              sizeof(domaintype_t) * chwall_bin_pol.max_types);
+
+    ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) +
+        sizeof(domaintype_t) * chwall_bin_pol.max_types;
+
+    if (buf_size < ret)
+        return -EINVAL;
+
+    /* now copy buffers over */
+    arrcpy16((u16 *) (buf + ntohl(chwall_buf->chwall_ssid_offset)),
+             chwall_bin_pol.ssidrefs,
+             chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
+
+    arrcpy16((u16 *) (buf +
+                      ntohl(chwall_buf->chwall_conflict_sets_offset)),
+             chwall_bin_pol.conflict_sets,
+             chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
+
+    arrcpy16((u16 *) (buf +
+                      ntohl(chwall_buf->chwall_running_types_offset)),
+             chwall_bin_pol.running_types, chwall_bin_pol.max_types);
+
+    arrcpy16((u16 *) (buf +
+                      ntohl(chwall_buf->chwall_conflict_aggregate_offset)),
+             chwall_bin_pol.conflict_aggregate_set,
+             chwall_bin_pol.max_types);
+    return ret;
 }
 
 /* adapt security state (running_types and conflict_aggregate_set) to all 
running
  * domains; chwall_init_state is called when a policy is changed to bring the 
security
  * information into a consistent state and to detect violations (return != 0).
  * from a security point of view, we simulate that all running domains are 
re-started
- */ 
+ */
 static int
-chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, domaintype_t 
*ssidrefs, domaintype_t *conflict_sets,
-                 domaintype_t *running_types, domaintype_t 
*conflict_aggregate_set)
-{
-       int violation = 0, i, j;
-       struct chwall_ssid *chwall_ssid;
-       ssidref_t chwall_ssidref;
-       struct domain **pd;
-
-        write_lock(&domlist_lock);
-       /* go through all domains and adjust policy as if this domain was 
started now */
-        pd = &domain_list;
-        for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-               chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct 
acm_ssid_domain *)(*pd)->ssid);
-               chwall_ssidref = chwall_ssid->chwall_ssidref;
-               traceprintk("%s: validating policy for domain %x 
(chwall-REF=%x).\n", 
-                       __func__, (*pd)->domain_id, chwall_ssidref);
-               /* a) adjust types ref-count for running domains */
-               for (i=0; i< chwall_buf->chwall_max_types; i++)
-                       running_types[i] +=
-                               
ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i];
-
-               /* b) check for conflict */
-               for (i=0; i< chwall_buf->chwall_max_types; i++)
-                       if (conflict_aggregate_set[i] && 
-                           
ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) {
-                               printk("%s: CHINESE WALL CONFLICT in type 
%02x.\n", __func__, i);
-                               violation = 1;
-                               goto out;
-                       }
-               /* set violation and break out of the loop */
-               /* c) adapt conflict aggregate set for this domain (notice 
conflicts) */
-               for (i=0; i<chwall_buf->chwall_max_conflictsets; i++) {
-                       int common = 0;
-                       /* check if conflict_set_i and ssidref have common 
types */
-                       for (j=0; j<chwall_buf->chwall_max_types; j++)
-                               if 
(conflict_sets[i*chwall_buf->chwall_max_types + j] &&
-                                   
ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) {
-                                       common = 1;
-                                       break;
-                               }
-                       if (common == 0)
-                               continue; /* try next conflict set */
-                       /* now add types of the conflict set to 
conflict_aggregate_set (except types in chwall_ssidref) */
-                       for (j=0; j<chwall_buf->chwall_max_types; j++)
-                               if 
(conflict_sets[i*chwall_buf->chwall_max_types + j] &&
-                                   
!ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j])
-                                       conflict_aggregate_set[j]++;
-               }       
-       }
+chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf,
+                  domaintype_t * ssidrefs, domaintype_t * conflict_sets,
+                  domaintype_t * running_types,
+                  domaintype_t * conflict_aggregate_set)
+{
+    int violation = 0, i, j;
+    struct chwall_ssid *chwall_ssid;
+    ssidref_t chwall_ssidref;
+    struct domain **pd;
+
+    write_lock(&domlist_lock);
+    /* go through all domains and adjust policy as if this domain was started 
now */
+    pd = &domain_list;
+    for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list)
+    {
+        chwall_ssid =
+            GET_SSIDP(ACM_CHINESE_WALL_POLICY,
+                      (struct acm_ssid_domain *) (*pd)->ssid);
+        chwall_ssidref = chwall_ssid->chwall_ssidref;
+        traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
+                    __func__, (*pd)->domain_id, chwall_ssidref);
+        /* a) adjust types ref-count for running domains */
+        for (i = 0; i < chwall_buf->chwall_max_types; i++)
+            running_types[i] +=
+                ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i];
+
+        /* b) check for conflict */
+        for (i = 0; i < chwall_buf->chwall_max_types; i++)
+            if (conflict_aggregate_set[i] &&
+                ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i])
+            {
+                printk("%s: CHINESE WALL CONFLICT in type %02x.\n",
+                       __func__, i);
+                violation = 1;
+                goto out;
+            }
+        /* set violation and break out of the loop */
+        /* c) adapt conflict aggregate set for this domain (notice conflicts) 
*/
+        for (i = 0; i < chwall_buf->chwall_max_conflictsets; i++)
+        {
+            int common = 0;
+            /* check if conflict_set_i and ssidref have common types */
+            for (j = 0; j < chwall_buf->chwall_max_types; j++)
+                if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
+                    ssidrefs[chwall_ssidref *
+                            chwall_buf->chwall_max_types + j])
+                {
+                    common = 1;
+                    break;
+                }
+            if (common == 0)
+                continue;       /* try next conflict set */
+            /* now add types of the conflict set to conflict_aggregate_set 
(except types in chwall_ssidref) */
+            for (j = 0; j < chwall_buf->chwall_max_types; j++)
+                if (conflict_sets[i * chwall_buf->chwall_max_types + j] &&
+                    !ssidrefs[chwall_ssidref *
+                             chwall_buf->chwall_max_types + j])
+                    conflict_aggregate_set[j]++;
+        }
+    }
  out:
-        write_unlock(&domlist_lock);
-       return violation;
-       /* returning "violation != 0" means that the currently running set of 
domains would 
-        * not be possible if the new policy had been enforced before starting 
them; for chinese
-        * wall, this means that the new policy includes at least one conflict 
set of which 
-        * more than one type is currently running */
-}
-
-static int
-chwall_set_policy(u8 *buf, u16 buf_size) 
-{      
-       /* policy write-locked already */
-       struct acm_chwall_policy_buffer *chwall_buf = (struct 
acm_chwall_policy_buffer *)buf;
-       void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, 
*conflict_aggregate_set = NULL;       
-
-        /* rewrite the policy due to endianess */
-        chwall_buf->policy_code                      = 
ntohl(chwall_buf->policy_code);
-        chwall_buf->policy_version                   = 
ntohl(chwall_buf->policy_version);
-        chwall_buf->chwall_max_types                 = 
ntohl(chwall_buf->chwall_max_types);
-        chwall_buf->chwall_max_ssidrefs              = 
ntohl(chwall_buf->chwall_max_ssidrefs);
-        chwall_buf->chwall_max_conflictsets          = 
ntohl(chwall_buf->chwall_max_conflictsets);
-        chwall_buf->chwall_ssid_offset               = 
ntohl(chwall_buf->chwall_ssid_offset);
-        chwall_buf->chwall_conflict_sets_offset      = 
ntohl(chwall_buf->chwall_conflict_sets_offset);
-        chwall_buf->chwall_running_types_offset      = 
ntohl(chwall_buf->chwall_running_types_offset);
-        chwall_buf->chwall_conflict_aggregate_offset = 
ntohl(chwall_buf->chwall_conflict_aggregate_offset);
-
-       /* policy type and version checks */
-       if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
-           (chwall_buf->policy_version != ACM_CHWALL_VERSION))
-               return -EINVAL;
-
-       /* 1. allocate new buffers */
-       ssids = xmalloc_array(domaintype_t, 
chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
-       conflict_sets = xmalloc_array(domaintype_t, 
chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types);
-       running_types = 
xmalloc_array(domaintype_t,chwall_buf->chwall_max_types);
-       conflict_aggregate_set = xmalloc_array(domaintype_t, 
chwall_buf->chwall_max_types);
-
-       if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == 
NULL)||(conflict_aggregate_set == NULL))
-               goto error_free;
-
-       /* 2. set new policy */
-       if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * 
-           chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > 
buf_size)
-               goto error_free;
-       arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
-              sizeof(domaintype_t),  
-              chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
-
-       if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * 
-           chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets 
> buf_size)
-               goto error_free;
-
-       arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
-              sizeof(domaintype_t),
-              chwall_buf->chwall_max_types * 
chwall_buf->chwall_max_conflictsets);
-
-       /* we also use new state buffers since max_types can change */
-       memset(running_types, 0, 
sizeof(domaintype_t)*chwall_buf->chwall_max_types);
-       memset(conflict_aggregate_set, 0, 
sizeof(domaintype_t)*chwall_buf->chwall_max_types);
-
-       /* 3. now re-calculate the state for the new policy based on running 
domains; 
-        *    this can fail if new policy is conflicting with running domains */
-       if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, 
conflict_aggregate_set)) {
-               printk("%s: New policy conflicts with running domains. Policy 
load aborted.\n", __func__);
-               goto error_free; /* new policy conflicts with running domains */
-       }
-       /* 4. free old policy buffers, replace with new ones */
-       chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
-       chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
-       chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
-       if (chwall_bin_pol.ssidrefs != NULL) 
-               xfree(chwall_bin_pol.ssidrefs);
-       if (chwall_bin_pol.conflict_aggregate_set != NULL) 
-               xfree(chwall_bin_pol.conflict_aggregate_set);
-       if (chwall_bin_pol.running_types != NULL) 
-               xfree(chwall_bin_pol.running_types);
-       if (chwall_bin_pol.conflict_sets != NULL) 
-               xfree(chwall_bin_pol.conflict_sets);
-       chwall_bin_pol.ssidrefs = ssids;
-       chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
-       chwall_bin_pol.running_types = running_types;
-       chwall_bin_pol.conflict_sets = conflict_sets;
-       return ACM_OK;
-
-error_free:
-       printk("%s: ERROR setting policy.\n", __func__);
-       if (ssids != NULL) xfree(ssids);
-       if (conflict_sets != NULL) xfree(conflict_sets);
-       if (running_types != NULL) xfree(running_types);
-       if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set);
-       return -EFAULT;
-}
-       
-static int 
-chwall_dump_stats(u8 *buf, u16 len)
-{
-       /* no stats for Chinese Wall Policy */
-       return 0;
-}
-
-static int
-chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
+    write_unlock(&domlist_lock);
+    return violation;
+    /* returning "violation != 0" means that the currently running set of 
domains would
+     * not be possible if the new policy had been enforced before starting 
them; for chinese
+     * wall, this means that the new policy includes at least one conflict set 
of which
+     * more than one type is currently running */
+}
+
+static int chwall_set_policy(u8 * buf, u32 buf_size)
+{
+    /* policy write-locked already */
+    struct acm_chwall_policy_buffer *chwall_buf =
+        (struct acm_chwall_policy_buffer *) buf;
+    void *ssids = NULL, *conflict_sets = NULL, *running_types =
+        NULL, *conflict_aggregate_set = NULL;
+
+    if (buf_size < sizeof(struct acm_chwall_policy_buffer))
+        return -EINVAL;
+
+    /* rewrite the policy due to endianess */
+    chwall_buf->policy_code = ntohl(chwall_buf->policy_code);
+    chwall_buf->policy_version = ntohl(chwall_buf->policy_version);
+    chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types);
+    chwall_buf->chwall_max_ssidrefs =
+        ntohl(chwall_buf->chwall_max_ssidrefs);
+    chwall_buf->chwall_max_conflictsets =
+        ntohl(chwall_buf->chwall_max_conflictsets);
+    chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset);
+    chwall_buf->chwall_conflict_sets_offset =
+        ntohl(chwall_buf->chwall_conflict_sets_offset);
+    chwall_buf->chwall_running_types_offset =
+        ntohl(chwall_buf->chwall_running_types_offset);
+    chwall_buf->chwall_conflict_aggregate_offset =
+        ntohl(chwall_buf->chwall_conflict_aggregate_offset);
+
+    /* policy type and version checks */
+    if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||
+        (chwall_buf->policy_version != ACM_CHWALL_VERSION))
+        return -EINVAL;
+
+    /* 1. allocate new buffers */
+    ssids =
+        xmalloc_array(domaintype_t,
+                      chwall_buf->chwall_max_types *
+                      chwall_buf->chwall_max_ssidrefs);
+    conflict_sets =
+        xmalloc_array(domaintype_t,
+                      chwall_buf->chwall_max_conflictsets *
+                      chwall_buf->chwall_max_types);
+    running_types =
+        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
+    conflict_aggregate_set =
+        xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
+
+    if ((ssids == NULL) || (conflict_sets == NULL)
+        || (running_types == NULL) || (conflict_aggregate_set == NULL))
+        goto error_free;
+
+    /* 2. set new policy */
+    if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
+        chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs >
+        buf_size)
+        goto error_free;
+
+    arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
+           sizeof(domaintype_t),
+           chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
+
+    if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
+        chwall_buf->chwall_max_types *
+        chwall_buf->chwall_max_conflictsets > buf_size)
+        goto error_free;
+
+    arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
+           sizeof(domaintype_t),
+           chwall_buf->chwall_max_types *
+           chwall_buf->chwall_max_conflictsets);
+
+    /* we also use new state buffers since max_types can change */
+    memset(running_types, 0,
+           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
+    memset(conflict_aggregate_set, 0,
+           sizeof(domaintype_t) * chwall_buf->chwall_max_types);
+
+    /* 3. now re-calculate the state for the new policy based on running 
domains;
+     *    this can fail if new policy is conflicting with running domains */
+    if (chwall_init_state(chwall_buf, ssids,
+                          conflict_sets, running_types,
+                          conflict_aggregate_set))
+    {
+        printk("%s: New policy conflicts with running domains. Policy load 
aborted.\n",
+               __func__);
+        goto error_free;        /* new policy conflicts with running domains */
+    }
+    /* 4. free old policy buffers, replace with new ones */
+    chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
+    chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
+    chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
+    if (chwall_bin_pol.ssidrefs != NULL)
+        xfree(chwall_bin_pol.ssidrefs);
+    if (chwall_bin_pol.conflict_aggregate_set != NULL)
+        xfree(chwall_bin_pol.conflict_aggregate_set);
+    if (chwall_bin_pol.running_types != NULL)
+        xfree(chwall_bin_pol.running_types);
+    if (chwall_bin_pol.conflict_sets != NULL)
+        xfree(chwall_bin_pol.conflict_sets);
+    chwall_bin_pol.ssidrefs = ssids;
+    chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
+    chwall_bin_pol.running_types = running_types;
+    chwall_bin_pol.conflict_sets = conflict_sets;
+    return ACM_OK;
+
+ error_free:
+    printk("%s: ERROR setting policy.\n", __func__);
+    if (ssids != NULL)
+        xfree(ssids);
+    if (conflict_sets != NULL)
+        xfree(conflict_sets);
+    if (running_types != NULL)
+        xfree(running_types);
+    if (conflict_aggregate_set != NULL)
+        xfree(conflict_aggregate_set);
+    return -EFAULT;
+}
+
+static int chwall_dump_stats(u8 * buf, u16 len)
+{
+    /* no stats for Chinese Wall Policy */
+    return 0;
+}
+
+static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len)
 {
     int i;
 
@@ -319,12 +385,14 @@
     if (chwall_bin_pol.max_types > len)
         return -EFAULT;
 
-       if (ssidref >= chwall_bin_pol.max_ssidrefs)
-               return -EFAULT;
+    if (ssidref >= chwall_bin_pol.max_ssidrefs)
+        return -EFAULT;
 
     /* read types for chwall ssidref */
-    for(i=0; i< chwall_bin_pol.max_types; i++) {
-        if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i])
+    for (i = 0; i < chwall_bin_pol.max_types; i++)
+    {
+        if (chwall_bin_pol.
+            ssidrefs[ssidref * chwall_bin_pol.max_types + i])
             buf[i] = 1;
         else
             buf[i] = 0;
@@ -336,198 +404,239 @@
  * Authorization functions
  ***************************/
 
-
 /* -------- DOMAIN OPERATION HOOKS -----------*/
 
-static int 
-chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
-{
-       ssidref_t chwall_ssidref;
-       int i,j;
-       traceprintk("%s.\n", __func__);
-
-       read_lock(&acm_bin_pol_rwlock);
-       chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-       if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) {
-               printk("%s: ERROR CHWALL SSID is NOT SET but policy 
enforced.\n", __func__);
-               read_unlock(&acm_bin_pol_rwlock);
-               return ACM_ACCESS_DENIED; /* catching and indicating config 
error */
-       }
-       if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
-               printk("%s: ERROR chwall_ssidref > max(%x).\n",
-                      __func__, chwall_bin_pol.max_ssidrefs-1);
-               read_unlock(&acm_bin_pol_rwlock);
-               return ACM_ACCESS_DENIED;
-       }
-       /* A: chinese wall check for conflicts */
-       for (i=0; i< chwall_bin_pol.max_types; i++)
-               if (chwall_bin_pol.conflict_aggregate_set[i] && 
-                   
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) {
-                       printk("%s: CHINESE WALL CONFLICT in type %02x.\n", 
__func__, i);
-                       read_unlock(&acm_bin_pol_rwlock);
-                       return ACM_ACCESS_DENIED;
-               }
-
-       /* B: chinese wall conflict set adjustment (so that other 
-        *      other domains simultaneously created are evaluated against this 
new set)*/
-       for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
-               int common = 0;
-               /* check if conflict_set_i and ssidref have common types */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
-                               common = 1;
-                               break;
-                       }
-               if (common == 0)
-                       continue; /* try next conflict set */
-               /* now add types of the conflict set to conflict_aggregate_set 
(except types in chwall_ssidref) */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
!chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
-                               chwall_bin_pol.conflict_aggregate_set[j]++;
-       }
-       read_unlock(&acm_bin_pol_rwlock);
-       return ACM_ACCESS_PERMITTED;
-}
-
-static void
-chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
-{
-       int i,j;
-       ssidref_t chwall_ssidref;
-       traceprintk("%s.\n", __func__);
-       
-       read_lock(&acm_bin_pol_rwlock);
-       chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-       /* adjust types ref-count for running domains */
-       for (i=0; i< chwall_bin_pol.max_types; i++)
-               chwall_bin_pol.running_types[i] +=
-                       
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
-       if (domid) {
-               read_unlock(&acm_bin_pol_rwlock);
-               return;
-       }
-       /* Xen does not call pre-create hook for DOM0;
-        * to consider type conflicts of any domain with DOM0, we need
-        * to adjust the conflict_aggregate for DOM0 here the same way it
-        * is done for non-DOM0 domains in the pre-hook */
-       printkd("%s: adjusting security state for DOM0 (ssidref=%x, 
chwall_ssidref=%x).\n", 
-               __func__, ssidref, chwall_ssidref);
-
-       /* chinese wall conflict set adjustment (so that other 
-        *      other domains simultaneously created are evaluated against this 
new set)*/
-       for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
-               int common = 0;
-               /* check if conflict_set_i and ssidref have common types */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
-                               common = 1;
-                               break;
-                       }
-               if (common == 0)
-                       continue; /* try next conflict set */
-               /* now add types of the conflict set to conflict_aggregate_set 
(except types in chwall_ssidref) */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
!chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
-                               chwall_bin_pol.conflict_aggregate_set[j]++;
-       }
-       read_unlock(&acm_bin_pol_rwlock);
-       return;
+static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+    ssidref_t chwall_ssidref;
+    int i, j;
+    traceprintk("%s.\n", __func__);
+
+    read_lock(&acm_bin_pol_rwlock);
+    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+    if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)
+    {
+        printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n",
+               __func__);
+        read_unlock(&acm_bin_pol_rwlock);
+        return ACM_ACCESS_DENIED;       /* catching and indicating config 
error */
+    }
+    if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs)
+    {
+        printk("%s: ERROR chwall_ssidref > max(%x).\n",
+               __func__, chwall_bin_pol.max_ssidrefs - 1);
+        read_unlock(&acm_bin_pol_rwlock);
+        return ACM_ACCESS_DENIED;
+    }
+    /* A: chinese wall check for conflicts */
+    for (i = 0; i < chwall_bin_pol.max_types; i++)
+        if (chwall_bin_pol.conflict_aggregate_set[i] &&
+            chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                   chwall_bin_pol.max_types + i])
+        {
+            printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
+            read_unlock(&acm_bin_pol_rwlock);
+            return ACM_ACCESS_DENIED;
+        }
+
+    /* B: chinese wall conflict set adjustment (so that other
+     *      other domains simultaneously created are evaluated against this 
new set)*/
+    for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
+    {
+        int common = 0;
+        /* check if conflict_set_i and ssidref have common types */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                          chwall_bin_pol.max_types + j])
+            {
+                common = 1;
+                break;
+            }
+        if (common == 0)
+            continue;           /* try next conflict set */
+        /* now add types of the conflict set to conflict_aggregate_set (except 
types in chwall_ssidref) */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && !chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                           chwall_bin_pol.max_types + j])
+                chwall_bin_pol.conflict_aggregate_set[j]++;
+    }
+    read_unlock(&acm_bin_pol_rwlock);
+    return ACM_ACCESS_PERMITTED;
+}
+
+static void chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
+{
+    int i, j;
+    ssidref_t chwall_ssidref;
+    traceprintk("%s.\n", __func__);
+
+    read_lock(&acm_bin_pol_rwlock);
+    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+    /* adjust types ref-count for running domains */
+    for (i = 0; i < chwall_bin_pol.max_types; i++)
+        chwall_bin_pol.running_types[i] +=
+            chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                   chwall_bin_pol.max_types + i];
+    if (domid)
+    {
+        read_unlock(&acm_bin_pol_rwlock);
+        return;
+    }
+    /* Xen does not call pre-create hook for DOM0;
+     * to consider type conflicts of any domain with DOM0, we need
+     * to adjust the conflict_aggregate for DOM0 here the same way it
+     * is done for non-DOM0 domains in the pre-hook */
+    printkd("%s: adjusting security state for DOM0 (ssidref=%x, 
chwall_ssidref=%x).\n",
+            __func__, ssidref, chwall_ssidref);
+
+    /* chinese wall conflict set adjustment (so that other
+     *      other domains simultaneously created are evaluated against this 
new set)*/
+    for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
+    {
+        int common = 0;
+        /* check if conflict_set_i and ssidref have common types */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                          chwall_bin_pol.max_types + j])
+            {
+                common = 1;
+                break;
+            }
+        if (common == 0)
+            continue;           /* try next conflict set */
+        /* now add types of the conflict set to conflict_aggregate_set (except 
types in chwall_ssidref) */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && !chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                           chwall_bin_pol.max_types + j])
+                chwall_bin_pol.conflict_aggregate_set[j]++;
+    }
+    read_unlock(&acm_bin_pol_rwlock);
+    return;
 }
 
 static void
 chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
 {
-       int i, j;
-       ssidref_t chwall_ssidref;
-       traceprintk("%s.\n", __func__);
-
-       read_lock(&acm_bin_pol_rwlock);
-       chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
-       /* roll-back: re-adjust conflicting types aggregate */
-       for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
-               int common = 0;
-               /* check if conflict_set_i and ssidref have common types */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
-                               common = 1;
-                               break;
-                       }
-               if (common == 0)
-                       continue; /* try next conflict set, this one does not 
include any type of chwall_ssidref */
-               /* now add types of the conflict set to conflict_aggregate_set 
(except types in chwall_ssidref) */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
!chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
-                               chwall_bin_pol.conflict_aggregate_set[j]--;
-       }
-       read_unlock(&acm_bin_pol_rwlock);
-}
-
-
-static void
-chwall_post_domain_destroy(void *object_ssid, domid_t id) 
-{
-       int i,j;
-       struct chwall_ssid *chwall_ssidp = 
-               GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain 
*)object_ssid);
-       ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
-
-       traceprintk("%s.\n", __func__);
-
-       read_lock(&acm_bin_pol_rwlock);
-       /* adjust running types set */
-       for (i=0; i< chwall_bin_pol.max_types; i++)
-               chwall_bin_pol.running_types[i] -=
-                       
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
-
-       /* roll-back: re-adjust conflicting types aggregate */
-       for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
-               int common = 0;
-               /* check if conflict_set_i and ssidref have common types */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
-                               common = 1;
-                               break;
-                       }
-               if (common == 0)
-                       continue; /* try next conflict set, this one does not 
include any type of chwall_ssidref */
-               /* now add types of the conflict set to conflict_aggregate_set 
(except types in chwall_ssidref) */
-               for (j=0; j<chwall_bin_pol.max_types; j++)
-                       if 
(chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
-                           
!chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
-                               chwall_bin_pol.conflict_aggregate_set[j]--;
-       }
-       read_unlock(&acm_bin_pol_rwlock);
-       return;
+    int i, j;
+    ssidref_t chwall_ssidref;
+    traceprintk("%s.\n", __func__);
+
+    read_lock(&acm_bin_pol_rwlock);
+    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+    /* roll-back: re-adjust conflicting types aggregate */
+    for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
+    {
+        int common = 0;
+        /* check if conflict_set_i and ssidref have common types */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                          chwall_bin_pol.max_types + j])
+            {
+                common = 1;
+                break;
+            }
+        if (common == 0)
+            continue;           /* try next conflict set, this one does not 
include any type of chwall_ssidref */
+        /* now add types of the conflict set to conflict_aggregate_set (except 
types in chwall_ssidref) */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && !chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                           chwall_bin_pol.max_types + j])
+                chwall_bin_pol.conflict_aggregate_set[j]--;
+    }
+    read_unlock(&acm_bin_pol_rwlock);
+}
+
+
+static void chwall_post_domain_destroy(void *object_ssid, domid_t id)
+{
+    int i, j;
+    struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,
+                                                 (struct acm_ssid_domain *)
+                                                 object_ssid);
+    ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
+
+    traceprintk("%s.\n", __func__);
+
+    read_lock(&acm_bin_pol_rwlock);
+    /* adjust running types set */
+    for (i = 0; i < chwall_bin_pol.max_types; i++)
+        chwall_bin_pol.running_types[i] -=
+            chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                   chwall_bin_pol.max_types + i];
+
+    /* roll-back: re-adjust conflicting types aggregate */
+    for (i = 0; i < chwall_bin_pol.max_conflictsets; i++)
+    {
+        int common = 0;
+        /* check if conflict_set_i and ssidref have common types */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                          chwall_bin_pol.max_types + j])
+            {
+                common = 1;
+                break;
+            }
+        if (common == 0)
+            continue;           /* try next conflict set, this one does not 
include any type of chwall_ssidref */
+        /* now add types of the conflict set to conflict_aggregate_set (except 
types in chwall_ssidref) */
+        for (j = 0; j < chwall_bin_pol.max_types; j++)
+            if (chwall_bin_pol.
+                conflict_sets[i * chwall_bin_pol.max_types + j]
+                && !chwall_bin_pol.ssidrefs[chwall_ssidref *
+                                           chwall_bin_pol.max_types + j])
+                chwall_bin_pol.conflict_aggregate_set[j]--;
+    }
+    read_unlock(&acm_bin_pol_rwlock);
+    return;
 }
 
 struct acm_operations acm_chinesewall_ops = {
-       /* policy management services */
-       .init_domain_ssid               = chwall_init_domain_ssid,
-       .free_domain_ssid               = chwall_free_domain_ssid,
-       .dump_binary_policy             = chwall_dump_policy,
-       .set_binary_policy              = chwall_set_policy,
-       .dump_statistics                = chwall_dump_stats,
-    .dump_ssid_types        = chwall_dump_ssid_types,
-       /* domain management control hooks */
-       .pre_domain_create              = chwall_pre_domain_create,
-       .post_domain_create             = chwall_post_domain_create,
-       .fail_domain_create             = chwall_fail_domain_create,
-       .post_domain_destroy            = chwall_post_domain_destroy,
-       /* event channel control hooks */
-       .pre_eventchannel_unbound       = NULL,
-       .fail_eventchannel_unbound      = NULL,
-       .pre_eventchannel_interdomain   = NULL,
-       .fail_eventchannel_interdomain  = NULL,
-       /* grant table control hooks */
-       .pre_grant_map_ref              = NULL,
-       .fail_grant_map_ref             = NULL,
-       .pre_grant_setup                = NULL,
-       .fail_grant_setup               = NULL,
+    /* policy management services */
+    .init_domain_ssid = chwall_init_domain_ssid,
+    .free_domain_ssid = chwall_free_domain_ssid,
+    .dump_binary_policy = chwall_dump_policy,
+    .set_binary_policy = chwall_set_policy,
+    .dump_statistics = chwall_dump_stats,
+    .dump_ssid_types = chwall_dump_ssid_types,
+    /* domain management control hooks */
+    .pre_domain_create = chwall_pre_domain_create,
+    .post_domain_create = chwall_post_domain_create,
+    .fail_domain_create = chwall_fail_domain_create,
+    .post_domain_destroy = chwall_post_domain_destroy,
+    /* event channel control hooks */
+    .pre_eventchannel_unbound = NULL,
+    .fail_eventchannel_unbound = NULL,
+    .pre_eventchannel_interdomain = NULL,
+    .fail_eventchannel_interdomain = NULL,
+    /* grant table control hooks */
+    .pre_grant_map_ref = NULL,
+    .fail_grant_map_ref = NULL,
+    .pre_grant_setup = NULL,
+    .fail_grant_setup = NULL,
+    /* generic domain-requested decision hooks */
+    .sharing = NULL,
 };
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c        Thu Oct 20 18:37:41 2005
+++ b/xen/acm/acm_core.c        Thu Oct 20 20:37:15 2005
@@ -47,7 +47,7 @@
 void acm_init_ste_policy(void);
 
 extern struct acm_operations acm_chinesewall_ops, 
-       acm_simple_type_enforcement_ops, acm_null_ops;
+    acm_simple_type_enforcement_ops, acm_null_ops;
 
 /* global ops structs called by the hooks */
 struct acm_operations *acm_primary_ops = NULL;
@@ -66,7 +66,7 @@
     u32 test = 1;
     if (*((u8 *)&test) == 1)
     {
-       printk("ACM module running in LITTLE ENDIAN.\n");
+        printk("ACM module running in LITTLE ENDIAN.\n");
         little_endian = 1;
     }
     else
@@ -80,10 +80,10 @@
 static void
 acm_init_binary_policy(void *primary, void *secondary)
 {
-       acm_bin_pol.primary_policy_code = 0;
-       acm_bin_pol.secondary_policy_code = 0;
-       acm_bin_pol.primary_binary_policy = primary;
-       acm_bin_pol.secondary_binary_policy = secondary;
+    acm_bin_pol.primary_policy_code = 0;
+    acm_bin_pol.secondary_policy_code = 0;
+    acm_bin_pol.primary_binary_policy = primary;
+    acm_bin_pol.secondary_binary_policy = secondary;
 }
 
 static int
@@ -96,7 +96,7 @@
     int rc = ACM_OK;
 
     if (mbi->mods_count > 1)
-           *initrdidx = 1;
+        *initrdidx = 1;
 
     /*
      * Try all modules and see whichever could be the binary policy.
@@ -115,14 +115,14 @@
 #error Architecture unsupported by sHype
 #endif
         _policy_len   = mod[i].mod_end - mod[i].mod_start;
-       if (_policy_len < sizeof(struct acm_policy_buffer))
-               continue; /* not a policy */
+        if (_policy_len < sizeof(struct acm_policy_buffer))
+            continue; /* not a policy */
 
         pol = (struct acm_policy_buffer *)_policy_start;
         if (ntohl(pol->magic) == ACM_MAGIC)
         {
             rc = acm_set_policy((void *)_policy_start,
-                                (u16)_policy_len,
+                                (u32)_policy_len,
                                 0);
             if (rc == ACM_OK)
             {
@@ -145,7 +145,7 @@
             }
             else
             {
-               printk("Invalid policy. %d.th module line.\n", i+1);
+                printk("Invalid policy. %d.th module line.\n", i+1);
             }
         } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == 
ACM_MAGIC ) */
     }
@@ -158,10 +158,10 @@
          const multiboot_info_t *mbi,
          unsigned long initial_images_start)
 {
-       int ret = ACM_OK;
+    int ret = ACM_OK;
 
     acm_set_endian();
-       write_lock(&acm_bin_pol_rwlock);
+    write_lock(&acm_bin_pol_rwlock);
     acm_init_binary_policy(NULL, NULL);
 
     /* set primary policy component */
@@ -170,14 +170,14 @@
 
     case ACM_CHINESE_WALL_POLICY:
         acm_init_chwall_policy();
-               acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
-               acm_primary_ops = &acm_chinesewall_ops;
+        acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+        acm_primary_ops = &acm_chinesewall_ops;
         break;
 
     case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
         acm_init_ste_policy();
-               acm_bin_pol.primary_policy_code = 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-               acm_primary_ops = &acm_simple_type_enforcement_ops;
+        acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+        acm_primary_ops = &acm_simple_type_enforcement_ops;
         break;
 
     default:
@@ -190,9 +190,9 @@
     /* secondary policy component part */
     switch ((ACM_USE_SECURITY_POLICY) >> 4) {
     case ACM_NULL_POLICY:
-               acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
-               acm_secondary_ops = &acm_null_ops;
-               break;
+        acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+        acm_secondary_ops = &acm_null_ops;
+        break;
 
     case ACM_CHINESE_WALL_POLICY:
         if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
@@ -200,9 +200,9 @@
             ret = -EINVAL;
             goto out;
         }
-               acm_init_chwall_policy();
+        acm_init_chwall_policy();
         acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
-               acm_secondary_ops = &acm_chinesewall_ops;
+        acm_secondary_ops = &acm_chinesewall_ops;
         break;
 
     case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
@@ -211,9 +211,9 @@
             ret = -EINVAL;
             goto out;
         }
-               acm_init_ste_policy();
-               acm_bin_pol.secondary_policy_code = 
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
-               acm_secondary_ops = &acm_simple_type_enforcement_ops;
+        acm_init_ste_policy();
+        acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+        acm_secondary_ops = &acm_simple_type_enforcement_ops;
         break;
 
     default:
@@ -222,96 +222,103 @@
     }
 
  out:
-       write_unlock(&acm_bin_pol_rwlock);
-
-       if (ret != ACM_OK)
-    {
-        printk("%s: Error setting policies.\n", __func__);
+    write_unlock(&acm_bin_pol_rwlock);
+
+    if (ret != ACM_OK)
+    {
+        printk("%s: Error initializing policies.\n", __func__);
         /* here one could imagine a clean panic */
-               return -EINVAL;
-       }
-       acm_setup(initrdidx, mbi, initial_images_start);
-       printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, 
-              ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
+        return -EINVAL;
+    }
+    if (acm_setup(initrdidx, mbi, initial_images_start) != ACM_OK)
+    {
+        printk("%s: Error loading policy at boot time.\n", __func__);
+        /* ignore, just continue with the minimal hardcoded startup policy */
+    }
+    printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, 
+           ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
            ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
-       return ret;
+    return ret;
 }
 
 int
 acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
 {
-       struct acm_ssid_domain *ssid;
-       struct domain *subj = find_domain_by_id(id);
-       int ret1, ret2;
-       
-       if (subj == NULL)
-    {
-               printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
-               return ACM_NULL_POINTER_ERROR;
-       }
-       if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
-               return ACM_INIT_SSID_ERROR;
-
-       ssid->datatype       = DOMAIN;
-       ssid->subject        = subj;
-       ssid->domainid       = subj->domain_id;
-       ssid->primary_ssid   = NULL;
-       ssid->secondary_ssid = NULL;
-
-       if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
-               ssid->ssidref = ssidref;
-       else
-               ssid->ssidref = ACM_DEFAULT_SSID;
-
-       subj->ssid           = ssid;
-       /* now fill in primary and secondary parts; we only get here through 
hooks */
-       if (acm_primary_ops->init_domain_ssid != NULL)
-               ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), 
ssidref);
-       else
-               ret1 = ACM_OK;
-
-       if (acm_secondary_ops->init_domain_ssid != NULL)
-               ret2 = 
acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
-       else
-               ret2 = ACM_OK;
-
-       if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
-    {
-               printk("%s: ERROR instantiating individual ssids for domain 
0x%02x.\n",
-                      __func__, subj->domain_id);
-               acm_free_domain_ssid(ssid);     
-               put_domain(subj);
-               return ACM_INIT_SSID_ERROR;
-       }
-       printk("%s: assigned domain %x the ssidref=%x.\n",
+    struct acm_ssid_domain *ssid;
+    struct domain *subj = find_domain_by_id(id);
+    int ret1, ret2;
+ 
+    if (subj == NULL)
+    {
+        printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
+        return ACM_NULL_POINTER_ERROR;
+    }
+    if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
+        return ACM_INIT_SSID_ERROR;
+
+    ssid->datatype       = DOMAIN;
+    ssid->subject        = subj;
+    ssid->domainid      = subj->domain_id;
+    ssid->primary_ssid   = NULL;
+    ssid->secondary_ssid = NULL;
+
+    if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
+        ssid->ssidref = ssidref;
+    else
+        ssid->ssidref = ACM_DEFAULT_SSID;
+
+    subj->ssid           = ssid;
+    /* now fill in primary and secondary parts; we only get here through hooks 
*/
+    if (acm_primary_ops->init_domain_ssid != NULL)
+        ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), 
ssidref);
+    else
+        ret1 = ACM_OK;
+
+    if (acm_secondary_ops->init_domain_ssid != NULL)
+        ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), 
ssidref);
+    else
+        ret2 = ACM_OK;
+
+    if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
+    {
+        printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
+               __func__, subj->domain_id);
+        acm_free_domain_ssid(ssid); 
+        put_domain(subj);
+        return ACM_INIT_SSID_ERROR;
+    }
+    printk("%s: assigned domain %x the ssidref=%x.\n",
            __func__, id, ssid->ssidref);
-       put_domain(subj);
-       return ACM_OK;
-}
-
-
-int
+    put_domain(subj);
+    return ACM_OK;
+}
+
+
+void
 acm_free_domain_ssid(struct acm_ssid_domain *ssid)
 {
-       domid_t id;
-
-       /* domain is already gone, just ssid is left */
-       if (ssid == NULL)
-    {
-               printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
-               return ACM_NULL_POINTER_ERROR;
-       }
-    id = ssid->domainid;
-       ssid->subject        = NULL;
-
-       if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
-               acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
-       ssid->primary_ssid = NULL;
-       if (acm_secondary_ops->free_domain_ssid != NULL)
-               acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
-       ssid->secondary_ssid = NULL;
-       xfree(ssid);
-       printkd("%s: Freed individual domain ssid (domain=%02x).\n",
+    /* domain is already gone, just ssid is left */
+    if (ssid == NULL)
+        return;
+
+    ssid->subject = NULL;
+    if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
+        acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
+    ssid->primary_ssid = NULL;
+    if (acm_secondary_ops->free_domain_ssid != NULL)
+        acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
+    ssid->secondary_ssid = NULL;
+    xfree(ssid);
+    printkd("%s: Freed individual domain ssid (domain=%02x).\n",
             __func__, id);
-       return ACM_OK;
-}
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c  Thu Oct 20 18:37:41 2005
+++ b/xen/acm/acm_null_hooks.c  Thu Oct 20 20:37:15 2005
@@ -11,37 +11,38 @@
  * published by the Free Software Foundation, version 2 of the
  * License.
  */
+
 #include <acm/acm_hooks.h>
 
 static int
 null_init_domain_ssid(void **ssid, ssidref_t ssidref)
 {
-       return ACM_OK;
+    return ACM_OK;
 }
 
 static void
 null_free_domain_ssid(void *ssid)
 {
-       return;
+    return;
 }
 
 static int
-null_dump_binary_policy(u8 *buf, u16 buf_size) 
-{      
-       return 0;
+null_dump_binary_policy(u8 *buf, u32 buf_size)
+{ 
+    return 0;
 }
 
 static int
-null_set_binary_policy(u8 *buf, u16 buf_size) 
-{      
-       return ACM_OK;
+null_set_binary_policy(u8 *buf, u32 buf_size)
+{ 
+    return ACM_OK;
 }
-       
+ 
 static int 
 null_dump_stats(u8 *buf, u16 buf_size)
 {
-       /* no stats for NULL policy */
-       return 0;
+    /* no stats for NULL policy */
+    return 0;
 }
 
 static int
@@ -54,25 +55,35 @@
 
 /* now define the hook structure similarly to LSM */
 struct acm_operations acm_null_ops = {
-       .init_domain_ssid               = null_init_domain_ssid,
-       .free_domain_ssid               = null_free_domain_ssid,
-       .dump_binary_policy             = null_dump_binary_policy,
-       .set_binary_policy              = null_set_binary_policy,
-       .dump_statistics                = null_dump_stats,
-    .dump_ssid_types        = null_dump_ssid_types,
-       /* domain management control hooks */
-       .pre_domain_create              = NULL,
-       .post_domain_create             = NULL,
-       .fail_domain_create             = NULL,
-       .post_domain_destroy            = NULL,
-       /* event channel control hooks */
-       .pre_eventchannel_unbound       = NULL,
-       .fail_eventchannel_unbound      = NULL,
-       .pre_eventchannel_interdomain   = NULL,
-       .fail_eventchannel_interdomain  = NULL,
-       /* grant table control hooks */
-       .pre_grant_map_ref              = NULL,
-       .fail_grant_map_ref             = NULL,
-       .pre_grant_setup                = NULL,
-       .fail_grant_setup               = NULL
+    .init_domain_ssid = null_init_domain_ssid,
+    .free_domain_ssid = null_free_domain_ssid,
+    .dump_binary_policy = null_dump_binary_policy,
+    .set_binary_policy = null_set_binary_policy,
+    .dump_statistics = null_dump_stats,
+    .dump_ssid_types = null_dump_ssid_types,
+    /* domain management control hooks */
+    .pre_domain_create = NULL,
+    .post_domain_create = NULL,
+    .fail_domain_create = NULL,
+    .post_domain_destroy = NULL,
+    /* event channel control hooks */
+    .pre_eventchannel_unbound = NULL,
+    .fail_eventchannel_unbound = NULL,
+    .pre_eventchannel_interdomain = NULL,
+    .fail_eventchannel_interdomain = NULL,
+    /* grant table control hooks */
+    .pre_grant_map_ref = NULL,
+    .fail_grant_map_ref = NULL,
+    .pre_grant_setup = NULL,
+    .fail_grant_setup = NULL
 };
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c      Thu Oct 20 18:37:41 2005
+++ b/xen/acm/acm_policy.c      Thu Oct 20 20:37:15 2005
@@ -32,165 +32,166 @@
 #include <acm/acm_endian.h>
 
 int
-acm_set_policy(void *buf, u16 buf_size, int isuserbuffer)
+acm_set_policy(void *buf, u32 buf_size, int isuserbuffer)
 {
-       u8 *policy_buffer = NULL;
-       struct acm_policy_buffer *pol;
-       
+    u8 *policy_buffer = NULL;
+    struct acm_policy_buffer *pol;
+ 
     if (buf_size < sizeof(struct acm_policy_buffer))
-               return -EFAULT;
-
-       /* 1. copy buffer from domain */
-       if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
-           return -ENOMEM;
-
-       if (isuserbuffer) {
-               if (copy_from_user(policy_buffer, buf, buf_size))
+        return -EFAULT;
+
+    /* 1. copy buffer from domain */
+    if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+        return -ENOMEM;
+
+    if (isuserbuffer) {
+        if (copy_from_user(policy_buffer, buf, buf_size))
         {
-                       printk("%s: Error copying!\n",__func__);
-                       goto error_free;
-               }
-       } else
-               memcpy(policy_buffer, buf, buf_size);
-
-       /* 2. some sanity checking */
-       pol = (struct acm_policy_buffer *)policy_buffer;
-
-       if ((ntohl(pol->magic) != ACM_MAGIC) || 
-           (ntohl(pol->policy_version) != ACM_POLICY_VERSION) ||
-           (ntohl(pol->primary_policy_code) != 
acm_bin_pol.primary_policy_code) ||
-           (ntohl(pol->secondary_policy_code) != 
acm_bin_pol.secondary_policy_code))
+            printk("%s: Error copying!\n",__func__);
+            goto error_free;
+        }
+    } else
+        memcpy(policy_buffer, buf, buf_size);
+
+    /* 2. some sanity checking */
+    pol = (struct acm_policy_buffer *)policy_buffer;
+
+    if ((ntohl(pol->magic) != ACM_MAGIC) || 
+        (ntohl(pol->policy_version) != ACM_POLICY_VERSION) ||
+        (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
+        (ntohl(pol->secondary_policy_code) != 
acm_bin_pol.secondary_policy_code))
     {
-               printkd("%s: Wrong policy magics or versions!\n", __func__);
-               goto error_free;
-       }
-       if (buf_size != ntohl(pol->len))
+        printkd("%s: Wrong policy magics or versions!\n", __func__);
+        goto error_free;
+    }
+    if (buf_size != ntohl(pol->len))
     {
-               printk("%s: ERROR in buf size.\n", __func__);
-               goto error_free;
-       }
-
-       /* get bin_policy lock and rewrite policy (release old one) */
-       write_lock(&acm_bin_pol_rwlock);
-
-       /* 3. set primary policy data */
-       if (acm_primary_ops->set_binary_policy(buf + 
ntohl(pol->primary_buffer_offset),
-                                               
ntohl(pol->secondary_buffer_offset) -
-                                              
ntohl(pol->primary_buffer_offset)))
-               goto error_lock_free;
-
-       /* 4. set secondary policy data */
-       if (acm_secondary_ops->set_binary_policy(buf + 
ntohl(pol->secondary_buffer_offset),
-                                                ntohl(pol->len) - 
-                                                
ntohl(pol->secondary_buffer_offset)))
-               goto error_lock_free;
-
-       write_unlock(&acm_bin_pol_rwlock);
-       xfree(policy_buffer);
-       return ACM_OK;
+        printk("%s: ERROR in buf size.\n", __func__);
+        goto error_free;
+    }
+
+    /* get bin_policy lock and rewrite policy (release old one) */
+    write_lock(&acm_bin_pol_rwlock);
+
+    /* 3. set primary policy data */
+    if (acm_primary_ops->set_binary_policy(buf + 
ntohl(pol->primary_buffer_offset),
+                                           ntohl(pol->secondary_buffer_offset) 
-
+                                           ntohl(pol->primary_buffer_offset)))
+        goto error_lock_free;
+
+    /* 4. set secondary policy data */
+    if (acm_secondary_ops->set_binary_policy(buf + 
ntohl(pol->secondary_buffer_offset),
+                                             ntohl(pol->len) - 
+                                             
ntohl(pol->secondary_buffer_offset)))
+        goto error_lock_free;
+
+    write_unlock(&acm_bin_pol_rwlock);
+    xfree(policy_buffer);
+    return ACM_OK;
 
  error_lock_free:
-       write_unlock(&acm_bin_pol_rwlock);
+    write_unlock(&acm_bin_pol_rwlock);
  error_free:
-       printk("%s: Error setting policy.\n", __func__);
-    xfree(policy_buffer);
-       return -EFAULT;
-}
-
-int
-acm_get_policy(void *buf, u16 buf_size)
-{      
-     u8 *policy_buffer;
-     int ret;
-     struct acm_policy_buffer *bin_pol;
-       
+    printk("%s: Error setting policy.\n", __func__);
+    xfree(policy_buffer);
+    return -EFAULT;
+}
+
+int
+acm_get_policy(void *buf, u32 buf_size)
+{ 
+    u8 *policy_buffer;
+    int ret;
+    struct acm_policy_buffer *bin_pol;
+ 
     if (buf_size < sizeof(struct acm_policy_buffer))
-               return -EFAULT;
-
-     if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
-           return -ENOMEM;
-
-     read_lock(&acm_bin_pol_rwlock);
-
-     bin_pol = (struct acm_policy_buffer *)policy_buffer;
-     bin_pol->magic = htonl(ACM_MAGIC);
-     bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
-     bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
-
-     bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
-     bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
-     bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
+        return -EFAULT;
+
+    if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+        return -ENOMEM;
+
+    read_lock(&acm_bin_pol_rwlock);
+
+    bin_pol = (struct acm_policy_buffer *)policy_buffer;
+    bin_pol->magic = htonl(ACM_MAGIC);
+    bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
+    bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
+
+    bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
+    bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
+    bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
      
-     ret = acm_primary_ops->dump_binary_policy (policy_buffer + 
ntohl(bin_pol->primary_buffer_offset),
-                                      buf_size - 
ntohl(bin_pol->primary_buffer_offset));
-     if (ret < 0)
-         goto error_free_unlock;
-
-     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-     bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
-
-     ret = acm_secondary_ops->dump_binary_policy(policy_buffer + 
ntohl(bin_pol->secondary_buffer_offset),
-                                   buf_size - 
ntohl(bin_pol->secondary_buffer_offset));
-     if (ret < 0)
-         goto error_free_unlock;
-
-     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
-     if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
-            goto error_free_unlock;
-
-     read_unlock(&acm_bin_pol_rwlock);
-     xfree(policy_buffer);
-     return ACM_OK;
+    ret = acm_primary_ops->dump_binary_policy (policy_buffer + 
ntohl(bin_pol->primary_buffer_offset),
+                                               buf_size - 
ntohl(bin_pol->primary_buffer_offset));
+    if (ret < 0)
+        goto error_free_unlock;
+
+    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+    bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
+
+    ret = acm_secondary_ops->dump_binary_policy(policy_buffer + 
ntohl(bin_pol->secondary_buffer_offset),
+                                                buf_size - 
ntohl(bin_pol->secondary_buffer_offset));
+    if (ret < 0)
+        goto error_free_unlock;
+
+    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+    if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
+        goto error_free_unlock;
+
+    read_unlock(&acm_bin_pol_rwlock);
+    xfree(policy_buffer);
+    return ACM_OK;
 
  error_free_unlock:
-     read_unlock(&acm_bin_pol_rwlock);
-     printk("%s: Error getting policy.\n", __func__);
-     xfree(policy_buffer);
-     return -EFAULT;
+    read_unlock(&acm_bin_pol_rwlock);
+    printk("%s: Error getting policy.\n", __func__);
+    xfree(policy_buffer);
+    return -EFAULT;
 }
 
 int
 acm_dump_statistics(void *buf, u16 buf_size)
-{      
+{ 
     /* send stats to user space */
-     u8 *stats_buffer;
-     int len1, len2;
-     struct acm_stats_buffer acm_stats;
-
-     if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
-           return -ENOMEM;
-
-     read_lock(&acm_bin_pol_rwlock);
+    u8 *stats_buffer;
+    int len1, len2;
+    struct acm_stats_buffer acm_stats;
+
+    if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
+        return -ENOMEM;
+
+    read_lock(&acm_bin_pol_rwlock);
      
-     len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct 
acm_stats_buffer),
-                                            buf_size - sizeof(struct 
acm_stats_buffer));
-     if (len1 < 0)
-            goto error_lock_free;
-            
-     len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct 
acm_stats_buffer) + len1,
-                                              buf_size - sizeof(struct 
acm_stats_buffer) - len1);
-     if (len2 < 0)
-            goto error_lock_free;
-
-     acm_stats.magic = htonl(ACM_MAGIC);
-     acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
-     acm_stats.secondary_policy_code = 
htonl(acm_bin_pol.secondary_policy_code);
-     acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
-     acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) 
+ len1);
-     acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
-     memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
-
-     if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + 
len1 + len2))
-            goto error_lock_free;
-
-     read_unlock(&acm_bin_pol_rwlock);
-     xfree(stats_buffer);
-     return ACM_OK;
+    len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct 
acm_stats_buffer),
+                                            buf_size - sizeof(struct 
acm_stats_buffer));
+    if (len1 < 0)
+        goto error_lock_free;
+      
+    len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct 
acm_stats_buffer) + len1,
+                                              buf_size - sizeof(struct 
acm_stats_buffer) - len1);
+    if (len2 < 0)
+        goto error_lock_free;
+
+    acm_stats.magic = htonl(ACM_MAGIC);
+    acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
+    acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code);
+    acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer));
+    acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + 
len1);
+    acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
+
+    memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
+
+    if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 
+ len2))
+        goto error_lock_free;
+
+    read_unlock(&acm_bin_pol_rwlock);
+    xfree(stats_buffer);
+    return ACM_OK;
 
  error_lock_free:
-     read_unlock(&acm_bin_pol_rwlock);
-     xfree(stats_buffer);
-     return -EFAULT;
+    read_unlock(&acm_bin_pol_rwlock);
+    xfree(stats_buffer);
+    return -EFAULT;
 }
 
 
@@ -198,57 +199,88 @@
 acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
 {
     /* send stats to user space */
-     u8 *ssid_buffer;
-     int ret;
-     struct acm_ssid_buffer *acm_ssid;
-     if (buf_size < sizeof(struct acm_ssid_buffer))
-               return -EFAULT;
-
-     if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
-           return -ENOMEM;
-
-     read_lock(&acm_bin_pol_rwlock);
-
-     acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
-     acm_ssid->len = sizeof(struct acm_ssid_buffer);
-     acm_ssid->ssidref = ssidref;
-     acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
-     acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
-     acm_ssid->primary_types_offset = acm_ssid->len;
-
-     /* ret >= 0 --> ret == max_types */
-     ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
-                                            ssid_buffer + 
acm_ssid->primary_types_offset,
-                                            buf_size - 
acm_ssid->primary_types_offset);
-     if (ret < 0)
-         goto error_free_unlock;
-
-     acm_ssid->len += ret;
-     acm_ssid->primary_max_types = ret;
-
-     acm_ssid->secondary_types_offset = acm_ssid->len;
-
-     ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
-                                              ssid_buffer + 
acm_ssid->secondary_types_offset,
-                                              buf_size - 
acm_ssid->secondary_types_offset);
-     if (ret < 0)
-         goto error_free_unlock;
-
-     acm_ssid->len += ret;
-     acm_ssid->secondary_max_types = ret;
-
-     if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
-            goto error_free_unlock;
-
-     read_unlock(&acm_bin_pol_rwlock);
-     xfree(ssid_buffer);
-     return ACM_OK;
+    u8 *ssid_buffer;
+    int ret;
+    struct acm_ssid_buffer *acm_ssid;
+    if (buf_size < sizeof(struct acm_ssid_buffer))
+        return -EFAULT;
+
+    if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
+        return -ENOMEM;
+
+    read_lock(&acm_bin_pol_rwlock);
+
+    acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
+    acm_ssid->len = sizeof(struct acm_ssid_buffer);
+    acm_ssid->ssidref = ssidref;
+    acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
+    acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
+    acm_ssid->primary_types_offset = acm_ssid->len;
+
+    /* ret >= 0 --> ret == max_types */
+    ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
+                                           ssid_buffer + 
acm_ssid->primary_types_offset,
+                                           buf_size - 
acm_ssid->primary_types_offset);
+    if (ret < 0)
+        goto error_free_unlock;
+
+    acm_ssid->len += ret;
+    acm_ssid->primary_max_types = ret;
+    acm_ssid->secondary_types_offset = acm_ssid->len;
+
+    ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
+                                             ssid_buffer + 
acm_ssid->secondary_types_offset,
+                                             buf_size - 
acm_ssid->secondary_types_offset);
+    if (ret < 0)
+        goto error_free_unlock;
+
+    acm_ssid->len += ret;
+    acm_ssid->secondary_max_types = ret;
+
+    if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
+        goto error_free_unlock;
+
+    read_unlock(&acm_bin_pol_rwlock);
+    xfree(ssid_buffer);
+    return ACM_OK;
 
  error_free_unlock:
-     read_unlock(&acm_bin_pol_rwlock);
-     printk("%s: Error getting ssid.\n", __func__);
-     xfree(ssid_buffer);
-     return -ENOMEM;
-}
-
-/*eof*/
+    read_unlock(&acm_bin_pol_rwlock);
+    printk("%s: Error getting ssid.\n", __func__);
+    xfree(ssid_buffer);
+    return -ENOMEM;
+}
+
+int
+acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2,
+                 enum acm_hook_type hook)
+{
+    int ret = ACM_ACCESS_DENIED;
+    switch (hook) {
+
+    case SHARING:
+        /* SHARING Hook restricts access in STE policy only */
+        ret = acm_sharing(ssidref1, ssidref2);
+        break;
+
+    default:
+        /* deny */
+        break;
+    }
+
+    printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n",
+            __func__, ssidref1, ssidref2,
+            (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED");
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c       Thu Oct 20 18:37:41 2005
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c       Thu Oct 20 20:37:15 2005
@@ -24,6 +24,7 @@
  *     share at least on common type.
  *
  */
+
 #include <xen/lib.h>
 #include <asm/types.h>
 #include <asm/current.h>
@@ -35,34 +36,34 @@
 struct ste_binary_policy ste_bin_pol;
 
 static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) {
-       int i;
-       for(i=0; i< ste_bin_pol.max_types; i++)
-               if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && 
-                    ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) {
-                       printkd("%s: common type #%02x.\n", __func__, i);
-                       return 1;
-               }
-       return 0;
+    int i;
+    for(i=0; i< ste_bin_pol.max_types; i++)
+        if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && 
+             ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) {
+            printkd("%s: common type #%02x.\n", __func__, i);
+            return 1;
+        }
+    return 0;
 }
 
 /* Helper function: return = (subj and obj share a common type) */
 static int share_common_type(struct domain *subj, struct domain *obj)
 {
-       ssidref_t ref_s, ref_o;
-       int ret;
-
-       if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || 
(obj->ssid == NULL))
-               return 0;
-       read_lock(&acm_bin_pol_rwlock);
-       /* lookup the policy-local ssids */
-       ref_s = ((struct ste_ssid 
*)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                   (struct acm_ssid_domain 
*)subj->ssid)))->ste_ssidref;
-       ref_o = ((struct ste_ssid 
*)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                   (struct acm_ssid_domain 
*)obj->ssid)))->ste_ssidref;
-        /* check whether subj and obj share a common ste type */
-       ret = have_common_type(ref_s, ref_o);
-       read_unlock(&acm_bin_pol_rwlock);
-       return ret;
+    ssidref_t ref_s, ref_o;
+    int ret;
+
+    if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid 
== NULL))
+        return 0;
+    read_lock(&acm_bin_pol_rwlock);
+    /* lookup the policy-local ssids */
+    ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                           (struct acm_ssid_domain 
*)subj->ssid)))->ste_ssidref;
+    ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                           (struct acm_ssid_domain 
*)obj->ssid)))->ste_ssidref;
+    /* check whether subj and obj share a common ste type */
+    ret = have_common_type(ref_s, ref_o);
+    read_unlock(&acm_bin_pol_rwlock);
+    return ret;
 }
 
 /*
@@ -71,26 +72,26 @@
  */
 int acm_init_ste_policy(void)
 {
-       /* minimal startup policy; policy write-locked already */
-       ste_bin_pol.max_types = 1;
-       ste_bin_pol.max_ssidrefs = 2;
-       ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2);
-       memset(ste_bin_pol.ssidrefs, 0, 2);
-
-       if (ste_bin_pol.ssidrefs == NULL)
-               return ACM_INIT_SSID_ERROR;
-
-       /* initialize state so that dom0 can start up and communicate with 
itself */
-       ste_bin_pol.ssidrefs[1] = 1;
-
-       /* init stats */
-       atomic_set(&(ste_bin_pol.ec_eval_count), 0);
-       atomic_set(&(ste_bin_pol.ec_denied_count), 0); 
-       atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
-       atomic_set(&(ste_bin_pol.gt_eval_count), 0);
-       atomic_set(&(ste_bin_pol.gt_denied_count), 0); 
-       atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
-       return ACM_OK;
+    /* minimal startup policy; policy write-locked already */
+    ste_bin_pol.max_types = 1;
+    ste_bin_pol.max_ssidrefs = 2;
+    ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2);
+    memset(ste_bin_pol.ssidrefs, 0, 2);
+
+    if (ste_bin_pol.ssidrefs == NULL)
+        return ACM_INIT_SSID_ERROR;
+
+ /* initialize state so that dom0 can start up and communicate with itself */
+    ste_bin_pol.ssidrefs[1] = 1;
+
+    /* init stats */
+    atomic_set(&(ste_bin_pol.ec_eval_count), 0);
+    atomic_set(&(ste_bin_pol.ec_denied_count), 0); 
+    atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
+    atomic_set(&(ste_bin_pol.gt_eval_count), 0);
+    atomic_set(&(ste_bin_pol.gt_denied_count), 0); 
+    atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
+    return ACM_OK;
 }
 
 
@@ -98,62 +99,68 @@
 static int
 ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
 {
-       int i;
-       struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); 
-       traceprintk("%s.\n", __func__);
-
-       if (ste_ssidp == NULL)
-               return ACM_INIT_SSID_ERROR;
-
-       /* get policy-local ssid reference */
-       ste_ssidp->ste_ssidref = 
GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
-       if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) ||
-           (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) {
-               printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n",
-                       __func__, ste_ssidp->ste_ssidref);
-               xfree(ste_ssidp);
-               return ACM_INIT_SSID_ERROR;
-       }
-       /* clean ste cache */
-       for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-               ste_ssidp->ste_cache[i].valid = FREE;
-
-       (*ste_ssid) = ste_ssidp;
-       printkd("%s: determined ste_ssidref to %x.\n", 
-              __func__, ste_ssidp->ste_ssidref);
-       return ACM_OK;
+    int i;
+    struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); 
+    traceprintk("%s.\n", __func__);
+
+    if (ste_ssidp == NULL)
+        return ACM_INIT_SSID_ERROR;
+
+    /* get policy-local ssid reference */
+    ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
ssidref);
+    if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) ||
+        (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) {
+        printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n",
+                __func__, ste_ssidp->ste_ssidref);
+        xfree(ste_ssidp);
+        return ACM_INIT_SSID_ERROR;
+    }
+    /* clean ste cache */
+    for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+        ste_ssidp->ste_cache[i].valid = FREE;
+
+    (*ste_ssid) = ste_ssidp;
+    printkd("%s: determined ste_ssidref to %x.\n", 
+            __func__, ste_ssidp->ste_ssidref);
+    return ACM_OK;
 }
 
 
 static void
 ste_free_domain_ssid(void *ste_ssid)
 {
-       traceprintk("%s.\n", __func__);
-       if (ste_ssid != NULL)
-               xfree(ste_ssid);
-       return;
+    traceprintk("%s.\n", __func__);
+    if (ste_ssid != NULL)
+        xfree(ste_ssid);
+    return;
 }
 
 /* dump type enforcement cache; policy read-locked already */
 static int 
-ste_dump_policy(u8 *buf, u16 buf_size) {
-     struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer 
*)buf;
-     int ret = 0;
-
-     ste_buf->ste_max_types = htonl(ste_bin_pol.max_types);
-     ste_buf->ste_max_ssidrefs = htonl(ste_bin_pol.max_ssidrefs);
-     ste_buf->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
-     ste_buf->ste_ssid_offset = htonl(sizeof(struct acm_ste_policy_buffer));
-     ret = ntohl(ste_buf->ste_ssid_offset) +
-            
sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
-
-     /* now copy buffer over */
-     arrcpy(buf + ntohl(ste_buf->ste_ssid_offset),
-           ste_bin_pol.ssidrefs,
-           sizeof(domaintype_t),
-             ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
-
-     return ret;
+ste_dump_policy(u8 *buf, u32 buf_size) {
+    struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer 
*)buf;
+    int ret = 0;
+
+    if (buf_size < sizeof(struct acm_ste_policy_buffer))
+        return -EINVAL;
+
+    ste_buf->ste_max_types = htonl(ste_bin_pol.max_types);
+    ste_buf->ste_max_ssidrefs = htonl(ste_bin_pol.max_ssidrefs);
+    ste_buf->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+    ste_buf->ste_ssid_offset = htonl(sizeof(struct acm_ste_policy_buffer));
+    ret = ntohl(ste_buf->ste_ssid_offset) +
+        sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
+
+    if (buf_size < ret)
+        return -EINVAL;
+
+    /* now copy buffer over */
+    arrcpy(buf + ntohl(ste_buf->ste_ssid_offset),
+           ste_bin_pol.ssidrefs,
+           sizeof(domaintype_t),
+           ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
+
+    return ret;
 }
 
 /* ste_init_state is called when a policy is changed to detect violations 
(return != 0).
@@ -176,83 +183,83 @@
     /* go through all domains and adjust policy as if this domain was started 
now */
     pd = &domain_list;
     for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-           ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                (struct acm_ssid_domain *)(*pd)->ssid);
-           ste_ssidref = ste_ssid->ste_ssidref;
-           traceprintk("%s: validating policy for eventch domain %x 
(ste-Ref=%x).\n",
-                   __func__, (*pd)->domain_id, ste_ssidref);
-           /* a) check for event channel conflicts */
-           for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
-                   spin_lock(&(*pd)->evtchn_lock);
-                   if ((*pd)->evtchn[port] == NULL) {
-                            spin_unlock(&(*pd)->evtchn_lock);
-                           continue;
-                   }
-                   if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
-                           rdom = 
(*pd)->evtchn[port]->u.interdomain.remote_dom;
-                           rdomid = rdom->domain_id;
-                           /* rdom now has remote domain */
-                           ste_rssid = 
GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                                 (struct acm_ssid_domain 
*)(rdom->ssid));
-                           ste_rssidref = ste_rssid->ste_ssidref;
-                   } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) {
-                           rdomid = 
(*pd)->evtchn[port]->u.unbound.remote_domid;
-                           if ((rdom = find_domain_by_id(rdomid)) == NULL) {
-                                   printk("%s: Error finding domain to id 
%x!\n", __func__, rdomid);
-                                   goto out;
-                           }
-                           /* rdom now has remote domain */
-                           ste_rssid = 
GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                                 (struct acm_ssid_domain 
*)(rdom->ssid));
-                           ste_rssidref = ste_rssid->ste_ssidref;
-                           put_domain(rdom);
-                   } else {
-                           spin_unlock(&(*pd)->evtchn_lock);
-                           continue; /* port unused */
-                   }
-                   spin_unlock(&(*pd)->evtchn_lock);
-
-                   /* rdom now has remote domain */
-                   ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                            (struct acm_ssid_domain 
*)(rdom->ssid));
-                   ste_rssidref = ste_rssid->ste_ssidref;
-                   traceprintk("%s: eventch: domain %x (ssidref %x) --> domain 
%x (rssidref %x) used (port %x).\n", 
-                           __func__, (*pd)->domain_id, ste_ssidref, 
rdom->domain_id, ste_rssidref, port);  
-                   /* check whether on subj->ssid, obj->ssid share a common 
type*/
-                   if (!have_common_type(ste_ssidref, ste_rssidref)) {
-                           printkd("%s: Policy violation in event channel 
domain %x -> domain %x.\n",
-                                   __func__, (*pd)->domain_id, rdomid);
-                           goto out;
-                   }
-           }   
-           /* b) check for grant table conflicts on shared pages */
-           if ((*pd)->grant_table->shared == NULL) {
-                   printkd("%s: Grant ... sharing for domain %x not setup!\n", 
__func__, (*pd)->domain_id);
-                   continue;
-           }
-           for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) {
-                   sha_copy =  (*pd)->grant_table->shared[i];
-                   if ( sha_copy.flags ) {
-                           printkd("%s: grant dom (%hu) SHARED (%d) 
flags:(%hx) dom:(%hu) frame:(%lx)\n",
-                                   __func__, (*pd)->domain_id, i, 
sha_copy.flags, sha_copy.domid, 
-                                   (unsigned long)sha_copy.frame);
-                           rdomid = sha_copy.domid;
-                           if ((rdom = find_domain_by_id(rdomid)) == NULL) {
-                                   printkd("%s: domain not found ERROR!\n", 
__func__);
-                                   goto out;
-                           };
-                           /* rdom now has remote domain */
-                           ste_rssid = 
GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                                 (struct acm_ssid_domain 
*)(rdom->ssid));
-                           ste_rssidref = ste_rssid->ste_ssidref;
-                           put_domain(rdom);
-                           if (!have_common_type(ste_ssidref, ste_rssidref)) {
-                                   printkd("%s: Policy violation in grant 
table sharing domain %x -> domain %x.\n",
-                                           __func__, (*pd)->domain_id, rdomid);
-                                   goto out;
-                           }
-                   }
-           }
+        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                             (struct acm_ssid_domain *)(*pd)->ssid);
+        ste_ssidref = ste_ssid->ste_ssidref;
+        traceprintk("%s: validating policy for eventch domain %x 
(ste-Ref=%x).\n",
+                    __func__, (*pd)->domain_id, ste_ssidref);
+        /* a) check for event channel conflicts */
+        for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
+            spin_lock(&(*pd)->evtchn_lock);
+            if ((*pd)->evtchn[port] == NULL) {
+                spin_unlock(&(*pd)->evtchn_lock);
+                continue;
+            }
+            if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
+                rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom;
+                rdomid = rdom->domain_id;
+                /* rdom now has remote domain */
+                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                      (struct acm_ssid_domain *)(rdom->ssid));
+                ste_rssidref = ste_rssid->ste_ssidref;
+            } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) {
+                rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid;
+                if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+                    printk("%s: Error finding domain to id %x!\n", __func__, 
rdomid);
+                    goto out;
+                }
+                /* rdom now has remote domain */
+                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                      (struct acm_ssid_domain *)(rdom->ssid));
+                ste_rssidref = ste_rssid->ste_ssidref;
+                put_domain(rdom);
+            } else {
+                spin_unlock(&(*pd)->evtchn_lock);
+                continue; /* port unused */
+            }
+            spin_unlock(&(*pd)->evtchn_lock);
+
+            /* rdom now has remote domain */
+            ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                  (struct acm_ssid_domain *)(rdom->ssid));
+            ste_rssidref = ste_rssid->ste_ssidref;
+            traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x 
(rssidref %x) used (port %x).\n", 
+                        __func__, (*pd)->domain_id, ste_ssidref, 
rdom->domain_id, ste_rssidref, port);  
+            /* check whether on subj->ssid, obj->ssid share a common type*/
+            if (!have_common_type(ste_ssidref, ste_rssidref)) {
+                printkd("%s: Policy violation in event channel domain %x -> 
domain %x.\n",
+                        __func__, (*pd)->domain_id, rdomid);
+                goto out;
+            }
+        } 
+        /* b) check for grant table conflicts on shared pages */
+        if ((*pd)->grant_table->shared == NULL) {
+            printkd("%s: Grant ... sharing for domain %x not setup!\n", 
__func__, (*pd)->domain_id);
+            continue;
+        }
+        for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) {
+            sha_copy =  (*pd)->grant_table->shared[i];
+            if ( sha_copy.flags ) {
+                printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) 
frame:(%lx)\n",
+                        __func__, (*pd)->domain_id, i, sha_copy.flags, 
sha_copy.domid, 
+                        (unsigned long)sha_copy.frame);
+                rdomid = sha_copy.domid;
+                if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+                    printkd("%s: domain not found ERROR!\n", __func__);
+                    goto out;
+                };
+                /* rdom now has remote domain */
+                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                                      (struct acm_ssid_domain *)(rdom->ssid));
+                ste_rssidref = ste_rssid->ste_ssidref;
+                put_domain(rdom);
+                if (!have_common_type(ste_ssidref, ste_rssidref)) {
+                    printkd("%s: Policy violation in grant table sharing 
domain %x -> domain %x.\n",
+                            __func__, (*pd)->domain_id, rdomid);
+                    goto out;
+                }
+            }
+        }
     }
     violation = 0;
  out:
@@ -267,110 +274,78 @@
 
 /* set new policy; policy write-locked already */
 static int
-ste_set_policy(u8 *buf, u16 buf_size) 
-{
-     struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer 
*)buf;
-     void *ssidrefsbuf;
-     struct ste_ssid *ste_ssid;
-     struct domain **pd;
-     int i;
-
-     /* Convert endianess of policy */
-     ste_buf->policy_code = ntohl(ste_buf->policy_code);
-     ste_buf->policy_version = ntohl(ste_buf->policy_version);
-     ste_buf->ste_max_types = ntohl(ste_buf->ste_max_types);
-     ste_buf->ste_max_ssidrefs = ntohl(ste_buf->ste_max_ssidrefs);
-     ste_buf->ste_ssid_offset = ntohl(ste_buf->ste_ssid_offset);
-
-     /* policy type and version checks */
-     if ((ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ||
-        (ste_buf->policy_version != ACM_STE_VERSION))
-            return -EINVAL;
-
-     /* 1. create and copy-in new ssidrefs buffer */
-     ssidrefsbuf = xmalloc_array(u8, 
sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs);
-     if (ssidrefsbuf == NULL) {
-            return -ENOMEM;
-     }
-     if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * 
ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
-         goto error_free;
-
-     arrcpy(ssidrefsbuf, 
-            buf + ste_buf->ste_ssid_offset,
-            sizeof(domaintype_t),
-           ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
-
-     /* 2. now re-calculate sharing decisions based on running domains; 
-      *    this can fail if new policy is conflicting with sharing of running 
domains 
-      *    now: reject violating new policy; future: adjust sharing through 
revoking sharing */
-     if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) {
-            printk("%s: New policy conflicts with running domains. Policy load 
aborted.\n", __func__);
-            goto error_free; /* new policy conflicts with sharing of running 
domains */
-     }
-     /* 3. replace old policy (activate new policy) */
-     ste_bin_pol.max_types = ste_buf->ste_max_types;
-     ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
-     if (ste_bin_pol.ssidrefs) 
-            xfree(ste_bin_pol.ssidrefs);
-     ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
-
-     /* clear all ste caches */
-     read_lock(&domlist_lock);
-     pd = &domain_list;
-     for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                        (struct acm_ssid_domain *)(*pd)->ssid);
-        for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-               ste_ssid->ste_cache[i].valid = FREE;
-     }
-     read_unlock(&domlist_lock);
-     return ACM_OK;
-
-error_free:
-       printk("%s: ERROR setting policy.\n", __func__);
-       if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
-       return -EFAULT;
+ste_set_policy(u8 *buf, u32 buf_size)
+{
+    struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer 
*)buf;
+    void *ssidrefsbuf;
+    struct ste_ssid *ste_ssid;
+    struct domain **pd;
+    int i;
+
+    if (buf_size < sizeof(struct acm_ste_policy_buffer))
+        return -EINVAL;
+
+    /* Convert endianess of policy */
+    ste_buf->policy_code = ntohl(ste_buf->policy_code);
+    ste_buf->policy_version = ntohl(ste_buf->policy_version);
+    ste_buf->ste_max_types = ntohl(ste_buf->ste_max_types);
+    ste_buf->ste_max_ssidrefs = ntohl(ste_buf->ste_max_ssidrefs);
+    ste_buf->ste_ssid_offset = ntohl(ste_buf->ste_ssid_offset);
+
+    /* policy type and version checks */
+    if ((ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ||
+        (ste_buf->policy_version != ACM_STE_VERSION))
+        return -EINVAL;
+
+    /* 1. create and copy-in new ssidrefs buffer */
+    ssidrefsbuf = xmalloc_array(u8, 
sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs);
+    if (ssidrefsbuf == NULL) {
+        return -ENOMEM;
+    }
+    if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * 
ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
+        goto error_free;
+
+    arrcpy(ssidrefsbuf, 
+           buf + ste_buf->ste_ssid_offset,
+           sizeof(domaintype_t),
+           ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
+
+    /* 2. now re-calculate sharing decisions based on running domains; 
+     *    this can fail if new policy is conflicting with sharing of running 
domains 
+     *    now: reject violating new policy; future: adjust sharing through 
revoking sharing */
+    if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) {
+        printk("%s: New policy conflicts with running domains. Policy load 
aborted.\n", __func__);
+        goto error_free; /* new policy conflicts with sharing of running 
domains */
+    }
+    /* 3. replace old policy (activate new policy) */
+    ste_bin_pol.max_types = ste_buf->ste_max_types;
+    ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
+    if (ste_bin_pol.ssidrefs) 
+        xfree(ste_bin_pol.ssidrefs);
+    ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
+
+    /* clear all ste caches */
+    read_lock(&domlist_lock);
+    pd = &domain_list;
+    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                             (struct acm_ssid_domain *)(*pd)->ssid);
+        for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+            ste_ssid->ste_cache[i].valid = FREE;
+    }
+    read_unlock(&domlist_lock);
+    return ACM_OK;
+
+ error_free:
+    printk("%s: ERROR setting policy.\n", __func__);
+    if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
+    return -EFAULT;
 }
 
 static int 
 ste_dump_stats(u8 *buf, u16 buf_len)
 {
     struct acm_ste_stats_buffer stats;
-
-#ifdef ACM_DEBUG
-    int i;
-    struct ste_ssid *ste_ssid;
-    struct domain **pd;
-
-    printk("ste: Decision caches:\n");
-    /* go through all domains and adjust policy as if this domain was started 
now */
-    read_lock(&domlist_lock); /* go by domain? or directly by global? 
event/grant list */
-    pd = &domain_list;
-    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-        printk("ste: Cache Domain %02x.\n", (*pd)->domain_id);
-       ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                        (struct acm_ssid_domain *)(*pd)->ssid);
-       for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-               printk("\t\tcache[%02x] = %s, domid=%x.\n", i,
-                      (ste_ssid->ste_cache[i].valid == VALID) ? 
-                      "VALID" : "FREE",
-                      (ste_ssid->ste_cache[i].valid == VALID) ? 
-                      ste_ssid->ste_cache[i].id : 0xffffffff);
-    }
-    read_unlock(&domlist_lock);
-    /* init stats */
-    printk("STE-Policy Security Hook Statistics:\n");
-    printk("ste: event_channel eval_count      = %x\n", 
atomic_read(&(ste_bin_pol.ec_eval_count)));
-    printk("ste: event_channel denied_count    = %x\n", 
atomic_read(&(ste_bin_pol.ec_denied_count))); 
-    printk("ste: event_channel cache_hit_count = %x\n", 
atomic_read(&(ste_bin_pol.ec_cachehit_count)));
-    printk("ste:\n");
-    printk("ste: grant_table   eval_count      = %x\n", 
atomic_read(&(ste_bin_pol.gt_eval_count)));
-    printk("ste: grant_table   denied_count    = %x\n", 
atomic_read(&(ste_bin_pol.gt_denied_count))); 
-    printk("ste: grant_table   cache_hit_count = %x\n", 
atomic_read(&(ste_bin_pol.gt_cachehit_count)));
-#endif
-
-    if (buf_len < sizeof(struct acm_ste_stats_buffer))
-           return -ENOMEM;
 
     /* now send the hook counts to user space */
     stats.ec_eval_count = htonl(atomic_read(&ste_bin_pol.ec_eval_count));
@@ -379,6 +354,10 @@
     stats.gt_denied_count = htonl(atomic_read(&ste_bin_pol.gt_denied_count)); 
     stats.ec_cachehit_count = 
htonl(atomic_read(&ste_bin_pol.ec_cachehit_count));
     stats.gt_cachehit_count = 
htonl(atomic_read(&ste_bin_pol.gt_cachehit_count));
+
+    if (buf_len < sizeof(struct acm_ste_stats_buffer))
+        return -ENOMEM;
+
     memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));
     return sizeof(struct acm_ste_stats_buffer);
 }
@@ -392,12 +371,12 @@
     if (ste_bin_pol.max_types > len)
         return -EFAULT;
 
-       if (ssidref >= ste_bin_pol.max_ssidrefs)
-               return -EFAULT;
+    if (ssidref >= ste_bin_pol.max_ssidrefs)
+        return -EFAULT;
 
     /* read types for chwall ssidref */
     for(i=0; i< ste_bin_pol.max_types; i++) {
-               if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])
+        if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])
             buf[i] = 1;
         else
             buf[i] = 0;
@@ -409,40 +388,40 @@
  * returns 1 == cache hit */
 static int inline
 check_cache(struct domain *dom, domid_t rdom) {
-       struct ste_ssid *ste_ssid;
-       int i;
-
-       printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
-       ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                        (struct acm_ssid_domain *)(dom)->ssid);
-
-       for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
-               if ((ste_ssid->ste_cache[i].valid == VALID) &&
-                   (ste_ssid->ste_cache[i].id == rdom)) {
-                       printkd("cache hit (entry %x, id= %x!\n", i, 
ste_ssid->ste_cache[i].id);
-                       return 1;
-               }
-       }
-       return 0;
+    struct ste_ssid *ste_ssid;
+    int i;
+
+    printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
+    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                         (struct acm_ssid_domain *)(dom)->ssid);
+
+    for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
+        if ((ste_ssid->ste_cache[i].valid == VALID) &&
+            (ste_ssid->ste_cache[i].id == rdom)) {
+            printkd("cache hit (entry %x, id= %x!\n", i, 
ste_ssid->ste_cache[i].id);
+            return 1;
+        }
+    }
+    return 0;
 }
 
 
 /* we only get here if there is NO entry yet; no duplication check! */
 static void inline
 cache_result(struct domain *subj, struct domain *obj) {
-       struct ste_ssid *ste_ssid;
-       int i;
-       printkd("caching from doms: %x --> %x.\n", subj->domain_id, 
obj->domain_id);
-       ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                        (struct acm_ssid_domain *)(subj)->ssid);
-       for(i=0; i< ACM_TE_CACHE_SIZE; i++)
-               if (ste_ssid->ste_cache[i].valid == FREE)
-                       break;
-       if (i< ACM_TE_CACHE_SIZE) {
-               ste_ssid->ste_cache[i].valid = VALID;
-               ste_ssid->ste_cache[i].id = obj->domain_id;
-       } else
-               printk ("Cache of dom %x is full!\n", subj->domain_id);
+    struct ste_ssid *ste_ssid;
+    int i;
+    printkd("caching from doms: %x --> %x.\n", subj->domain_id, 
obj->domain_id);
+    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                         (struct acm_ssid_domain *)(subj)->ssid);
+    for(i=0; i< ACM_TE_CACHE_SIZE; i++)
+        if (ste_ssid->ste_cache[i].valid == FREE)
+            break;
+    if (i< ACM_TE_CACHE_SIZE) {
+        ste_ssid->ste_cache[i].valid = VALID;
+        ste_ssid->ste_cache[i].id = obj->domain_id;
+    } else
+        printk ("Cache of dom %x is full!\n", subj->domain_id);
 }
 
 /* deletes entries for domain 'id' from all caches (re-use) */
@@ -458,12 +437,12 @@
     read_lock(&domlist_lock); /* look through caches of all domains */
     pd = &domain_list;
     for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
-       ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                        (struct acm_ssid_domain *)(*pd)->ssid);
-       for (i=0; i<ACM_TE_CACHE_SIZE; i++)
-           if ((ste_ssid->ste_cache[i].valid == VALID) &&
-               (ste_ssid->ste_cache[i].id = id))
-                   ste_ssid->ste_cache[i].valid = FREE;
+        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                             (struct acm_ssid_domain *)(*pd)->ssid);
+        for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+            if ((ste_ssid->ste_cache[i].valid == VALID) &&
+                (ste_ssid->ste_cache[i].id = id))
+                ste_ssid->ste_cache[i].valid = FREE;
     }
     read_unlock(&domlist_lock);
 }
@@ -482,15 +461,15 @@
     read_lock(&acm_bin_pol_rwlock);
     ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
     if (ste_ssidref == ACM_DEFAULT_LOCAL_SSID) {
-       printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", 
__func__);
-       read_unlock(&acm_bin_pol_rwlock);
-       return ACM_ACCESS_DENIED; /* catching and indicating config error */
+        printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", 
__func__);
+        read_unlock(&acm_bin_pol_rwlock);
+        return ACM_ACCESS_DENIED; /* catching and indicating config error */
     }
     if (ste_ssidref >= ste_bin_pol.max_ssidrefs) {
-       printk("%s: ERROR ste_ssidref > max(%x).\n", 
-              __func__, ste_bin_pol.max_ssidrefs-1);
-       read_unlock(&acm_bin_pol_rwlock);
-       return ACM_ACCESS_DENIED;
+        printk("%s: ERROR ste_ssidref > max(%x).\n", 
+               __func__, ste_bin_pol.max_ssidrefs-1);
+        read_unlock(&acm_bin_pol_rwlock);
+        return ACM_ACCESS_DENIED;
     }
     read_unlock(&acm_bin_pol_rwlock);
     return ACM_ACCESS_PERMITTED;
@@ -506,163 +485,193 @@
 /* -------- EVENTCHANNEL OPERATIONS -----------*/
 static int
 ste_pre_eventchannel_unbound(domid_t id) {
-       struct domain *subj, *obj;
-       int ret;
-       traceprintk("%s: dom%x-->dom%x.\n", 
-                   __func__, current->domain->domain_id, id);
-
-       if (check_cache(current->domain, id)) {
-               atomic_inc(&ste_bin_pol.ec_cachehit_count);
-               return ACM_ACCESS_PERMITTED;
-       }
-       atomic_inc(&ste_bin_pol.ec_eval_count);
-       subj = current->domain;
-       obj = find_domain_by_id(id);
-
-       if (share_common_type(subj, obj)) {
-               cache_result(subj, obj);
-               ret = ACM_ACCESS_PERMITTED;
-       } else {
-               atomic_inc(&ste_bin_pol.ec_denied_count); 
-               ret = ACM_ACCESS_DENIED;        
-       }
-       if (obj != NULL)
-               put_domain(obj);
-       return ret;
+    struct domain *subj, *obj;
+    int ret;
+    traceprintk("%s: dom%x-->dom%x.\n", 
+                __func__, current->domain->domain_id, id);
+
+    if (check_cache(current->domain, id)) {
+        atomic_inc(&ste_bin_pol.ec_cachehit_count);
+        return ACM_ACCESS_PERMITTED;
+    }
+    atomic_inc(&ste_bin_pol.ec_eval_count);
+    subj = current->domain;
+    obj = find_domain_by_id(id);
+
+    if (share_common_type(subj, obj)) {
+        cache_result(subj, obj);
+        ret = ACM_ACCESS_PERMITTED;
+    } else {
+        atomic_inc(&ste_bin_pol.ec_denied_count); 
+        ret = ACM_ACCESS_DENIED; 
+    }
+    if (obj != NULL)
+        put_domain(obj);
+    return ret;
 }
 
 static int
 ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
 {
-       struct domain *subj, *obj;
-       int ret;
-       traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                   (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
-                   (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
-
-       /* following is a bit longer but ensures that we
-         * "put" only domains that we where "find"-ing 
-        */
-       if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
-       if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
-
-       subj = find_domain_by_id(id1);
-       obj  = find_domain_by_id(id2);
-       if ((subj == NULL) || (obj == NULL)) {
-               ret = ACM_ACCESS_DENIED;
-               goto out;
-       }
-       /* cache check late, but evtchn is not on performance critical path */
-       if (check_cache(subj, obj->domain_id)) {
-               atomic_inc(&ste_bin_pol.ec_cachehit_count);
-               ret = ACM_ACCESS_PERMITTED;
-               goto out;
-       }
-       atomic_inc(&ste_bin_pol.ec_eval_count);
-
-       if (share_common_type(subj, obj)) {
-               cache_result(subj, obj);
-               ret = ACM_ACCESS_PERMITTED;
-       } else {
-               atomic_inc(&ste_bin_pol.ec_denied_count); 
-               ret = ACM_ACCESS_DENIED;        
-       }
+    struct domain *subj, *obj;
+    int ret;
+    traceprintk("%s: dom%x-->dom%x.\n", __func__,
+                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
+                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
+
+    /* following is a bit longer but ensures that we
+     * "put" only domains that we where "find"-ing 
+     */
+    if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
+    if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
+
+    subj = find_domain_by_id(id1);
+    obj  = find_domain_by_id(id2);
+    if ((subj == NULL) || (obj == NULL)) {
+        ret = ACM_ACCESS_DENIED;
+        goto out;
+    }
+    /* cache check late, but evtchn is not on performance critical path */
+    if (check_cache(subj, obj->domain_id)) {
+        atomic_inc(&ste_bin_pol.ec_cachehit_count);
+        ret = ACM_ACCESS_PERMITTED;
+        goto out;
+    }
+    atomic_inc(&ste_bin_pol.ec_eval_count);
+
+    if (share_common_type(subj, obj)) {
+        cache_result(subj, obj);
+        ret = ACM_ACCESS_PERMITTED;
+    } else {
+        atomic_inc(&ste_bin_pol.ec_denied_count); 
+        ret = ACM_ACCESS_DENIED; 
+    }
  out:
-       if (obj != NULL)
-               put_domain(obj);
-       if (subj != NULL)
-               put_domain(subj);
-       return ret;
+    if (obj != NULL)
+        put_domain(obj);
+    if (subj != NULL)
+        put_domain(subj);
+    return ret;
 }
 
 /* -------- SHARED MEMORY OPERATIONS -----------*/
 
 static int
 ste_pre_grant_map_ref (domid_t id) {
-       struct domain *obj, *subj;
-       int ret;
-       traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                   current->domain->domain_id, id);
-
-       if (check_cache(current->domain, id)) {
-               atomic_inc(&ste_bin_pol.gt_cachehit_count);
-               return ACM_ACCESS_PERMITTED;
-       }
-       atomic_inc(&ste_bin_pol.gt_eval_count);
-       subj = current->domain;
-       obj = find_domain_by_id(id);
-
-       if (share_common_type(subj, obj)) {
-               cache_result(subj, obj);
-               ret = ACM_ACCESS_PERMITTED;
-       } else {
-               atomic_inc(&ste_bin_pol.gt_denied_count); 
-               printkd("%s: ACCESS DENIED!\n", __func__);
-               ret = ACM_ACCESS_DENIED;        
-       }
-       if (obj != NULL)
-               put_domain(obj);
-       return ret;
-}
+    struct domain *obj, *subj;
+    int ret;
+    traceprintk("%s: dom%x-->dom%x.\n", __func__,
+                current->domain->domain_id, id);
+
+    if (check_cache(current->domain, id)) {
+        atomic_inc(&ste_bin_pol.gt_cachehit_count);
+        return ACM_ACCESS_PERMITTED;
+    }
+    atomic_inc(&ste_bin_pol.gt_eval_count);
+    subj = current->domain;
+    obj = find_domain_by_id(id);
+
+    if (share_common_type(subj, obj)) {
+        cache_result(subj, obj);
+        ret = ACM_ACCESS_PERMITTED;
+    } else {
+        atomic_inc(&ste_bin_pol.gt_denied_count); 
+        printkd("%s: ACCESS DENIED!\n", __func__);
+        ret = ACM_ACCESS_DENIED; 
+    }
+    if (obj != NULL)
+        put_domain(obj);
+    return ret;
+}
+
 
 /* since setting up grant tables involves some implicit information
    flow from the creating domain to the domain that is setup, we 
    check types in addition to the general authorization */
 static int
 ste_pre_grant_setup (domid_t id) {
-       struct domain *obj, *subj;
-       int ret;
-       traceprintk("%s: dom%x-->dom%x.\n", __func__,
-                   current->domain->domain_id, id);
-
-       if (check_cache(current->domain, id)) {
-               atomic_inc(&ste_bin_pol.gt_cachehit_count);
-               return ACM_ACCESS_PERMITTED;
-       }
-       atomic_inc(&ste_bin_pol.gt_eval_count);
-       /* a) check authorization (eventually use specific capabilities) */
-       if (!IS_PRIV(current->domain)) {
-               printk("%s: Grant table management authorization denied 
ERROR!\n", __func__);
-               return ACM_ACCESS_DENIED;
-       }
-       /* b) check types */
-       subj = current->domain;
-       obj = find_domain_by_id(id);
-
-       if (share_common_type(subj, obj)) {
-               cache_result(subj, obj);
-               ret = ACM_ACCESS_PERMITTED;
-       } else {
-               atomic_inc(&ste_bin_pol.gt_denied_count); 
-               ret = ACM_ACCESS_DENIED;        
-       }
-       if (obj != NULL)
-               put_domain(obj);
-       return ret;
-}
+    struct domain *obj, *subj;
+    int ret;
+    traceprintk("%s: dom%x-->dom%x.\n", __func__,
+                current->domain->domain_id, id);
+
+    if (check_cache(current->domain, id)) {
+        atomic_inc(&ste_bin_pol.gt_cachehit_count);
+        return ACM_ACCESS_PERMITTED;
+    }
+    atomic_inc(&ste_bin_pol.gt_eval_count);
+    /* a) check authorization (eventually use specific capabilities) */
+    if (!IS_PRIV(current->domain)) {
+        printk("%s: Grant table management authorization denied ERROR!\n", 
__func__);
+        return ACM_ACCESS_DENIED;
+    }
+    /* b) check types */
+    subj = current->domain;
+    obj = find_domain_by_id(id);
+
+    if (share_common_type(subj, obj)) {
+        cache_result(subj, obj);
+        ret = ACM_ACCESS_PERMITTED;
+    } else {
+        atomic_inc(&ste_bin_pol.gt_denied_count); 
+        ret = ACM_ACCESS_DENIED; 
+    }
+    if (obj != NULL)
+        put_domain(obj);
+    return ret;
+}
+
+/* -------- DOMAIN-Requested Decision hooks -----------*/
+
+static int
+ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2) {
+    if (have_common_type (
+        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),
+        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2)
+        ))
+        return ACM_ACCESS_PERMITTED;
+    else
+        return ACM_ACCESS_DENIED;
+}
+
 
 /* now define the hook structure similarly to LSM */
 struct acm_operations acm_simple_type_enforcement_ops = {
-       /* policy management services */
-       .init_domain_ssid               = ste_init_domain_ssid,
-       .free_domain_ssid               = ste_free_domain_ssid,
-       .dump_binary_policy     = ste_dump_policy,
-       .set_binary_policy      = ste_set_policy,
-       .dump_statistics                = ste_dump_stats,
+
+    /* policy management services */
+    .init_domain_ssid  = ste_init_domain_ssid,
+    .free_domain_ssid  = ste_free_domain_ssid,
+    .dump_binary_policy     = ste_dump_policy,
+    .set_binary_policy      = ste_set_policy,
+    .dump_statistics  = ste_dump_stats,
     .dump_ssid_types        = ste_dump_ssid_types,
-       /* domain management control hooks */
-       .pre_domain_create              = ste_pre_domain_create,
-       .post_domain_create         = NULL,
-       .fail_domain_create     = NULL,
-       .post_domain_destroy    = ste_post_domain_destroy,
-       /* event channel control hooks */
-       .pre_eventchannel_unbound   = ste_pre_eventchannel_unbound,
-       .fail_eventchannel_unbound      = NULL,
-       .pre_eventchannel_interdomain   = ste_pre_eventchannel_interdomain,
-       .fail_eventchannel_interdomain  = NULL,
-       /* grant table control hooks */
-       .pre_grant_map_ref      = ste_pre_grant_map_ref,
-       .fail_grant_map_ref     = NULL,
-       .pre_grant_setup        = ste_pre_grant_setup,
-       .fail_grant_setup       = NULL,
+
+    /* domain management control hooks */
+    .pre_domain_create       = ste_pre_domain_create,
+    .post_domain_create     = NULL,
+    .fail_domain_create     = NULL,
+    .post_domain_destroy    = ste_post_domain_destroy,
+
+    /* event channel control hooks */
+    .pre_eventchannel_unbound   = ste_pre_eventchannel_unbound,
+    .fail_eventchannel_unbound = NULL,
+    .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
+    .fail_eventchannel_interdomain  = NULL,
+
+    /* grant table control hooks */
+    .pre_grant_map_ref      = ste_pre_grant_map_ref,
+    .fail_grant_map_ref     = NULL,
+    .pre_grant_setup        = ste_pre_grant_setup,
+    .fail_grant_setup       = NULL,
+    .sharing                = ste_sharing,
 };
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Thu Oct 20 18:37:41 2005
+++ b/xen/common/acm_ops.c      Thu Oct 20 20:37:15 2005
@@ -31,22 +31,23 @@
 
 #if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
 
-long do_acm_op(acm_op_t * u_acm_op)
+long do_acm_op(struct acm_op * u_acm_op)
 {
     return -ENOSYS;
 }
 
 #else
 
-typedef enum acm_operation {
+enum acm_operation {
     POLICY,                     /* access to policy interface (early drop) */
     GETPOLICY,                  /* dump policy cache */
     SETPOLICY,                  /* set policy cache (controls security) */
     DUMPSTATS,                  /* dump policy statistics */
-    GETSSID                     /* retrieve ssidref for domain id */
-} acm_operation_t;
-
-int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops)
+    GETSSID,                    /* retrieve ssidref for domain id (decide 
inside authorized domains) */
+    GETDECISION                 /* retrieve ACM decision from authorized 
domains */
+};
+
+int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
 {
     /* all policy management functions are restricted to privileged domains,
      * soon we will introduce finer-grained privileges for policy operations
@@ -59,10 +60,10 @@
     return ACM_ACCESS_PERMITTED;
 }
 
-long do_acm_op(acm_op_t * u_acm_op)
+long do_acm_op(struct acm_op * u_acm_op)
 {
     long ret = 0;
-    acm_op_t curop, *op = &curop;
+    struct acm_op curop, *op = &curop;
 
     /* check here policy decision for policy commands */
     /* for now allow DOM0 only, later indepedently    */
@@ -78,81 +79,148 @@
     switch (op->cmd)
     {
     case ACM_SETPOLICY:
-        {
-            if (acm_authorize_acm_ops(current->domain, SETPOLICY))
-                return -EACCES;
-            printkd("%s: setting policy.\n", __func__);
-            ret = acm_set_policy(op->u.setpolicy.pushcache,
-                                 op->u.setpolicy.pushcache_size, 1);
-            if (ret == ACM_OK)
-                ret = 0;
-            else
-                ret = -ESRCH;
-        }
-        break;
+    {
+        if (acm_authorize_acm_ops(current->domain, SETPOLICY))
+            return -EACCES;
+        printkd("%s: setting policy.\n", __func__);
+        ret = acm_set_policy(op->u.setpolicy.pushcache,
+                             op->u.setpolicy.pushcache_size, 1);
+        if (ret == ACM_OK)
+            ret = 0;
+        else
+            ret = -ESRCH;
+    }
+    break;
 
     case ACM_GETPOLICY:
-        {
-            if (acm_authorize_acm_ops(current->domain, GETPOLICY))
-                return -EACCES;
-            printkd("%s: getting policy.\n", __func__);
-            ret = acm_get_policy(op->u.getpolicy.pullcache,
-                                 op->u.getpolicy.pullcache_size);
-            if (ret == ACM_OK)
-                ret = 0;
-            else
-                ret = -ESRCH;
-        }
-        break;
+    {
+        if (acm_authorize_acm_ops(current->domain, GETPOLICY))
+            return -EACCES;
+        printkd("%s: getting policy.\n", __func__);
+        ret = acm_get_policy(op->u.getpolicy.pullcache,
+                             op->u.getpolicy.pullcache_size);
+        if (ret == ACM_OK)
+            ret = 0;
+        else
+            ret = -ESRCH;
+    }
+    break;
 
     case ACM_DUMPSTATS:
-        {
-            if (acm_authorize_acm_ops(current->domain, DUMPSTATS))
-                return -EACCES;
-            printkd("%s: dumping statistics.\n", __func__);
-            ret = acm_dump_statistics(op->u.dumpstats.pullcache,
-                                      op->u.dumpstats.pullcache_size);
-            if (ret == ACM_OK)
-                ret = 0;
-            else
-                ret = -ESRCH;
-        }
-        break;
+    {
+        if (acm_authorize_acm_ops(current->domain, DUMPSTATS))
+            return -EACCES;
+        printkd("%s: dumping statistics.\n", __func__);
+        ret = acm_dump_statistics(op->u.dumpstats.pullcache,
+                                  op->u.dumpstats.pullcache_size);
+        if (ret == ACM_OK)
+            ret = 0;
+        else
+            ret = -ESRCH;
+    }
+    break;
 
     case ACM_GETSSID:
-        {
-                       ssidref_t ssidref;
-
-            if (acm_authorize_acm_ops(current->domain, GETSSID))
-                return -EACCES;
-
-                       if (op->u.getssid.get_ssid_by == SSIDREF)
-                               ssidref = op->u.getssid.id.ssidref;
-                       else if (op->u.getssid.get_ssid_by == DOMAINID) {
-                               struct domain *subj = 
find_domain_by_id(op->u.getssid.id.domainid);
-                               if (!subj)
-                                       return -ESRCH; /* domain not found */
-
-                               ssidref = ((struct acm_ssid_domain 
*)(subj->ssid))->ssidref;
-                               put_domain(subj);
-                       } else
-                               return -ESRCH;
-
-            ret = acm_get_ssid(ssidref,
-                               op->u.getssid.ssidbuf,
-                               op->u.getssid.ssidbuf_size);
-            if (ret == ACM_OK)
-                ret = 0;
-            else
-                ret = -ESRCH;
-        }
-        break;
+    {
+        ssidref_t ssidref;
+
+        if (acm_authorize_acm_ops(current->domain, GETSSID))
+            return -EACCES;
+        printkd("%s: getting SSID.\n", __func__);
+        if (op->u.getssid.get_ssid_by == SSIDREF)
+            ssidref = op->u.getssid.id.ssidref;
+        else if (op->u.getssid.get_ssid_by == DOMAINID) {
+            struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
+            if (!subj)
+                return -ESRCH; /* domain not found */
+
+            ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
+            put_domain(subj);
+        } else
+            return -ESRCH;
+
+        ret = acm_get_ssid(ssidref,
+                           op->u.getssid.ssidbuf,
+                           op->u.getssid.ssidbuf_size);
+        if (ret == ACM_OK)
+            ret = 0;
+        else
+            ret = -ESRCH;
+    }
+    break;
+
+    case ACM_GETDECISION:
+    {
+        ssidref_t ssidref1, ssidref2;
+
+        if (acm_authorize_acm_ops(current->domain, GETDECISION)) {
+            ret = -EACCES;
+            goto out;
+        }
+        printkd("%s: getting access control decision.\n", __func__);
+        if (op->u.getdecision.get_decision_by1 == SSIDREF) {
+            ssidref1 = op->u.getdecision.id1.ssidref;
+        }
+        else if (op->u.getdecision.get_decision_by1 == DOMAINID) {
+            struct domain *subj = 
find_domain_by_id(op->u.getdecision.id1.domainid);
+            if (!subj) {
+                ret = -ESRCH; /* domain not found */
+                goto out;
+            }
+            ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
+            put_domain(subj);
+        } else {
+            ret = -ESRCH;
+            goto out;
+        }
+        if (op->u.getdecision.get_decision_by2 == SSIDREF) {
+            ssidref2 = op->u.getdecision.id2.ssidref;
+        }
+        else if (op->u.getdecision.get_decision_by2 == DOMAINID) {
+            struct domain *subj = 
find_domain_by_id(op->u.getdecision.id2.domainid);
+            if (!subj) {
+                ret = -ESRCH; /* domain not found */
+                goto out;
+            }
+            ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
+            put_domain(subj);
+        } else {
+            ret = -ESRCH;
+            goto out;
+        }
+        ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
+    }
+    break;
 
     default:
         ret = -ESRCH;
-
-    }
+    }
+
+ out:
+    if (ret == ACM_ACCESS_PERMITTED) {
+        op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
+        ret = 0;
+    } else if  (ret == ACM_ACCESS_DENIED) {
+        op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
+        ret = 0;
+    } else {
+        op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
+        if (ret > 0)
+            ret = -ret;
+    }
+    /* copy decision back to user space */
+    copy_to_user(u_acm_op, op, sizeof(*op));
     return ret;
 }
 
 #endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     Thu Oct 20 18:37:41 2005
+++ b/xen/common/dom0_ops.c     Thu Oct 20 20:37:15 2005
@@ -199,7 +199,7 @@
         /*
          * If we're on a HT system, we only use the first HT for dom0, other 
          * domains will all share the second HT of each CPU. Since dom0 is on 
-            * CPU 0, we favour high numbered CPUs in the event of a tie.
+         * CPU 0, we favour high numbered CPUs in the event of a tie.
          */
         pro = smp_num_siblings - 1;
         for ( i = pro; i < num_online_cpus(); i += smp_num_siblings )
diff -r 6f5b94da963a -r 1e40bed176d4 xen/common/sched_sedf.c
--- a/xen/common/sched_sedf.c   Thu Oct 20 18:37:41 2005
+++ b/xen/common/sched_sedf.c   Thu Oct 20 20:37:15 2005
@@ -1150,7 +1150,7 @@
     inf->block_tot++;
 #endif
     if (unlikely(now < PERIOD_BEGIN(inf))) {
-       PRINT(4,"extratime unblock\n");
+        PRINT(4,"extratime unblock\n");
         /* unblocking in extra-time! */
 #if (EXTRA == EXTRA_BLOCK_WEIGHT)
         if (inf->status & EXTRA_WANT_PEN_Q) {
@@ -1459,3 +1459,13 @@
     .wake           = sedf_wake,
     .adjdom         = sedf_adjdom,
 };
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h        Thu Oct 20 18:37:41 2005
+++ b/xen/include/acm/acm_core.h        Thu Oct 20 20:37:15 2005
@@ -15,6 +15,7 @@
  *    for the access control module and relevant policies
  *
  */
+
 #ifndef _ACM_CORE_H
 #define _ACM_CORE_H
 
@@ -25,30 +26,30 @@
 
 /* Xen-internal representation of the binary policy */
 struct acm_binary_policy {
-       u16 primary_policy_code;
-       u16 secondary_policy_code;
-       void *primary_binary_policy;                                 
-       void *secondary_binary_policy;
-       
+    u16 primary_policy_code;
+    u16 secondary_policy_code;
+    void *primary_binary_policy;                                 
+    void *secondary_binary_policy;
+ 
 };
 
 struct chwall_binary_policy {
-       u16 max_types;
-       u16 max_ssidrefs;
-       u16 max_conflictsets;
-       domaintype_t *ssidrefs;                 /* [max_ssidrefs][max_types]    
*/
-       domaintype_t *conflict_aggregate_set;   /* [max_types]                  
*/
-       domaintype_t *running_types;            /* [max_types]                  
*/
-       domaintype_t *conflict_sets;            /* 
[max_conflictsets][max_types]*/
+    u32 max_types;
+    u32 max_ssidrefs;
+    u32 max_conflictsets;
+    domaintype_t *ssidrefs;     /* [max_ssidrefs][max_types]  */
+    domaintype_t *conflict_aggregate_set;  /* [max_types]      */
+    domaintype_t *running_types;    /* [max_types]      */
+    domaintype_t *conflict_sets;   /* [max_conflictsets][max_types]*/
 };
 
 struct ste_binary_policy {
-       u16 max_types;
-       u16 max_ssidrefs;
-       domaintype_t *ssidrefs;                 /* [max_ssidrefs][max_types]    
*/
-       atomic_t ec_eval_count, gt_eval_count;
-       atomic_t ec_denied_count, gt_denied_count; 
-       atomic_t ec_cachehit_count, gt_cachehit_count;
+    u32 max_types;
+    u32 max_ssidrefs;
+    domaintype_t *ssidrefs;     /* [max_ssidrefs][max_types]  */
+    atomic_t ec_eval_count, gt_eval_count;
+    atomic_t ec_denied_count, gt_denied_count; 
+    atomic_t ec_cachehit_count, gt_cachehit_count;
 };
 
 /* global acm policy */
@@ -63,7 +64,7 @@
 
 /* defines number of access decisions to other domains can be cached
  * one entry per domain, TE does not distinguish evtchn or grant_table */
-#define ACM_TE_CACHE_SIZE      8
+#define ACM_TE_CACHE_SIZE 8
 enum acm_ste_flag { VALID, FREE };
 
 /* cache line:
@@ -72,57 +73,67 @@
  *                 on domain cache_line.id
  */
 struct acm_ste_cache_line {
-       enum acm_ste_flag valid;
-       domid_t id;
+    enum acm_ste_flag valid;
+    domid_t id;
 };
 
 /* general definition of a subject security id */
 struct acm_ssid_domain {
-       enum acm_datatype datatype;             /* type of subject (e.g., 
partition) */
-       ssidref_t         ssidref;              /* combined security reference 
*/
-       void              *primary_ssid;        /* primary policy ssid part 
(e.g. chinese wall) */
-       void              *secondary_ssid;      /* secondary policy ssid part 
(e.g. type enforcement) */
-       struct domain     *subject;             /* backpointer to subject 
structure */
-       domid_t           domainid;             /* replicate id */
+    enum acm_datatype datatype; /* type of subject (e.g., partition) */
+    ssidref_t ssidref;   /* combined security reference */
+    void *primary_ssid;   /* primary policy ssid part (e.g. chinese wall) */
+    void *secondary_ssid;    /* secondary policy ssid part (e.g. type 
enforcement) */
+    struct domain *subject;     /* backpointer to subject structure */
+    domid_t domainid;   /* replicate id */
 };
 
 /* chinese wall ssid type */
 struct chwall_ssid {
-       ssidref_t chwall_ssidref;
+    ssidref_t chwall_ssidref;
 };
 
 /* simple type enforcement ssid type */
 struct ste_ssid {
-       ssidref_t ste_ssidref;
-       struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision 
cache */
+    ssidref_t ste_ssidref;
+    struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache 
*/
 };
 
 /* macros to access ssidref for primary / secondary policy 
- *     primary ssidref   = lower 16 bit
- *      secondary ssidref = higher 16 bit
+ * primary ssidref   = lower 16 bit
+ *  secondary ssidref = higher 16 bit
  */
 #define ACM_PRIMARY(ssidref) \
-       ((ssidref) & 0xffff)
+ ((ssidref) & 0xffff)
 
 #define ACM_SECONDARY(ssidref) \
-       ((ssidref) >> 16)
+ ((ssidref) >> 16)
 
 #define GET_SSIDREF(POLICY, ssidref) \
-       ((POLICY) == acm_bin_pol.primary_policy_code) ? \
-       ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref)
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref)
 
 /* macros to access ssid pointer for primary / secondary policy */
 #define GET_SSIDP(POLICY, ssid) \
-       ((POLICY) == acm_bin_pol.primary_policy_code) ? \
-       ((ssid)->primary_ssid) : ((ssid)->secondary_ssid)
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ((ssid)->primary_ssid) : ((ssid)->secondary_ssid)
 
 /* protos */
 int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
-int acm_free_domain_ssid(struct acm_ssid_domain *ssid);
-int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer);
-int acm_get_policy(void *buf, u16 buf_size);
+void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
+int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer);
+int acm_get_policy(void *buf, u32 buf_size);
 int acm_dump_statistics(void *buf, u16 buf_size);
 int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
+int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, enum 
acm_hook_type hook);
 
 #endif
 
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/include/acm/acm_endian.h
--- a/xen/include/acm/acm_endian.h      Thu Oct 20 18:37:41 2005
+++ b/xen/include/acm/acm_endian.h      Thu Oct 20 20:37:15 2005
@@ -18,6 +18,7 @@
  * big-endian policy interface
  *
  */
+
 #ifndef _ACM_ENDIAN_H
 #define _ACM_ENDIAN_H
 
@@ -30,10 +31,10 @@
 {
     if (little_endian)
         return 
-           ( (((x) >> 24) & 0xff      )| 
-             (((x) >>  8) & 0xff00    )| 
-             (((x) <<  8) & 0xff0000  )|
-             (((x) << 24) & 0xff000000) );
+            ( (((x) >> 24) & 0xff      )| 
+              (((x) >>  8) & 0xff00    )| 
+              (((x) <<  8) & 0xff0000  )|
+              (((x) << 24) & 0xff000000) );
     else
         return x;
 }
@@ -42,10 +43,10 @@
 {
     if (little_endian)
         return 
-           ( (((x) >> 8) & 0xff   )|
-             (((x) << 8) & 0xff00 ) );
+            ( (((x) >> 8) & 0xff   )|
+              (((x) << 8) & 0xff00 ) );
     else
-       return x;
+        return x;
 }
 
 #define htonl(x) ntohl(x)
@@ -55,8 +56,8 @@
 {
     unsigned int i = 0;
     while (i < n) {
-               dest[i] = htons(src[i]);
-               i++;
+        dest[i] = htons(src[i]);
+        i++;
     }
 }
 
@@ -64,8 +65,8 @@
 {
     unsigned int i = 0;
     while (i < n) {
-       dest[i] = htonl(src[i]);
-       i++;
+        dest[i] = htonl(src[i]);
+        i++;
     }
 }
 
@@ -86,3 +87,13 @@
 }
 
 #endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h       Thu Oct 20 18:37:41 2005
+++ b/xen/include/acm/acm_hooks.h       Thu Oct 20 20:37:15 2005
@@ -15,6 +15,7 @@
  *      sHype hooks that are called throughout Xen.
  * 
  */
+
 #ifndef _ACM_HOOKS_H
 #define _ACM_HOOKS_H
 
@@ -89,8 +90,8 @@
     /* policy management functions (must always be defined!) */
     int  (*init_domain_ssid)           (void **ssid, ssidref_t ssidref);
     void (*free_domain_ssid)           (void *ssid);
-    int  (*dump_binary_policy)         (u8 *buffer, u16 buf_size);
-    int  (*set_binary_policy)          (u8 *buffer, u16 buf_size);
+    int  (*dump_binary_policy)         (u8 *buffer, u32 buf_size);
+    int  (*set_binary_policy)          (u8 *buffer, u32 buf_size);
     int  (*dump_statistics)            (u8 *buffer, u16 buf_size);
     int  (*dump_ssid_types)            (ssidref_t ssidref, u8 *buffer, u16 
buf_size);
     /* domain management control hooks (can be NULL) */
@@ -108,6 +109,8 @@
     void (*fail_grant_map_ref)         (domid_t id);
     int  (*pre_grant_setup)            (domid_t id);
     void (*fail_grant_setup)           (domid_t id);
+    /* generic domain-requested decision hooks (can be NULL) */
+    int (*sharing)                     (ssidref_t ssidref1, ssidref_t 
ssidref2);
 };
 
 /* global variables */
@@ -144,6 +147,8 @@
 { return 0; }
 static inline void acm_post_domain0_create(domid_t domid) 
 { return; }
+static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
+{ return 0; }
 
 #else
 
@@ -281,7 +286,8 @@
         break;
     case EVTCHNOP_bind_interdomain:
         ret = acm_pre_eventchannel_interdomain(
-            op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2);
+            current->domain->domain_id,
+            op->u.bind_interdomain.remote_dom);
         break;
     default:
         ret = 0; /* ok */
@@ -341,6 +347,18 @@
     acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
 }
 
+static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2)
+{
+    if ((acm_primary_ops->sharing != NULL) &&
+        acm_primary_ops->sharing(ssidref1, ssidref2))
+        return ACM_ACCESS_DENIED;
+    else if ((acm_secondary_ops->sharing != NULL) &&
+             acm_secondary_ops->sharing(ssidref1, ssidref2)) {
+        return ACM_ACCESS_DENIED;
+    } else
+        return ACM_ACCESS_PERMITTED;
+}
+
 extern int acm_init(unsigned int *initrdidx,
                     const multiboot_info_t *mbi,
                     unsigned long start);
@@ -348,3 +366,13 @@
 #endif
 
 #endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 6f5b94da963a -r 1e40bed176d4 xen/include/public/acm.h
--- a/xen/include/public/acm.h  Thu Oct 20 18:37:41 2005
+++ b/xen/include/public/acm.h  Thu Oct 20 20:37:15 2005
@@ -52,9 +52,9 @@
 #define ACM_ERROR          -4
 
 /* External ACCESS DECISIONS */
-#define ACM_ACCESS_PERMITTED  0
-#define ACM_ACCESS_DENIED  -111
-#define ACM_NULL_POINTER_ERROR  -200
+#define ACM_ACCESS_PERMITTED        0
+#define ACM_ACCESS_DENIED           -111
+#define ACM_NULL_POINTER_ERROR      -200
 
 /* primary policy in lower 4 bits */
 #define ACM_NULL_POLICY 0
@@ -83,6 +83,9 @@
 
 /* defines a ssid reference used by xen */
 typedef uint32_t ssidref_t;
+
+/* hooks that are known to domains */
+enum acm_hook_type {NONE=0, SHARING};
 
 /* -------security policy relevant type definitions-------- */
 
diff -r 6f5b94da963a -r 1e40bed176d4 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h      Thu Oct 20 18:37:41 2005
+++ b/xen/include/public/acm_ops.h      Thu Oct 20 20:37:15 2005
@@ -27,36 +27,36 @@
  * This makes sure that old versions of acm tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define ACM_INTERFACE_VERSION   0xAAAA0004
+#define ACM_INTERFACE_VERSION   0xAAAA0005
 
 /************************************************************************/
 
 #define ACM_SETPOLICY         4
-typedef struct acm_setpolicy {
+struct acm_setpolicy {
     /* OUT variables */
     void *pushcache;
-    uint16_t pushcache_size;
-} acm_setpolicy_t;
+    uint32_t pushcache_size;
+};
 
 
 #define ACM_GETPOLICY         5
-typedef struct acm_getpolicy {
+struct acm_getpolicy {
     /* OUT variables */
     void *pullcache;
-    uint16_t pullcache_size;
-} acm_getpolicy_t;
+    uint32_t pullcache_size;
+};
 
 
 #define ACM_DUMPSTATS         6
-typedef struct acm_dumpstats {
+struct acm_dumpstats {
     void *pullcache;
-    uint16_t pullcache_size;
-} acm_dumpstats_t;
+    uint32_t pullcache_size;
+};
 
 
 #define ACM_GETSSID           7
-enum get_type {UNSET, SSIDREF, DOMAINID};
-typedef struct acm_getssid {
+enum get_type {UNSET=0, SSIDREF, DOMAINID};
+struct acm_getssid {
     enum get_type get_ssid_by;
     union {
         domaintype_t domainid;
@@ -64,18 +64,35 @@
     } id;
     void *ssidbuf;
     uint16_t ssidbuf_size;
-} acm_getssid_t;
+};
 
-typedef struct acm_op {
+#define ACM_GETDECISION        8
+struct acm_getdecision {
+    enum get_type get_decision_by1; /* in */
+    enum get_type get_decision_by2;
+    union {
+        domaintype_t domainid;
+        ssidref_t    ssidref;
+    } id1;
+    union {
+        domaintype_t domainid;
+        ssidref_t    ssidref;
+    } id2;
+    enum acm_hook_type hook;
+    int acm_decision;           /* out */
+};
+
+struct acm_op {
     uint32_t cmd;
     uint32_t interface_version;      /* ACM_INTERFACE_VERSION */
     union {
-        acm_setpolicy_t setpolicy;
-        acm_getpolicy_t getpolicy;
-        acm_dumpstats_t dumpstats;
-        acm_getssid_t getssid;
+        struct acm_setpolicy setpolicy;
+        struct acm_getpolicy getpolicy;
+        struct acm_dumpstats dumpstats;
+        struct acm_getssid getssid;
+        struct acm_getdecision getdecision;
     } u;
-} acm_op_t;
+};
 
 #endif                          /* __XEN_PUBLIC_ACM_OPS_H__ */
 
diff -r 6f5b94da963a -r 1e40bed176d4 tools/security/get_decision.c
--- /dev/null   Thu Oct 20 18:37:41 2005
+++ b/tools/security/get_decision.c     Thu Oct 20 20:37:15 2005
@@ -0,0 +1,176 @@
+/****************************************************************
+ * get_decision.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * An example program that shows how to retrieve an access control
+ * decision from the hypervisor ACM based on the currently active policy.
+ *
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <xen/acm.h>
+#include <xen/acm_ops.h>
+#include <xen/linux/privcmd.h>
+
+#define PERROR(_m, _a...) \
+fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,  \
+                errno, strerror(errno))
+
+void usage(char *progname)
+{
+    printf("Use: %s \n", progname);
+    printf(" Test program illustrating the retrieval of\n");
+    printf(" access control decisions from xen. At this time,\n");
+    printf(" only sharing (STE) policy decisions are supported.\n");
+    printf(" parameter options:\n");
+    printf("\t -i domid -i domid\n");
+    printf("\t -i domid -s ssidref\n");
+    printf("\t -s ssidref -s ssidref\n\n");
+    exit(-1);
+}
+
+static inline int do_policycmd(int xc_handle, unsigned int cmd,
+                               unsigned long data)
+{
+    return ioctl(xc_handle, cmd, data);
+}
+
+static inline int do_xen_hypercall(int xc_handle,
+                                   privcmd_hypercall_t * hypercall)
+{
+    return do_policycmd(xc_handle,
+                        IOCTL_PRIVCMD_HYPERCALL,
+                        (unsigned long) hypercall);
+}
+
+static inline int do_acm_op(int xc_handle, struct acm_op *op)
+{
+    int ret = -1;
+    privcmd_hypercall_t hypercall;
+
+    op->interface_version = ACM_INTERFACE_VERSION;
+
+    hypercall.op = __HYPERVISOR_acm_op;
+    hypercall.arg[0] = (unsigned long) op;
+
+    if (mlock(op, sizeof(*op)) != 0) {
+        PERROR("Could not lock memory for Xen policy hypercall");
+        goto out1;
+    }
+
+    if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0) {
+        if (errno == EACCES)
+            fprintf(stderr, "ACM operation failed -- need to"
+                    " rebuild the user-space tool set?\n");
+        goto out2;
+    }
+
+  out2:(void) munlock(op, sizeof(*op));
+  out1:return ret;
+}
+
+
+/************************ get decision ******************************/
+
+/* this example uses two domain ids and retrieves the decision if these domains
+ * can share information (useful, i.e., to enforce policy onto network traffic 
in dom0
+ */
+int acm_get_decision(int xc_handle, int argc, char *const argv[])
+{
+    struct acm_op op;
+    int ret;
+
+    op.cmd = ACM_GETDECISION;
+    op.interface_version = ACM_INTERFACE_VERSION;
+    op.u.getdecision.get_decision_by1 = UNSET;
+    op.u.getdecision.get_decision_by2 = UNSET;
+    op.u.getdecision.hook = SHARING;
+
+    while (1) {
+        int c = getopt(argc, argv, "i:s:");
+        if (c == -1)
+            break;
+
+        if (c == 'i') {
+            if (op.u.getdecision.get_decision_by1 == UNSET) {
+                op.u.getdecision.get_decision_by1 = DOMAINID;
+                op.u.getdecision.id1.domainid = strtoul(optarg, NULL, 0);
+            } else if (op.u.getdecision.get_decision_by2 == UNSET) {
+                op.u.getdecision.get_decision_by2 = DOMAINID;
+                op.u.getdecision.id2.domainid = strtoul(optarg, NULL, 0);
+            } else
+                usage(argv[0]);
+        } else if (c == 's') {
+            if (op.u.getdecision.get_decision_by1 == UNSET) {
+                op.u.getdecision.get_decision_by1 = SSIDREF;
+                op.u.getdecision.id1.ssidref = strtoul(optarg, NULL, 0);
+            } else if (op.u.getdecision.get_decision_by2 == UNSET) {
+                op.u.getdecision.get_decision_by2 = SSIDREF;
+                op.u.getdecision.id2.ssidref = strtoul(optarg, NULL, 0);
+            } else
+                usage(argv[0]);
+        } else
+            usage(argv[0]);
+    }
+    if ((op.u.getdecision.get_decision_by1 == UNSET) ||
+        (op.u.getdecision.get_decision_by2 == UNSET))
+        usage(argv[0]);
+
+    if ((ret = do_acm_op(xc_handle, &op))) {
+        printf("%s: Error getting decision (%d).\n", __func__, ret);
+        printf("%s: decision = %s.\n", __func__,
+               (op.u.getdecision.acm_decision ==
+                ACM_ACCESS_PERMITTED) ? "PERMITTED" : ((op.u.getdecision.
+                                                        acm_decision ==
+                                                        ACM_ACCESS_DENIED)
+                                                       ? "DENIED" :
+                                                       "ERROR"));
+        return ret;
+    }
+    return op.u.getdecision.acm_decision;
+}
+
+/***************************** main **************************************/
+
+int main(int argc, char **argv)
+{
+
+    int acm_cmd_fd, ret = 0;
+
+    if (argc < 5)
+        usage(argv[0]);
+
+    if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
+        printf("ERROR: Could not open xen privcmd device!\n");
+        exit(-1);
+    }
+
+    ret = acm_get_decision(acm_cmd_fd, argc, argv);
+
+    printf("Decision: %s (%d)\n",
+           (ret == ACM_ACCESS_PERMITTED) ? "PERMITTED" :
+           ((ret == ACM_ACCESS_DENIED) ? "DENIED" : "ERROR"), ret);
+
+    close(acm_cmd_fd);
+    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] This patch to the Xen access control module (ACM) and tools:, Xen patchbot -unstable <=