# 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
|