aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorsmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>2005-06-20 22:28:08 +0000
committersmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>2005-06-20 22:28:08 +0000
commit80070b4a6ca1205c8bc00926fa23c997797f053c (patch)
tree0b9e314460f38c8989c228e5344a570f187e148a /tools
parent6b76d296bbfad35e3cea2f6073820e1dc9d8a8e7 (diff)
downloadxen-80070b4a6ca1205c8bc00926fa23c997797f053c.tar.gz
xen-80070b4a6ca1205c8bc00926fa23c997797f053c.tar.bz2
xen-80070b4a6ca1205c8bc00926fa23c997797f053c.zip
bitkeeper revision 1.1718.1.7 (42b742f8NxTuN2pqCHFAWI78dbEYKw)
Initial MAC (sHype) support from IBM. Defaults to NULL policy for now. Signed-off-by: Reiner Sailer <sailer@us.ibm.com> Signed-off-by: Stefan Berger <stefanb@us.ibm.com> Signed-off-by: Steven Hand <steven@xensource.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile1
-rw-r--r--tools/libxc/xc.h2
-rw-r--r--tools/libxc/xc_domain.c3
-rw-r--r--tools/policy/Makefile36
-rw-r--r--tools/policy/policy_tool.c557
-rw-r--r--tools/python/xen/lowlevel/xc/xc.c10
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py16
-rw-r--r--tools/python/xen/xend/image.py6
-rw-r--r--tools/python/xen/xend/server/SrvDomainDir.py1
-rw-r--r--tools/python/xen/xm/create.py7
-rw-r--r--tools/python/xen/xm/main.py10
-rw-r--r--tools/python/xen/xm/opts.py7
12 files changed, 641 insertions, 15 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 3a38e899de..00eb4991cc 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,6 +12,7 @@ SUBDIRS += xcs
SUBDIRS += xcutils
SUBDIRS += pygrub
SUBDIRS += firmware
+SUBDIRS += policy
.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h
index 27e7845798..e54f9b198d 100644
--- a/tools/libxc/xc.h
+++ b/tools/libxc/xc.h
@@ -110,6 +110,7 @@ int xc_waitdomain_core(int domain,
typedef struct {
u32 domid;
+ u32 ssidref;
unsigned int dying:1, crashed:1, shutdown:1,
paused:1, blocked:1, running:1;
unsigned int shutdown_reason; /* only meaningful if shutdown==1 */
@@ -124,6 +125,7 @@ typedef struct {
typedef dom0_getdomaininfo_t xc_domaininfo_t;
int xc_domain_create(int xc_handle,
+ u32 ssidref,
u32 *pdomid);
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 8f0bba3216..2edf11c39d 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -9,6 +9,7 @@
#include "xc_private.h"
int xc_domain_create(int xc_handle,
+ u32 ssidref,
u32 *pdomid)
{
int err;
@@ -16,6 +17,7 @@ int xc_domain_create(int xc_handle,
op.cmd = DOM0_CREATEDOMAIN;
op.u.createdomain.domain = (domid_t)*pdomid;
+ op.u.createdomain.ssidref = ssidref;
if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
return err;
@@ -101,6 +103,7 @@ int xc_domain_getinfo(int xc_handle,
info->crashed = 1;
}
+ info->ssidref = op.u.getdomaininfo.ssidref;
info->nr_pages = op.u.getdomaininfo.tot_pages;
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
diff --git a/tools/policy/Makefile b/tools/policy/Makefile
new file mode 100644
index 0000000000..b8d67471ae
--- /dev/null
+++ b/tools/policy/Makefile
@@ -0,0 +1,36 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+SRCS = policy_tool.c
+CFLAGS += -static
+CFLAGS += -Wall
+CFLAGS += -Werror
+CFLAGS += -O3
+CFLAGS += -fno-strict-aliasing
+CFLAGS += -I.
+
+all: build
+build: mk-symlinks
+ $(MAKE) policy_tool
+
+default: all
+
+install: all
+
+policy_tool : policy_tool.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+clean:
+ rm -rf policy_tool xen
+
+
+LINUX_ROOT := $(wildcard $(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 --git a/tools/policy/policy_tool.c b/tools/policy/policy_tool.c
new file mode 100644
index 0000000000..696a70c282
--- /dev/null
+++ b/tools/policy/policy_tool.c
@@ -0,0 +1,557 @@
+/****************************************************************
+ * policy_tool.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
+ * 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/policycmd proc-ioctl,
+ * which is translated into a policy_op hypercall into Xen.
+ *
+ * todo: implement setpolicy to dynamically set a policy cache.
+ */
+#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/policy_ops.h>
+
+#include <xen/linux/privcmd.h>
+
+#define ERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m "\n" , ## _a )
+
+#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_policy_op(int xc_handle, policy_op_t *op)
+{
+ int ret = -1;
+ privcmd_hypercall_t hypercall;
+
+ op->interface_version = POLICY_INTERFACE_VERSION;
+
+ hypercall.op = __HYPERVISOR_policy_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, "POLICY 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 (htons(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("Max Types = %x.\n", ntohs(cwbuf->chwall_max_types));
+ printf("Max Ssidrefs = %x.\n", ntohs(cwbuf->chwall_max_ssidrefs));
+ printf("Max ConfSets = %x.\n", ntohs(cwbuf->chwall_max_conflictsets));
+ printf("Ssidrefs Off = %x.\n", ntohs(cwbuf->chwall_ssid_offset));
+ printf("Conflicts Off = %x.\n", ntohs(cwbuf->chwall_conflict_sets_offset));
+ printf("Runing T. Off = %x.\n", ntohs(cwbuf->chwall_running_types_offset));
+ printf("C. Agg. Off = %x.\n", ntohs(cwbuf->chwall_conflict_aggregate_offset));
+ printf("\nSSID To CHWALL-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + ntohs(cwbuf->chwall_ssid_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_ssidrefs); i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
+ printf("%02x ", ntohs(ssids[i*ntohs(cwbuf->chwall_max_types) + j]));
+ }
+ printf("\n\nConfict Sets:\n");
+ conflicts = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_sets_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_conflictsets); i++) {
+ printf("\n c-set%2x: ", i);
+ for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
+ printf("%02x ", ntohs(conflicts[i*ntohs(cwbuf->chwall_max_types) +j]));
+ }
+ printf("\n");
+
+ printf("\nRunning\nTypes: ");
+ if (ntohs(cwbuf->chwall_running_types_offset)) {
+ running_types = (domaintype_t *)(buf + ntohs(cwbuf->chwall_running_types_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) {
+ printf("%02x ", ntohs(running_types[i]));
+ }
+ printf("\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+ printf("\nConflict\nAggregate Set: ");
+ if (ntohs(cwbuf->chwall_conflict_aggregate_offset)) {
+ conflict_aggregate = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_aggregate_offset));
+ for(i=0; i< ntohs(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 (ntohs(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("Max Types = %x.\n", ntohs(stebuf->ste_max_types));
+ printf("Max Ssidrefs = %x.\n", ntohs(stebuf->ste_max_ssidrefs));
+ printf("Ssidrefs Off = %x.\n", ntohs(stebuf->ste_ssid_offset));
+ printf("\nSSID To STE-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + ntohs(stebuf->ste_ssid_offset));
+ for(i=0; i< ntohs(stebuf->ste_max_ssidrefs); i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< ntohs(stebuf->ste_max_types); j++)
+ printf("%02x ", ntohs(ssids[i*ntohs(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("Magic = %x.\n", ntohl(pol->magic));
+ printf("PolVer = %x.\n", ntohl(pol->policyversion));
+ printf("Len = %x.\n", ntohl(pol->len));
+ printf("Primary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME(ntohs(pol->primary_policy_code)),
+ ntohs(pol->primary_policy_code), ntohs(pol->primary_buffer_offset));
+ printf("Secondary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME(ntohs(pol->secondary_policy_code)),
+ ntohs(pol->secondary_policy_code), ntohs(pol->secondary_buffer_offset));
+ switch (ntohs(pol->primary_policy_code)) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+ntohs(pol->primary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->primary_buffer_offset));
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+ntohs(pol->primary_buffer_offset),
+ ntohl(pol->len) - ntohs(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 (ntohs(pol->secondary_policy_code)) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+ntohs(pol->secondary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+ntohs(pol->secondary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
+ break;
+ case ACM_NULL_POLICY:
+ printf("Secondary policy is NULL Policy (n/a).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ printf("\nPolicy dump End.\n\n");
+}
+
+/*************************** set policy ****************************/
+
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
+#define CWALL_MAX_SSIDREFS 5
+#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 i,j;
+
+ chwall_bin_pol->chwall_max_types = htons(CWALL_MAX_TYPES);
+ chwall_bin_pol->chwall_max_ssidrefs = htons(CWALL_MAX_SSIDREFS);
+ chwall_bin_pol->policy_code = htons(ACM_CHINESE_WALL_POLICY);
+ chwall_bin_pol->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer));
+ chwall_bin_pol->chwall_max_conflictsets = htons(CWALL_MAX_CONFLICTSETS);
+ chwall_bin_pol->chwall_conflict_sets_offset =
+ htons(
+ ntohs(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+ntohs(chwall_bin_pol->chwall_ssid_offset));
+ for(i=0; i< CWALL_MAX_SSIDREFS; i++) {
+ for (j=0; j< CWALL_MAX_TYPES; j++)
+ ssidrefs[i*CWALL_MAX_TYPES + j] = htons(0);
+ /* here, set type i for ssidref i; generally, a ssidref can have multiple chwall types */
+ if (i < CWALL_MAX_SSIDREFS)
+ ssidrefs[i*CWALL_MAX_TYPES + i] = 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 +
+ ntohs(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]={0,5,6} */
+ if (CWALL_MAX_TYPES > 3) {
+ conflicts[2] = htons(1); conflicts[3] = htons(1); /* {2,3} */
+ conflicts[CWALL_MAX_TYPES] = 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 5
+#define STE_MAX_TYPES 5
+
+ struct acm_ste_policy_buffer *ste_bin_pol = (struct acm_ste_policy_buffer *)bufstart;
+ domaintype_t *ssidrefs;
+ int i,j, ret = 0;
+
+ ste_bin_pol->ste_max_types = htons(STE_MAX_TYPES);
+ ste_bin_pol->ste_max_ssidrefs = htons(STE_MAX_SSIDREFS);
+ ste_bin_pol->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+ ste_bin_pol->ste_ssid_offset = htons(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+ntohs(ste_bin_pol->ste_ssid_offset));
+ for(i=0; i< STE_MAX_SSIDREFS; i++) {
+ for (j=0; j< STE_MAX_TYPES; j++)
+ ssidrefs[i*STE_MAX_TYPES + j] = htons(0);
+ /* set type i in ssidref 0 and ssidref i */
+ ssidrefs[i] = htons(1); /* ssidref 0 has all types set */
+ if (i < STE_MAX_SSIDREFS)
+ ssidrefs[i*STE_MAX_TYPES + i] = 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;
+ policy_op_t op;
+
+ /* future: read policy from file and set it */
+ bin_pol = (struct acm_policy_buffer *)push_buffer;
+ bin_pol->magic = htonl(ACM_MAGIC);
+ bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
+ bin_pol->primary_policy_code = htons(ACM_CHINESE_WALL_POLICY);
+ bin_pol->secondary_policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+
+ bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
+ bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
+ ret = acm_domain_set_chwallpolicy(push_buffer + ntohs(bin_pol->primary_buffer_offset),
+ MAX_PUSH_BUFFER - ntohs(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 = htons(ntohl(bin_pol->len));
+ ret = acm_domain_set_stepolicy(push_buffer + ntohs(bin_pol->secondary_buffer_offset),
+ MAX_PUSH_BUFFER - ntohs(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 = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)push_buffer;
+ op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_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)
+{
+ policy_op_t op;
+ int ret;
+
+ memset(pull_buffer, 0x00, sizeof(pull_buffer));
+ op.cmd = POLICY_GETPOLICY;
+ op.u.getpolicy.pullcache = (void *)pull_buffer;
+ op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = do_policy_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)) {
+ policy_op_t op;
+ /* dump it and then push it down into xen/acm */
+ acm_dump_policy_buffer(buffer, len);
+ op.cmd = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)buffer;
+ op.u.setpolicy.pushcache_size = len;
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_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];
+ policy_op_t op;
+ int ret;
+ struct acm_stats_buffer *stats;
+
+ memset(stats_buffer, 0x00, sizeof(stats_buffer));
+ op.cmd = POLICY_DUMPSTATS;
+ op.u.dumpstats.pullcache = (void *)stats_buffer;
+ op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
+ ret = do_policy_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("PolVer = %x.\n", ntohl(stats->policyversion));
+ printf("Len = %x.\n", ntohl(stats->len));
+
+ switch(ntohs(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 + ntohs(stats->primary_stats_offset)));
+ break;
+ default:
+ printf("UNKNOWN PRIMARY POLICY ERROR!\n");
+ }
+ switch(ntohs(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 + ntohs(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 policycmd_fd;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ if ((policycmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
+ printf("ERROR: Could not open xen policycmd device!\n");
+ exit(-1);
+ }
+
+ if (!strcmp(argv[1], "setpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_setpolicy(policycmd_fd);
+
+ } else if (!strcmp(argv[1], "getpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_getpolicy(policycmd_fd);
+
+ } else if (!strcmp(argv[1], "loadpolicy")) {
+ if (argc != 3)
+ usage(argv[0]);
+ acm_domain_loadpolicy(policycmd_fd, argv[2]);
+
+ } else if (!strcmp(argv[1], "dumpstats")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_dumpstats(policycmd_fd);
+
+ } else
+ usage(argv[0]);
+
+ close(policycmd_fd);
+ return 0;
+}
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index 13d60be08e..81721d961e 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -78,13 +78,14 @@ static PyObject *pyxc_domain_create(PyObject *self,
u32 dom = 0;
int ret;
+ u32 ssidref = 0xFFFFFFFF;
- static char *kwd_list[] = { "dom", NULL };
+ static char *kwd_list[] = { "dom", "ssidref", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &dom))
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, &dom, &ssidref))
return NULL;
- if ( (ret = xc_domain_create(xc->xc_handle, &dom)) < 0 )
+ if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
@@ -230,7 +231,7 @@ static PyObject *pyxc_domain_getinfo(PyObject *self,
}
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
- ",s:l,s:L,s:l,s:i}",
+ ",s:l,s:L,s:l,s:i,s:i}",
"dom", info[i].domid,
"vcpus", info[i].vcpus,
"dying", info[i].dying,
@@ -242,6 +243,7 @@ static PyObject *pyxc_domain_getinfo(PyObject *self,
"mem_kb", info[i].nr_pages*4,
"cpu_time", info[i].cpu_time,
"maxmem_kb", info[i].max_memkb,
+ "ssidref", info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason);
PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index a47709a369..0383b9c981 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -202,7 +202,9 @@ class XendDomainInfo:
"""
db = parentdb.addChild(uuid)
vm = cls(db)
- id = xc.domain_create()
+ ssidref = int(sxp.child_value(config, 'ssidref'))
+ log.debug('restoring with ssidref='+str(ssidref))
+ id = xc.domain_create(ssidref = ssidref)
vm.setdom(id)
try:
vm.restore = True
@@ -241,6 +243,7 @@ class XendDomainInfo:
self.start_time = None
self.name = None
self.memory = None
+ self.ssidref = None
self.image = None
self.channel = None
@@ -316,6 +319,7 @@ class XendDomainInfo:
"""
self.info = info
self.memory = self.info['mem_kb'] / 1024
+ self.ssidref = self.info['ssidref']
def state_set(self, state):
self.state_updated.acquire()
@@ -336,6 +340,7 @@ class XendDomainInfo:
s += " id=" + str(self.id)
s += " name=" + self.name
s += " memory=" + str(self.memory)
+ s += " ssidref=" + str(self.ssidref)
console = self.getConsole()
if console:
s += " console=" + str(console.console_port)
@@ -398,7 +403,8 @@ class XendDomainInfo:
sxpr = ['domain',
['id', self.id],
['name', self.name],
- ['memory', self.memory] ]
+ ['memory', self.memory],
+ ['ssidref', self.ssidref] ]
if self.uuid:
sxpr.append(['uuid', self.uuid])
if self.info:
@@ -533,6 +539,7 @@ class XendDomainInfo:
self.memory = int(sxp.child_value(config, 'memory'))
if self.memory is None:
raise VmError('missing memory size')
+ self.ssidref = int(sxp.child_value(config, 'ssidref'))
cpu = sxp.child_value(config, 'cpu')
if self.recreate and self.id and cpu is not None and int(cpu) >= 0:
xc.domain_pincpu(self.id, 0, 1<<int(cpu))
@@ -644,7 +651,7 @@ class XendDomainInfo:
def show(self):
"""Print virtual machine info.
"""
- print "[VM dom=%d name=%s memory=%d" % (self.id, self.name, self.memory)
+ print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.id, self.name, self.memory, self.ssidref)
print "image:"
sxp.show(self.image)
print "]"
@@ -660,7 +667,7 @@ class XendDomainInfo:
cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
except:
raise VmError('invalid cpu')
- id = self.image.initDomain(self.id, self.memory, cpu, self.cpu_weight)
+ id = self.image.initDomain(self.id, self.memory, self.ssidref, cpu, self.cpu_weight)
log.debug('init_domain> Created domain=%d name=%s memory=%d',
id, self.name, self.memory)
self.setdom(id)
@@ -1011,6 +1018,7 @@ addImageHandlerClass(VmxImageHandler)
# Ignore the fields we already handle.
add_config_handler('name', vm_field_ignore)
add_config_handler('memory', vm_field_ignore)
+add_config_handler('ssidref', vm_field_ignore)
add_config_handler('cpu', vm_field_ignore)
add_config_handler('cpu_weight', vm_field_ignore)
add_config_handler('console', vm_field_ignore)
diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
index f3b8642a5f..5abc121e86 100644
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -111,7 +111,7 @@ class ImageHandler:
except OSError, ex:
log.warning("error removing bootloader file '%s': %s", f, ex)
- def initDomain(self, dom, memory, cpu, cpu_weight):
+ def initDomain(self, dom, memory, ssidref, cpu, cpu_weight):
"""Initial domain create.
@return domain id
@@ -119,14 +119,14 @@ class ImageHandler:
mem_kb = self.getDomainMemory(memory)
if not self.vm.restore:
- dom = xc.domain_create(dom = dom or 0)
+ dom = xc.domain_create(dom = dom or 0, ssidref = ssidref)
# if bootloader, unlink here. But should go after buildDomain() ?
if self.vm.bootloader:
self.unlink(self.kernel)
self.unlink(self.ramdisk)
if dom <= 0:
raise VmError('Creating domain failed: name=%s' % self.vm.name)
- log.debug("initDomain: cpu=%d mem_kb=%d dom=%d", cpu, mem_kb, dom)
+ log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom)
# xc.domain_setuuid(dom, uuid)
xc.domain_setcpuweight(dom, cpu_weight)
xc.domain_setmaxmem(dom, mem_kb)
diff --git a/tools/python/xen/xend/server/SrvDomainDir.py b/tools/python/xen/xend/server/SrvDomainDir.py
index d6f6291716..7fcc7c5cf7 100644
--- a/tools/python/xen/xend/server/SrvDomainDir.py
+++ b/tools/python/xen/xend/server/SrvDomainDir.py
@@ -142,6 +142,7 @@ class SrvDomainDir(SrvDir):
% (url, d.name, d.name))
req.write('id=%s' % d.id)
req.write('memory=%d'% d.memory)
+ req.write('ssidref=%d'% d.ssidref)
req.write('</li>')
req.write('</ul>')
diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py
index 23001cc458..d2219f9668 100644
--- a/tools/python/xen/xm/create.py
+++ b/tools/python/xen/xm/create.py
@@ -120,6 +120,10 @@ gopts.var('memory', val='MEMORY',
fn=set_int, default=128,
use="Domain memory in MB.")
+gopts.var('ssidref', val='SSIDREF',
+ fn=set_u32, default=0xffffffff,
+ use="Security Identifier.")
+
gopts.var('maxmem', val='MEMORY',
fn=set_int, default=None,
use="Maximum domain memory in MB.")
@@ -405,7 +409,8 @@ def make_config(opts, vals):
config = ['vm',
['name', vals.name ],
- ['memory', vals.memory ]]
+ ['memory', vals.memory ],
+ ['ssidref', vals.ssidref ]]
if vals.maxmem:
config.append(['maxmem', vals.maxmem])
if vals.cpu is not None:
diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index d02a190ac4..6eda17e2a9 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -383,7 +383,7 @@ class ProgList(Prog):
self.brief_list(doms)
def brief_list(self, doms):
- print 'Name Id Mem(MB) CPU VCPU(s) State Time(s) Console'
+ print 'Name Id Mem(MB) CPU VCPU(s) State Time(s) Console SSID-REF'
for dom in doms:
info = server.xend_domain(dom)
d = {}
@@ -399,8 +399,12 @@ class ProgList(Prog):
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
- print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s"
- % d)
+ if ((int(sxp.child_value(info, 'ssidref', '-1'))) != -1):
+ d['ssidref1'] = int(sxp.child_value(info, 'ssidref', '-1')) & 0xffff
+ d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '-1')) >> 16) & 0xffff
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
+ else:
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s default" % d)
def show_vcpus(self, doms):
print 'Name Id VCPU CPU CPUMAP'
diff --git a/tools/python/xen/xm/opts.py b/tools/python/xen/xm/opts.py
index f92c82dfe6..30900450dc 100644
--- a/tools/python/xen/xm/opts.py
+++ b/tools/python/xen/xm/opts.py
@@ -451,6 +451,13 @@ def set_bool(opt, k, v):
else:
opt.opts.err('Invalid value:' +v)
+def set_u32(opt, k, v):
+ """Set an option to an u32 value."""
+ try:
+ v = u32(v)
+ except:
+ opt.opts.err('Invalid value: ' + str(v))
+ opt.set(v)
def set_value(opt, k, v):
"""Set an option to a value."""