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

[Xen-changelog] Remainder of ACM patch (hgrrrr).



# HG changeset patch
# User smh22@xxxxxxxxxxxxxxxxxxxx
# Node ID 433402c64c772f62501cac118ad173b25629f9c5
# Parent  d18f732c0a5fa2b4a14c52c511c3b6db8cb950bb
Remainder of ACM patch (hgrrrr). 

Signed-off-by: Reiner Sailer <sailer@xxxxxxxxxxxxxx>
Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>

diff -r d18f732c0a5f -r 433402c64c77 tools/misc/policyprocessor/Makefile
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/tools/misc/policyprocessor/Makefile       Tue Aug  2 10:15:17 2005
@@ -0,0 +1,42 @@
+XEN_ROOT = ../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+CFLAGS   += -static
+CFLAGS   += -Wall
+CFLAGS   += -Werror
+CFLAGS   += -O3
+CFLAGS   += -fno-strict-aliasing
+CFLAGS   += -I.
+
+all: build
+
+build: mk-symlinks
+       $(MAKE) xml_to_bin
+
+default: all
+
+install: all
+
+xml_to_bin : make_include XmlToBin.java XmlToBinInterface.java SsidsEntry.java 
SecurityLabel.java myHandler.java
+       javac XmlToBin.java
+
+make_include : c2j_include
+       ./c2j_include
+
+c2j_include: c2j_include.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+clean:
+       rm -rf *.class xen c2j_include policy_version.java *.bin
+
+
+LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
+mk-symlinks:
+       [ -e xen/linux ] || mkdir -p xen/linux
+       [ -e xen/io ]    || mkdir -p xen/io
+       ( cd xen >/dev/null ; \
+         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
+       ( cd xen/io >/dev/null ; \
+         ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+       ( cd xen/linux >/dev/null ; \
+         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -r d18f732c0a5f -r 433402c64c77 tools/misc/policyprocessor/c2j_include.c
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/tools/misc/policyprocessor/c2j_include.c  Tue Aug  2 10:15:17 2005
@@ -0,0 +1,57 @@
+/****************************************************************
+ * c2j_include.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.
+ *
+ * This tool makes some constants from acm.h available to the
+ * java policyprocessor for version checking.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef uint8_t  u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t   s8;
+typedef int16_t  s16;
+typedef int32_t  s32;
+typedef int64_t  s64;
+
+#include <xen/acm.h>
+
+char *filename = "policy_version.java";
+
+int main(int argc, char **argv)
+{
+
+    FILE *fd;
+    if ((fd = fopen(filename, "w")) <= 0)
+    {
+        printf("File %s not found.\n", filename);
+        exit(-ENOENT);
+    }
+
+    fprintf(fd, "/*\n * This file was automatically generated\n");
+    fprintf(fd, " * Do not change it manually!\n */\n");
+    fprintf(fd, "public class policy_version {\n");
+    fprintf(fd, "      final int ACM_POLICY_VERSION = %x;\n",
+            ACM_POLICY_VERSION);
+    fprintf(fd, "      final int ACM_CHWALL_VERSION = %x;\n",
+            ACM_CHWALL_VERSION);
+    fprintf(fd, "      final int ACM_STE_VERSION = %x;\n",
+            ACM_STE_VERSION);
+    fprintf(fd, "}\n");
+    fclose(fd);
+    return 0;
+}
diff -r d18f732c0a5f -r 433402c64c77 tools/security/Makefile
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/tools/security/Makefile   Tue Aug  2 10:15:17 2005
@@ -0,0 +1,36 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+SRCS     = secpol_tool.c
+CFLAGS   += -static
+CFLAGS   += -Wall
+CFLAGS   += -Werror
+CFLAGS   += -O3
+CFLAGS   += -fno-strict-aliasing
+CFLAGS   += -I.
+
+all: build
+build: mk-symlinks
+       $(MAKE) secpol_tool
+
+default: all
+
+install: all
+
+secpol_tool : secpol_tool.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+clean:
+       rm -rf secpol_tool xen
+
+
+LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
+mk-symlinks:
+       [ -e xen/linux ] || mkdir -p xen/linux
+       [ -e xen/io ]    || mkdir -p xen/io
+       ( cd xen >/dev/null ; \
+         ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
+       ( cd xen/io >/dev/null ; \
+         ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+       ( cd xen/linux >/dev/null ; \
+         ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -r d18f732c0a5f -r 433402c64c77 tools/security/secpol_tool.c
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/tools/security/secpol_tool.c      Tue Aug  2 10:15:17 2005
@@ -0,0 +1,648 @@
+/****************************************************************
+ * secpol_tool.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
+ * Stefan Berger <stefanb@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.
+ *
+ * sHype policy management tool. This code runs in a domain and
+ *     manages the Xen security policy by interacting with the
+ *     Xen access control module via a /proc/xen/privcmd proc-ioctl,
+ *     which is translated into a acm_op hypercall into Xen.
+ *
+ * indent -i4 -kr -nut
+ */
+
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdint.h>
+#include <netinet/in.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+#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))
+
+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, acm_op_t * 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;
+}
+
+/*************************** DUMPS *******************************/
+
+void acm_dump_chinesewall_buffer(void *buf, int buflen)
+{
+
+    struct acm_chwall_policy_buffer *cwbuf =
+        (struct acm_chwall_policy_buffer *) buf;
+    domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
+    int i, j;
+
+
+    if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY)
+    {
+        printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
+        return;
+    }
+    printf("\n\nChinese Wall policy:\n");
+    printf("====================\n");
+    printf("Policy version= %x.\n", ntohl(cwbuf->policy_version));
+    printf("Max Types     = %x.\n", ntohl(cwbuf->chwall_max_types));
+    printf("Max Ssidrefs  = %x.\n", ntohl(cwbuf->chwall_max_ssidrefs));
+    printf("Max ConfSets  = %x.\n", ntohl(cwbuf->chwall_max_conflictsets));
+    printf("Ssidrefs Off  = %x.\n", ntohl(cwbuf->chwall_ssid_offset));
+    printf("Conflicts Off = %x.\n",
+           ntohl(cwbuf->chwall_conflict_sets_offset));
+    printf("Runing T. Off = %x.\n",
+           ntohl(cwbuf->chwall_running_types_offset));
+    printf("C. Agg. Off   = %x.\n",
+           ntohl(cwbuf->chwall_conflict_aggregate_offset));
+    printf("\nSSID To CHWALL-Type matrix:\n");
+
+    ssids = (domaintype_t *) (buf + ntohl(cwbuf->chwall_ssid_offset));
+    for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++)
+    {
+        printf("\n   ssidref%2x:  ", i);
+        for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
+            printf("%02x ",
+                   ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
+    }
+    printf("\n\nConfict Sets:\n");
+    conflicts =
+        (domaintype_t *) (buf + ntohl(cwbuf->chwall_conflict_sets_offset));
+    for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++)
+    {
+        printf("\n   c-set%2x:    ", i);
+        for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
+            printf("%02x ",
+                   ntohs(conflicts
+                         [i * ntohl(cwbuf->chwall_max_types) + j]));
+    }
+    printf("\n");
+
+    printf("\nRunning\nTypes:         ");
+    if (ntohl(cwbuf->chwall_running_types_offset))
+    {
+        running_types =
+            (domaintype_t *) (buf +
+                              ntohl(cwbuf->chwall_running_types_offset));
+        for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
+        {
+            printf("%02x ", ntohs(running_types[i]));
+        }
+        printf("\n");
+    } else {
+        printf("Not Reported!\n");
+    }
+    printf("\nConflict\nAggregate Set: ");
+    if (ntohl(cwbuf->chwall_conflict_aggregate_offset))
+    {
+        conflict_aggregate =
+            (domaintype_t *) (buf +
+                              ntohl(cwbuf->chwall_conflict_aggregate_offset));
+        for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
+        {
+            printf("%02x ", ntohs(conflict_aggregate[i]));
+        }
+        printf("\n\n");
+    } else {
+        printf("Not Reported!\n");
+    }
+}
+
+void acm_dump_ste_buffer(void *buf, int buflen)
+{
+
+    struct acm_ste_policy_buffer *stebuf =
+        (struct acm_ste_policy_buffer *) buf;
+    domaintype_t *ssids;
+    int i, j;
+
+
+    if (ntohl(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+        printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
+        return;
+    }
+    printf("\nSimple Type Enforcement policy:\n");
+    printf("===============================\n");
+    printf("Policy version= %x.\n", ntohl(stebuf->policy_version));
+    printf("Max Types     = %x.\n", ntohl(stebuf->ste_max_types));
+    printf("Max Ssidrefs  = %x.\n", ntohl(stebuf->ste_max_ssidrefs));
+    printf("Ssidrefs Off  = %x.\n", ntohl(stebuf->ste_ssid_offset));
+    printf("\nSSID To STE-Type matrix:\n");
+
+    ssids = (domaintype_t *) (buf + ntohl(stebuf->ste_ssid_offset));
+    for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++)
+    {
+        printf("\n   ssidref%2x: ", i);
+        for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
+            printf("%02x ", ntohs(ssids[i * ntohl(stebuf->ste_max_types) + 
j]));
+    }
+    printf("\n\n");
+}
+
+void acm_dump_policy_buffer(void *buf, int buflen)
+{
+    struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
+
+    printf("\nPolicy dump:\n");
+    printf("============\n");
+    printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
+    printf("Magic     = %x.\n", ntohl(pol->magic));
+    printf("Len       = %x.\n", ntohl(pol->len));
+    printf("Primary   = %s (c=%x, off=%x).\n",
+           ACM_POLICY_NAME(ntohl(pol->primary_policy_code)),
+           ntohl(pol->primary_policy_code),
+           ntohl(pol->primary_buffer_offset));
+    printf("Secondary = %s (c=%x, off=%x).\n",
+           ACM_POLICY_NAME(ntohl(pol->secondary_policy_code)),
+           ntohl(pol->secondary_policy_code),
+           ntohl(pol->secondary_buffer_offset));
+    switch (ntohl(pol->primary_policy_code))
+    {
+    case ACM_CHINESE_WALL_POLICY:
+        acm_dump_chinesewall_buffer(buf +
+                                    ntohl(pol->primary_buffer_offset),
+                                    ntohl(pol->len) -
+                                    ntohl(pol->primary_buffer_offset));
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        acm_dump_ste_buffer(buf + ntohl(pol->primary_buffer_offset),
+                            ntohl(pol->len) -
+                            ntohl(pol->primary_buffer_offset));
+        break;
+
+    case ACM_NULL_POLICY:
+        printf("Primary policy is NULL Policy (n/a).\n");
+        break;
+
+    default:
+        printf("UNKNOWN POLICY!\n");
+    }
+
+    switch (ntohl(pol->secondary_policy_code))
+    {
+    case ACM_CHINESE_WALL_POLICY:
+        acm_dump_chinesewall_buffer(buf +
+                                    ntohl(pol->secondary_buffer_offset),
+                                    ntohl(pol->len) -
+                                    ntohl(pol->secondary_buffer_offset));
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        acm_dump_ste_buffer(buf + ntohl(pol->secondary_buffer_offset),
+                            ntohl(pol->len) -
+                            ntohl(pol->secondary_buffer_offset));
+        break;
+
+    case ACM_NULL_POLICY:
+        printf("Secondary policy is NULL Policy (n/a).\n");
+        break;
+
+    default:
+        printf("UNKNOWN POLICY!\n");
+    }
+}
+
+/*************************** set policy ****************************/
+
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen)
+{
+#define CWALL_MAX_SSIDREFS             6
+#define CWALL_MAX_TYPES             10
+#define CWALL_MAX_CONFLICTSETS         2
+
+    struct acm_chwall_policy_buffer *chwall_bin_pol =
+        (struct acm_chwall_policy_buffer *) bufstart;
+    domaintype_t *ssidrefs, *conflicts;
+    int ret = 0;
+    int j;
+
+    chwall_bin_pol->chwall_max_types = htonl(CWALL_MAX_TYPES);
+    chwall_bin_pol->chwall_max_ssidrefs = htonl(CWALL_MAX_SSIDREFS);
+    chwall_bin_pol->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+    chwall_bin_pol->policy_version = htonl(ACM_CHWALL_VERSION);
+    chwall_bin_pol->chwall_ssid_offset =
+        htonl(sizeof(struct acm_chwall_policy_buffer));
+    chwall_bin_pol->chwall_max_conflictsets =
+        htonl(CWALL_MAX_CONFLICTSETS);
+    chwall_bin_pol->chwall_conflict_sets_offset =
+        htonl(ntohl(chwall_bin_pol->chwall_ssid_offset) +
+              sizeof(domaintype_t) * CWALL_MAX_SSIDREFS * CWALL_MAX_TYPES);
+    chwall_bin_pol->chwall_running_types_offset = 0;    /* not set */
+    chwall_bin_pol->chwall_conflict_aggregate_offset = 0;       /* not set */
+    ret += sizeof(struct acm_chwall_policy_buffer);
+    /* now push example ssids into the buffer (max_ssidrefs x max_types 
entries) */
+    /* check buffer size */
+    if ((buflen - ret) <
+        (CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t)))
+        return -1;              /* not enough space */
+
+    ssidrefs = (domaintype_t *) (bufstart +
+                          ntohl(chwall_bin_pol->chwall_ssid_offset));
+    memset(ssidrefs, 0,
+           CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t));
+
+    /* now set type j-1 for ssidref i+1 */
+    for (j = 0; j <= CWALL_MAX_SSIDREFS; j++)
+        if ((0 < j) && (j <= CWALL_MAX_TYPES))
+            ssidrefs[j * CWALL_MAX_TYPES + j - 1] = htons(1);
+
+    ret += CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t);
+    if ((buflen - ret) <
+        (CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * sizeof(domaintype_t)))
+        return -1;              /* not enough space */
+
+    /* now the chinese wall policy conflict sets */
+    conflicts = (domaintype_t *) (bufstart +
+                                  ntohl(chwall_bin_pol->
+                                        chwall_conflict_sets_offset));
+    memset((void *) conflicts, 0,
+           CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES *
+           sizeof(domaintype_t));
+    /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */
+    if (CWALL_MAX_TYPES > 3)
+    {
+        conflicts[2] = htons(1);
+        conflicts[3] = htons(1);        /* {2,3} */
+        conflicts[CWALL_MAX_TYPES + 1] = htons(1);
+        conflicts[CWALL_MAX_TYPES + 5] = htons(1);
+        conflicts[CWALL_MAX_TYPES + 6] = htons(1);      /* {0,5,6} */
+    }
+    ret += sizeof(domaintype_t) * CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES;
+    return ret;
+}
+
+int acm_domain_set_stepolicy(void *bufstart, int buflen)
+{
+#define STE_MAX_SSIDREFS        6
+#define STE_MAX_TYPES                  5
+
+    struct acm_ste_policy_buffer *ste_bin_pol =
+        (struct acm_ste_policy_buffer *) bufstart;
+    domaintype_t *ssidrefs;
+    int j, ret = 0;
+
+    ste_bin_pol->ste_max_types = htonl(STE_MAX_TYPES);
+    ste_bin_pol->ste_max_ssidrefs = htonl(STE_MAX_SSIDREFS);
+    ste_bin_pol->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+    ste_bin_pol->policy_version = htonl(ACM_STE_VERSION);
+    ste_bin_pol->ste_ssid_offset =
+        htonl(sizeof(struct acm_ste_policy_buffer));
+    ret += sizeof(struct acm_ste_policy_buffer);
+    /* check buffer size */
+    if ((buflen - ret) <
+        (STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t)))
+        return -1;              /* not enough space */
+
+    ssidrefs =
+        (domaintype_t *) (bufstart + ntohl(ste_bin_pol->ste_ssid_offset));
+    memset(ssidrefs, 0,
+           STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t));
+    /* all types 1 for ssidref 1 */
+    for (j = 0; j < STE_MAX_TYPES; j++)
+        ssidrefs[1 * STE_MAX_TYPES + j] = htons(1);
+    /* now set type j-1 for ssidref j */
+    for (j = 0; j < STE_MAX_SSIDREFS; j++)
+        if ((0 < j) && (j <= STE_MAX_TYPES))
+            ssidrefs[j * STE_MAX_TYPES + j - 1] = htons(1);
+    ret += STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t);
+    return ret;
+}
+
+#define MAX_PUSH_BUFFER        16384
+u8 push_buffer[MAX_PUSH_BUFFER];
+
+int acm_domain_setpolicy(int xc_handle)
+{
+    int ret;
+    struct acm_policy_buffer *bin_pol;
+    acm_op_t op;
+
+    /* future: read policy from file and set it */
+    bin_pol = (struct acm_policy_buffer *) push_buffer;
+    bin_pol->policy_version = htonl(ACM_POLICY_VERSION);
+    bin_pol->magic = htonl(ACM_MAGIC);
+    bin_pol->primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
+    bin_pol->secondary_policy_code =
+        htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+
+    bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
+    bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
+    ret =
+        acm_domain_set_chwallpolicy(push_buffer +
+                                    ntohl(bin_pol->primary_buffer_offset),
+                                    MAX_PUSH_BUFFER -
+                                    ntohl(bin_pol->primary_buffer_offset));
+    if (ret < 0)
+    {
+        printf("ERROR creating chwallpolicy buffer.\n");
+        return -1;
+    }
+    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+    bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
+    ret = acm_domain_set_stepolicy(push_buffer +
+                                 ntohl(bin_pol->secondary_buffer_offset),
+                                 MAX_PUSH_BUFFER -
+                                 ntohl(bin_pol->secondary_buffer_offset));
+    if (ret < 0)
+    {
+        printf("ERROR creating chwallpolicy buffer.\n");
+        return -1;
+    }
+    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+
+    /* dump it and then push it down into xen/acm */
+    acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
+
+    op.cmd = ACM_SETPOLICY;
+    op.interface_version = ACM_INTERFACE_VERSION;
+    op.u.setpolicy.pushcache = (void *) push_buffer;
+    op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
+    ret = do_acm_op(xc_handle, &op);
+
+    if (ret)
+        printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+    else
+        printf("Successfully changed policy.\n");
+
+    return ret;
+}
+
+/******************************* get policy ******************************/
+
+#define PULL_CACHE_SIZE                8192
+u8 pull_buffer[PULL_CACHE_SIZE];
+int acm_domain_getpolicy(int xc_handle)
+{
+    acm_op_t op;
+    int ret;
+
+    memset(pull_buffer, 0x00, sizeof(pull_buffer));
+    op.cmd = ACM_GETPOLICY;
+    op.interface_version = ACM_INTERFACE_VERSION;
+    op.u.getpolicy.pullcache = (void *) pull_buffer;
+    op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
+    ret = do_acm_op(xc_handle, &op);
+    /* dump policy  */
+    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+    return ret;
+}
+
+/************************ load binary policy ******************************/
+
+int acm_domain_loadpolicy(int xc_handle, const char *filename)
+{
+    struct stat mystat;
+    int ret, fd;
+    off_t len;
+    u8 *buffer;
+
+    if ((ret = stat(filename, &mystat)))
+    {
+        printf("File %s not found.\n", filename);
+        goto out;
+    }
+
+    len = mystat.st_size;
+    if ((buffer = malloc(len)) == NULL)
+    {
+        ret = -ENOMEM;
+        goto out;
+    }
+    if ((fd = open(filename, O_RDONLY)) <= 0)
+    {
+        ret = -ENOENT;
+        printf("File %s not found.\n", filename);
+        goto free_out;
+    }
+    if (len == read(fd, buffer, len))
+    {
+        acm_op_t op;
+        /* dump it and then push it down into xen/acm */
+        acm_dump_policy_buffer(buffer, len);
+        op.cmd = ACM_SETPOLICY;
+        op.interface_version = ACM_INTERFACE_VERSION;
+        op.u.setpolicy.pushcache = (void *) buffer;
+        op.u.setpolicy.pushcache_size = len;
+        ret = do_acm_op(xc_handle, &op);
+
+        if (ret)
+            printf
+                ("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+        else
+            printf("Successfully changed policy.\n");
+
+    } else {
+        ret = -1;
+    }
+    close(fd);
+  free_out:
+    free(buffer);
+  out:
+    return ret;
+}
+
+/************************ dump hook statistics ******************************/
+void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
+{
+    printf("STE-Policy Security Hook Statistics:\n");
+    printf("ste: event_channel eval_count      = %d\n",
+           ntohl(ste_stats->ec_eval_count));
+    printf("ste: event_channel denied_count    = %d\n",
+           ntohl(ste_stats->ec_denied_count));
+    printf("ste: event_channel cache_hit_count = %d\n",
+           ntohl(ste_stats->ec_cachehit_count));
+    printf("ste:\n");
+    printf("ste: grant_table   eval_count      = %d\n",
+           ntohl(ste_stats->gt_eval_count));
+    printf("ste: grant_table   denied_count    = %d\n",
+           ntohl(ste_stats->gt_denied_count));
+    printf("ste: grant_table   cache_hit_count = %d\n",
+           ntohl(ste_stats->gt_cachehit_count));
+}
+
+#define PULL_STATS_SIZE                8192
+int acm_domain_dumpstats(int xc_handle)
+{
+    u8 stats_buffer[PULL_STATS_SIZE];
+    acm_op_t op;
+    int ret;
+    struct acm_stats_buffer *stats;
+
+    memset(stats_buffer, 0x00, sizeof(stats_buffer));
+    op.cmd = ACM_DUMPSTATS;
+    op.interface_version = ACM_INTERFACE_VERSION;
+    op.u.dumpstats.pullcache = (void *) stats_buffer;
+    op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
+    ret = do_acm_op(xc_handle, &op);
+
+    if (ret < 0)
+    {
+        printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
+        return ret;
+    }
+    stats = (struct acm_stats_buffer *) stats_buffer;
+
+    printf("\nPolicy dump:\n");
+    printf("============\n");
+    printf("Magic     = %x.\n", ntohl(stats->magic));
+    printf("Len       = %x.\n", ntohl(stats->len));
+
+    switch (ntohl(stats->primary_policy_code))
+    {
+    case ACM_NULL_POLICY:
+        printf("NULL Policy: No statistics apply.\n");
+        break;
+
+    case ACM_CHINESE_WALL_POLICY:
+        printf("Chinese Wall Policy: No statistics apply.\n");
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
+                                                        ntohl(stats->
+                                                              
primary_stats_offset)));
+        break;
+
+    default:
+        printf("UNKNOWN PRIMARY POLICY ERROR!\n");
+    }
+
+    switch (ntohl(stats->secondary_policy_code))
+    {
+    case ACM_NULL_POLICY:
+        printf("NULL Policy: No statistics apply.\n");
+        break;
+
+    case ACM_CHINESE_WALL_POLICY:
+        printf("Chinese Wall Policy: No statistics apply.\n");
+        break;
+
+    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+        dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
+                                                        ntohl(stats->
+                                                              
secondary_stats_offset)));
+        break;
+
+    default:
+        printf("UNKNOWN SECONDARY POLICY ERROR!\n");
+    }
+    return ret;
+}
+
+/***************************** main **************************************/
+
+void usage(char *progname)
+{
+    printf("Use: %s \n"
+           "\t setpolicy\n"
+           "\t getpolicy\n"
+           "\t dumpstats\n"
+           "\t loadpolicy <binary policy file>\n", progname);
+    exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+
+    int acm_cmd_fd, ret;
+
+    if (argc < 2)
+        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);
+    }
+
+    if (!strcmp(argv[1], "setpolicy"))
+    {
+        if (argc != 2)
+            usage(argv[0]);
+        ret = acm_domain_setpolicy(acm_cmd_fd);
+    } else if (!strcmp(argv[1], "getpolicy")) {
+        if (argc != 2)
+            usage(argv[0]);
+        ret = acm_domain_getpolicy(acm_cmd_fd);
+    } else if (!strcmp(argv[1], "loadpolicy")) {
+        if (argc != 3)
+            usage(argv[0]);
+        ret = acm_domain_loadpolicy(acm_cmd_fd, argv[2]);
+    } else if (!strcmp(argv[1], "dumpstats")) {
+        if (argc != 2)
+            usage(argv[0]);
+        ret = acm_domain_dumpstats(acm_cmd_fd);
+    } else
+        usage(argv[0]);
+
+    close(acm_cmd_fd);
+    return ret;
+}
diff -r d18f732c0a5f -r 433402c64c77 xen/common/acm_ops.c
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/xen/common/acm_ops.c      Tue Aug  2 10:15:17 2005
@@ -0,0 +1,127 @@
+/******************************************************************************
+ * acm_ops.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * 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.
+ *
+ * Process acm command requests from guest OS.
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <public/acm_ops.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <xen/trace.h>
+#include <xen/console.h>
+#include <asm/shadow.h>
+#include <public/sched_ctl.h>
+#include <acm/acm_hooks.h>
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+
+long do_acm_op(acm_op_t * u_acm_op)
+{
+    return -ENOSYS;
+}
+
+#else
+
+typedef enum acm_operation {
+    POLICY,                     /* access to policy interface (early drop) */
+    GETPOLICY,                  /* dump policy cache */
+    SETPOLICY,                  /* set policy cache (controls security) */
+    DUMPSTATS                   /* dump policy statistics */
+} acm_operation_t;
+
+int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops)
+{
+    /* all policy management functions are restricted to privileged domains,
+     * soon we will introduce finer-grained privileges for policy operations
+     */
+    if (!IS_PRIV(d))
+    {
+        printk("%s: ACM management authorization denied ERROR!\n", __func__);
+        return ACM_ACCESS_DENIED;
+    }
+    return ACM_ACCESS_PERMITTED;
+}
+
+long do_acm_op(acm_op_t * u_acm_op)
+{
+    long ret = 0;
+    acm_op_t curop, *op = &curop;
+
+    /* check here policy decision for policy commands */
+    /* for now allow DOM0 only, later indepedently    */
+    if (acm_authorize_acm_ops(current->domain, POLICY))
+        return -EACCES;
+
+    if (copy_from_user(op, u_acm_op, sizeof(*op)))
+        return -EFAULT;
+
+    if (op->interface_version != ACM_INTERFACE_VERSION)
+        return -EACCES;
+
+    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;
+
+    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;
+
+    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;
+
+    default:
+        ret = -ESRCH;
+
+    }
+    return ret;
+}
+
+#endif
diff -r d18f732c0a5f -r 433402c64c77 xen/include/public/acm_ops.h
--- /dev/null   Tue Aug  2 09:37:00 2005
+++ b/xen/include/public/acm_ops.h      Tue Aug  2 10:15:17 2005
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * acm_ops.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * 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.
+ *
+ * Process acm policy command requests from guest OS.
+ * access checked by policy; not restricted to DOM0
+ *
+ */
+
+#ifndef __XEN_PUBLIC_ACM_OPS_H__
+#define __XEN_PUBLIC_ACM_OPS_H__
+
+#include "xen.h"
+#include "sched_ctl.h"
+
+/*
+ * Make sure you increment the interface version whenever you modify this file!
+ * 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   0xAAAA0003
+
+/************************************************************************/
+
+#define ACM_SETPOLICY          4
+typedef struct acm_setpolicy {
+    /* OUT variables */
+    void *pushcache;
+    u16 pushcache_size;
+} acm_setpolicy_t;
+
+
+#define ACM_GETPOLICY          5
+typedef struct acm_getpolicy {
+    /* OUT variables */
+    void *pullcache;
+    u16 pullcache_size;
+} acm_getpolicy_t;
+
+#define ACM_DUMPSTATS          6
+typedef struct acm_dumpstats {
+    void *pullcache;
+    u16 pullcache_size;
+} acm_dumpstats_t;
+
+
+typedef struct acm_op {
+    u32 cmd;
+    u32 interface_version;      /* ACM_INTERFACE_VERSION */
+    union {
+        acm_setpolicy_t setpolicy;
+        acm_getpolicy_t getpolicy;
+        acm_dumpstats_t dumpstats;
+    } u;
+} acm_op_t;
+
+#endif                          /* __XEN_PUBLIC_ACM_OPS_H__ */

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


 


Rackspace

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