direct-io.hg

changeset 5514:aa52b853c28b

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>
author smh22@firebug.cl.cam.ac.uk
date Mon Jun 20 22:28:08 2005 +0000 (2005-06-20)
parents acf30d736a08
children 228f78f614cb
files .rootkeys tools/Makefile tools/libxc/xc.h tools/libxc/xc_domain.c tools/policy/Makefile tools/policy/policy_tool.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py tools/python/xen/xm/opts.py xen/Makefile xen/Rules.mk xen/acm/Makefile xen/acm/acm_chinesewall_hooks.c xen/acm/acm_core.c xen/acm/acm_null_hooks.c xen/acm/acm_policy.c xen/acm/acm_simple_type_enforcement_hooks.c xen/arch/x86/setup.c xen/arch/x86/x86_32/entry.S xen/common/dom0_ops.c xen/common/event_channel.c xen/common/grant_table.c xen/common/policy_ops.c xen/include/acm/acm_core.h xen/include/acm/acm_endian.h xen/include/acm/acm_hooks.h xen/include/public/acm.h xen/include/public/acm_dom0_setup.h xen/include/public/dom0_ops.h xen/include/public/policy_ops.h xen/include/public/xen.h xen/include/xen/sched.h
line diff
     1.1 --- a/.rootkeys	Sun Jun 19 17:05:55 2005 +0000
     1.2 +++ b/.rootkeys	Mon Jun 20 22:28:08 2005 +0000
     1.3 @@ -785,6 +785,8 @@ 40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/mis
     1.4  41adc641dV-0cDLSyzMs5BT8nL7v3Q tools/misc/xenperf.c
     1.5  4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops
     1.6  40cf2937dqM1jWW87O5OoOYND8leuA tools/misc/xm
     1.7 +42b742f6JFcp6LFpYu-B4AEsfQwSFw tools/policy/Makefile
     1.8 +42b742f66XOdRMrwaHvbCdSSQyCrFw tools/policy/policy_tool.c
     1.9  4270cc81g3nSNYCZ1ryCMDEbLtMtbQ tools/pygrub/Makefile
    1.10  4270deeccyRsJn6jLnRh9odRtMW9SA tools/pygrub/README
    1.11  4270cc81EIl7NyaS3Av6IPRk2c2a6Q tools/pygrub/setup.py
    1.12 @@ -1101,6 +1103,12 @@ 4050c413NtuyIq5lsYJV4P7KIjujXw tools/xen
    1.13  3f72f1bdJPsV3JCnBqs9ddL9tr6D2g xen/COPYING
    1.14  3ddb79bcbOVHh38VJzc97-JEGD4dJQ xen/Makefile
    1.15  3ddb79bcWnTwYsQRWl_PaneJfa6p0w xen/Rules.mk
    1.16 +42b742f6XHTfIEm_hUPtzjKr37LVhw xen/acm/Makefile
    1.17 +42b742f6tHzn0fZWH3TjPva8gbqpow xen/acm/acm_chinesewall_hooks.c
    1.18 +42b742f6bM8kZwuIUbepHZ8SQQkjJA xen/acm/acm_core.c
    1.19 +42b742f6cwfrPubqH47gQpke8xkYSA xen/acm/acm_null_hooks.c
    1.20 +42b742f69qSxm5MM-wtPaWtCqyI3KA xen/acm/acm_policy.c
    1.21 +42b742f6VbmdlwekQRMhXugjcu9QXg xen/acm/acm_simple_type_enforcement_hooks.c
    1.22  421098b25A0RvuYN3rP28ga3_FN3_Q xen/arch/ia64/Makefile
    1.23  421098b2okIeYXS9w9avmSozls61xA xen/arch/ia64/Rules.mk
    1.24  421098b21p12UcKjHBrLh_LjlvNEwA xen/arch/ia64/acpi.c
    1.25 @@ -1324,6 +1332,7 @@ 3ddb79bduhSEZI8xa7IbGQCpap5y2A xen/commo
    1.26  41a61536SZbR6cj1ukWTb0DYU-vz9w xen/common/multicall.c
    1.27  3ddb79bdD4SLmmdMD7yLW5HcUWucXw xen/common/page_alloc.c
    1.28  3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c
    1.29 +42b742f6mgq9puEr7lUrLST0VEpsig xen/common/policy_ops.c
    1.30  40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c
    1.31  41ebbfe9oF1BF3cH5v7yE3eOL9uPbA xen/common/sched_sedf.c
    1.32  3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
    1.33 @@ -1339,6 +1348,9 @@ 3e4a8cb7alzQCDKS7MlioPoHBKYkdQ xen/drive
    1.34  4049e6bfNSIq7s7OV-Bd69QD0RpR2Q xen/drivers/char/console.c
    1.35  4298e018XQtZkCdufpyFimOGZqqsFA xen/drivers/char/ns16550.c
    1.36  3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/serial.c
    1.37 +42b742f6OteAMPWnoqxqfRX3yxD0yw xen/include/acm/acm_core.h
    1.38 +42b742f6XfIijctEwA0YWL2BoWtDNg xen/include/acm/acm_endian.h
    1.39 +42b742f6jXvp1vdbU2v2WJjTPku65A xen/include/acm/acm_hooks.h
    1.40  40715b2cFpte_UNWnBZW0Du7z9AhTQ xen/include/acpi/acconfig.h
    1.41  40715b2ctNvVZ058w8eM8DR9hOat_A xen/include/acpi/acexcep.h
    1.42  40715b2com8I01qcHcAw47e93XsCqQ xen/include/acpi/acglobal.h
    1.43 @@ -1489,6 +1501,8 @@ 404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/inclu
    1.44  404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
    1.45  422f27c8RHFkePhD34VIEpMMqofZcA xen/include/asm-x86/x86_emulate.h
    1.46  400304fcmRQmDdFYEzDh0wcBba9alg xen/include/public/COPYING
    1.47 +42b742f6duiOTlZvysQkRYZHYBXqvg xen/include/public/acm.h
    1.48 +42b742f7TIMsQgUaNDJXp3QlBve2SQ xen/include/public/acm_dom0_setup.h
    1.49  421098b7OKb9YH_EUA_UpCxBjaqtgA xen/include/public/arch-ia64.h
    1.50  404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/public/arch-x86_32.h
    1.51  404f1bc7IwU-qnH8mJeVu0YsNGMrcw xen/include/public/arch-x86_64.h
    1.52 @@ -1502,6 +1516,7 @@ 40f5623cTZ80EwjWUBlh44A9F9i_Lg xen/inclu
    1.53  41d40e9b8zCk5VDqhVbuQyhc7G3lqA xen/include/public/io/ring.h
    1.54  41ee5e8c6mLxIx82KPsbpt_uts_vSA xen/include/public/io/usbif.h
    1.55  4051db79512nOCGweabrFWO2M2h5ng xen/include/public/physdev.h
    1.56 +42b742f7Lzy8SKKG25L_-fgk5FHA2Q xen/include/public/policy_ops.h
    1.57  40589968wmhPmV5-ENbBYmMjnedgKw xen/include/public/sched_ctl.h
    1.58  404f3d2eR2Owk-ZcGOx9ULGHg3nrww xen/include/public/trace.h
    1.59  42b5a5f2QC1IxeuwCwwsOEhvcJ2BJg xen/include/public/version.h
     2.1 --- a/tools/Makefile	Sun Jun 19 17:05:55 2005 +0000
     2.2 +++ b/tools/Makefile	Mon Jun 20 22:28:08 2005 +0000
     2.3 @@ -12,6 +12,7 @@ SUBDIRS += xcs
     2.4  SUBDIRS += xcutils
     2.5  SUBDIRS += pygrub
     2.6  SUBDIRS += firmware
     2.7 +SUBDIRS += policy
     2.8  
     2.9  .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
    2.10  
     3.1 --- a/tools/libxc/xc.h	Sun Jun 19 17:05:55 2005 +0000
     3.2 +++ b/tools/libxc/xc.h	Mon Jun 20 22:28:08 2005 +0000
     3.3 @@ -110,6 +110,7 @@ int xc_waitdomain_core(int domain,
     3.4  
     3.5  typedef struct {
     3.6      u32           domid;
     3.7 +    u32           ssidref;
     3.8      unsigned int  dying:1, crashed:1, shutdown:1, 
     3.9                    paused:1, blocked:1, running:1;
    3.10      unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
    3.11 @@ -124,6 +125,7 @@ typedef struct {
    3.12  
    3.13  typedef dom0_getdomaininfo_t xc_domaininfo_t;
    3.14  int xc_domain_create(int xc_handle, 
    3.15 +                     u32 ssidref,
    3.16                       u32 *pdomid);
    3.17  
    3.18  
     4.1 --- a/tools/libxc/xc_domain.c	Sun Jun 19 17:05:55 2005 +0000
     4.2 +++ b/tools/libxc/xc_domain.c	Mon Jun 20 22:28:08 2005 +0000
     4.3 @@ -9,6 +9,7 @@
     4.4  #include "xc_private.h"
     4.5  
     4.6  int xc_domain_create(int xc_handle,
     4.7 +                     u32 ssidref,
     4.8                       u32 *pdomid)
     4.9  {
    4.10      int err;
    4.11 @@ -16,6 +17,7 @@ int xc_domain_create(int xc_handle,
    4.12  
    4.13      op.cmd = DOM0_CREATEDOMAIN;
    4.14      op.u.createdomain.domain = (domid_t)*pdomid;
    4.15 +    op.u.createdomain.ssidref = ssidref;
    4.16      if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
    4.17          return err;
    4.18  
    4.19 @@ -101,6 +103,7 @@ int xc_domain_getinfo(int xc_handle,
    4.20              info->crashed  = 1;
    4.21          }
    4.22  
    4.23 +        info->ssidref  = op.u.getdomaininfo.ssidref;
    4.24          info->nr_pages = op.u.getdomaininfo.tot_pages;
    4.25          info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
    4.26          info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/policy/Makefile	Mon Jun 20 22:28:08 2005 +0000
     5.3 @@ -0,0 +1,36 @@
     5.4 +XEN_ROOT = ../..
     5.5 +include $(XEN_ROOT)/tools/Rules.mk
     5.6 +
     5.7 +SRCS     = policy_tool.c
     5.8 +CFLAGS   += -static
     5.9 +CFLAGS   += -Wall
    5.10 +CFLAGS   += -Werror
    5.11 +CFLAGS   += -O3
    5.12 +CFLAGS   += -fno-strict-aliasing
    5.13 +CFLAGS   += -I.
    5.14 +
    5.15 +all: build
    5.16 +build: mk-symlinks
    5.17 +	$(MAKE) policy_tool
    5.18 +
    5.19 +default: all
    5.20 +
    5.21 +install: all
    5.22 +
    5.23 +policy_tool : policy_tool.c
    5.24 +	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
    5.25 +
    5.26 +clean:
    5.27 +	rm -rf policy_tool xen
    5.28 +
    5.29 +
    5.30 +LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
    5.31 +mk-symlinks:
    5.32 +	[ -e xen/linux ] || mkdir -p xen/linux
    5.33 +	[ -e xen/io ]    || mkdir -p xen/io
    5.34 +	( cd xen >/dev/null ; \
    5.35 +	  ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
    5.36 +	( cd xen/io >/dev/null ; \
    5.37 +	  ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
    5.38 +	( cd xen/linux >/dev/null ; \
    5.39 +	  ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/policy/policy_tool.c	Mon Jun 20 22:28:08 2005 +0000
     6.3 @@ -0,0 +1,557 @@
     6.4 +/****************************************************************
     6.5 + * policy_tool.c
     6.6 + * 
     6.7 + * Copyright (C) 2005 IBM Corporation
     6.8 + *
     6.9 + * Authors:
    6.10 + * Reiner Sailer <sailer@watson.ibm.com>
    6.11 + * Stefan Berger <stefanb@watson.ibm.com>
    6.12 + *
    6.13 + * This program is free software; you can redistribute it and/or
    6.14 + * modify it under the terms of the GNU General Public License as
    6.15 + * published by the Free Software Foundation, version 2 of the
    6.16 + * License. 
    6.17 + *
    6.18 + * sHype policy management tool. This code runs in a domain and
    6.19 + *     manages the Xen security policy by interacting with the
    6.20 + *     Xen access control module via a /proc/xen/policycmd proc-ioctl, 
    6.21 + *     which is translated into a policy_op hypercall into Xen.
    6.22 + * 
    6.23 + * todo: implement setpolicy to dynamically set a policy cache.
    6.24 + */
    6.25 +#include <unistd.h>
    6.26 +#include <stdio.h>
    6.27 +#include <errno.h>
    6.28 +#include <fcntl.h>
    6.29 +#include <sys/mman.h>
    6.30 +#include <sys/types.h>
    6.31 +#include <sys/stat.h>
    6.32 +#include <stdlib.h>
    6.33 +#include <sys/ioctl.h>
    6.34 +#include <string.h>
    6.35 +#include <stdint.h>
    6.36 +#include <netinet/in.h>
    6.37 +
    6.38 +typedef uint8_t            u8;
    6.39 +typedef uint16_t           u16;
    6.40 +typedef uint32_t           u32;
    6.41 +typedef uint64_t           u64;
    6.42 +typedef int8_t             s8;
    6.43 +typedef int16_t            s16;
    6.44 +typedef int32_t            s32;
    6.45 +typedef int64_t            s64;
    6.46 +
    6.47 +#include <xen/acm.h>
    6.48 +
    6.49 +#include <xen/policy_ops.h>
    6.50 +
    6.51 +#include <xen/linux/privcmd.h>
    6.52 +
    6.53 +#define ERROR(_m, _a...)	\
    6.54 +	fprintf(stderr, "ERROR: " _m "\n" , ## _a )
    6.55 +
    6.56 +#define PERROR(_m, _a...) \
    6.57 +	fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,	\
    6.58 +            errno, strerror(errno))
    6.59 +
    6.60 +static inline int do_policycmd(int xc_handle,
    6.61 +                             unsigned int cmd, 
    6.62 +                             unsigned long data)
    6.63 +{
    6.64 +    return ioctl(xc_handle, cmd, data);
    6.65 +}
    6.66 +
    6.67 +static inline int do_xen_hypercall(int xc_handle,
    6.68 +                                   privcmd_hypercall_t *hypercall)
    6.69 +{
    6.70 +    return do_policycmd(xc_handle,
    6.71 +                      IOCTL_PRIVCMD_HYPERCALL, 
    6.72 +                      (unsigned long)hypercall);
    6.73 +}
    6.74 +
    6.75 +static inline int do_policy_op(int xc_handle, policy_op_t *op)
    6.76 +{
    6.77 +    int ret = -1;
    6.78 +    privcmd_hypercall_t hypercall;
    6.79 +
    6.80 +    op->interface_version = POLICY_INTERFACE_VERSION;
    6.81 +
    6.82 +    hypercall.op     = __HYPERVISOR_policy_op;
    6.83 +    hypercall.arg[0] = (unsigned long)op;
    6.84 +
    6.85 +    if ( mlock(op, sizeof(*op)) != 0 )
    6.86 +    {
    6.87 +        PERROR("Could not lock memory for Xen policy hypercall");
    6.88 +        goto out1;
    6.89 +    }
    6.90 +
    6.91 +    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
    6.92 +    {
    6.93 +        if ( errno == EACCES )
    6.94 +            fprintf(stderr, "POLICY operation failed -- need to"
    6.95 +                    " rebuild the user-space tool set?\n");
    6.96 +        goto out2;
    6.97 +    }
    6.98 +
    6.99 + out2: (void)munlock(op, sizeof(*op));
   6.100 + out1: return ret;
   6.101 +}
   6.102 +
   6.103 +/*************************** DUMPS *******************************/
   6.104 +
   6.105 +void acm_dump_chinesewall_buffer(void *buf, int buflen) {
   6.106 +
   6.107 +	struct acm_chwall_policy_buffer *cwbuf = (struct acm_chwall_policy_buffer *)buf;
   6.108 +	domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
   6.109 +	int i,j;
   6.110 +
   6.111 +       
   6.112 +	if (htons(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY) {
   6.113 +		printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
   6.114 +		return;
   6.115 +	}
   6.116 +	printf("\n\nChinese Wall policy:\n");
   6.117 +	printf("====================\n");
   6.118 +	printf("Max Types     = %x.\n", ntohs(cwbuf->chwall_max_types));
   6.119 +	printf("Max Ssidrefs  = %x.\n", ntohs(cwbuf->chwall_max_ssidrefs));
   6.120 +	printf("Max ConfSets  = %x.\n", ntohs(cwbuf->chwall_max_conflictsets));
   6.121 +	printf("Ssidrefs Off  = %x.\n", ntohs(cwbuf->chwall_ssid_offset));
   6.122 +	printf("Conflicts Off = %x.\n", ntohs(cwbuf->chwall_conflict_sets_offset));
   6.123 +	printf("Runing T. Off = %x.\n", ntohs(cwbuf->chwall_running_types_offset));
   6.124 +	printf("C. Agg. Off   = %x.\n", ntohs(cwbuf->chwall_conflict_aggregate_offset));
   6.125 +	printf("\nSSID To CHWALL-Type matrix:\n");
   6.126 +
   6.127 +	ssids = (domaintype_t *)(buf + ntohs(cwbuf->chwall_ssid_offset));
   6.128 +	for(i=0; i< ntohs(cwbuf->chwall_max_ssidrefs); i++) {
   6.129 +		printf("\n   ssidref%2x:  ", i);
   6.130 +		for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
   6.131 +			printf("%02x ", ntohs(ssids[i*ntohs(cwbuf->chwall_max_types) + j]));
   6.132 +	}
   6.133 +	printf("\n\nConfict Sets:\n");
   6.134 +	conflicts = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_sets_offset));
   6.135 +	for(i=0; i< ntohs(cwbuf->chwall_max_conflictsets); i++) {
   6.136 +		printf("\n   c-set%2x:    ", i);
   6.137 +		for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
   6.138 +			printf("%02x ", ntohs(conflicts[i*ntohs(cwbuf->chwall_max_types) +j]));
   6.139 +	}
   6.140 +	printf("\n");
   6.141 +
   6.142 +	printf("\nRunning\nTypes:         ");
   6.143 +	if (ntohs(cwbuf->chwall_running_types_offset)) {
   6.144 +		running_types = (domaintype_t *)(buf + ntohs(cwbuf->chwall_running_types_offset));
   6.145 +		for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) {
   6.146 +			printf("%02x ", ntohs(running_types[i]));
   6.147 +		}
   6.148 +		printf("\n");
   6.149 +	} else {
   6.150 +		printf("Not Reported!\n");
   6.151 +	}
   6.152 +	printf("\nConflict\nAggregate Set: ");
   6.153 +	if (ntohs(cwbuf->chwall_conflict_aggregate_offset)) {
   6.154 +		conflict_aggregate = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_aggregate_offset));
   6.155 +		for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) {
   6.156 +			printf("%02x ", ntohs(conflict_aggregate[i]));
   6.157 +		}
   6.158 +		printf("\n\n");
   6.159 +	} else {
   6.160 +		printf("Not Reported!\n");
   6.161 +	}
   6.162 +}
   6.163 +
   6.164 +void acm_dump_ste_buffer(void *buf, int buflen) {
   6.165 +
   6.166 +	struct acm_ste_policy_buffer *stebuf = (struct acm_ste_policy_buffer *)buf;
   6.167 +	domaintype_t *ssids;
   6.168 +	int i,j;
   6.169 +
   6.170 +       
   6.171 +	if (ntohs(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
   6.172 +		printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
   6.173 +		return;
   6.174 +	}
   6.175 +	printf("\nSimple Type Enforcement policy:\n");
   6.176 +	printf("===============================\n");
   6.177 +	printf("Max Types     = %x.\n", ntohs(stebuf->ste_max_types));
   6.178 +	printf("Max Ssidrefs  = %x.\n", ntohs(stebuf->ste_max_ssidrefs));
   6.179 +	printf("Ssidrefs Off  = %x.\n", ntohs(stebuf->ste_ssid_offset));
   6.180 +	printf("\nSSID To STE-Type matrix:\n");
   6.181 +	
   6.182 +	ssids = (domaintype_t *)(buf + ntohs(stebuf->ste_ssid_offset));
   6.183 +	for(i=0; i< ntohs(stebuf->ste_max_ssidrefs); i++) {
   6.184 +		printf("\n   ssidref%2x: ", i);
   6.185 +		for(j=0; j< ntohs(stebuf->ste_max_types); j++)
   6.186 +			printf("%02x ", ntohs(ssids[i*ntohs(stebuf->ste_max_types) +j]));
   6.187 +	}
   6.188 +	printf("\n\n");
   6.189 +}
   6.190 +
   6.191 +void acm_dump_policy_buffer(void *buf, int buflen) {
   6.192 +	struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
   6.193 +
   6.194 +	printf("\nPolicy dump:\n");
   6.195 +	printf("============\n");
   6.196 +	printf("Magic     = %x.\n", ntohl(pol->magic));
   6.197 +	printf("PolVer    = %x.\n", ntohl(pol->policyversion));
   6.198 +	printf("Len       = %x.\n", ntohl(pol->len));
   6.199 +	printf("Primary   = %s (c=%x, off=%x).\n",
   6.200 +	       ACM_POLICY_NAME(ntohs(pol->primary_policy_code)),
   6.201 +	       ntohs(pol->primary_policy_code), ntohs(pol->primary_buffer_offset));
   6.202 +	printf("Secondary = %s (c=%x, off=%x).\n",
   6.203 +	       ACM_POLICY_NAME(ntohs(pol->secondary_policy_code)),
   6.204 +	       ntohs(pol->secondary_policy_code), ntohs(pol->secondary_buffer_offset));
   6.205 +	switch (ntohs(pol->primary_policy_code)) {
   6.206 +	case ACM_CHINESE_WALL_POLICY:
   6.207 +		acm_dump_chinesewall_buffer(buf+ntohs(pol->primary_buffer_offset), 
   6.208 +					     ntohl(pol->len) - ntohs(pol->primary_buffer_offset));
   6.209 +		break;
   6.210 +	case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   6.211 +		acm_dump_ste_buffer(buf+ntohs(pol->primary_buffer_offset), 
   6.212 +				    ntohl(pol->len) - ntohs(pol->primary_buffer_offset));
   6.213 +		break;
   6.214 +	case ACM_NULL_POLICY:
   6.215 +		printf("Primary policy is NULL Policy (n/a).\n");
   6.216 +		break;
   6.217 +	default:
   6.218 +		printf("UNKNOWN POLICY!\n");
   6.219 +	}
   6.220 +	switch (ntohs(pol->secondary_policy_code)) {
   6.221 +	case ACM_CHINESE_WALL_POLICY:
   6.222 +		acm_dump_chinesewall_buffer(buf+ntohs(pol->secondary_buffer_offset), 
   6.223 +					     ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
   6.224 +		break;
   6.225 +	case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   6.226 +		acm_dump_ste_buffer(buf+ntohs(pol->secondary_buffer_offset), 
   6.227 +				    ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
   6.228 +		break;
   6.229 +	case ACM_NULL_POLICY:
   6.230 +		printf("Secondary policy is NULL Policy (n/a).\n");
   6.231 +		break;
   6.232 +	default:
   6.233 +		printf("UNKNOWN POLICY!\n");
   6.234 +	}
   6.235 +	printf("\nPolicy dump End.\n\n");
   6.236 +}
   6.237 +
   6.238 +/*************************** set policy ****************************/
   6.239 +
   6.240 +int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
   6.241 +#define CWALL_MAX_SSIDREFS      	5
   6.242 +#define CWALL_MAX_TYPES  		10
   6.243 +#define CWALL_MAX_CONFLICTSETS		2
   6.244 +
   6.245 +     struct acm_chwall_policy_buffer *chwall_bin_pol = (struct acm_chwall_policy_buffer *)bufstart;
   6.246 +     domaintype_t *ssidrefs, *conflicts;
   6.247 +     int ret = 0;
   6.248 +     int i,j;
   6.249 +
   6.250 +     chwall_bin_pol->chwall_max_types = htons(CWALL_MAX_TYPES);
   6.251 +     chwall_bin_pol->chwall_max_ssidrefs = htons(CWALL_MAX_SSIDREFS);
   6.252 +     chwall_bin_pol->policy_code = htons(ACM_CHINESE_WALL_POLICY);
   6.253 +     chwall_bin_pol->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer));
   6.254 +     chwall_bin_pol->chwall_max_conflictsets = htons(CWALL_MAX_CONFLICTSETS);
   6.255 +     chwall_bin_pol->chwall_conflict_sets_offset =
   6.256 +	 htons(
   6.257 +	     ntohs(chwall_bin_pol->chwall_ssid_offset) + 
   6.258 +	     sizeof(domaintype_t)*CWALL_MAX_SSIDREFS*CWALL_MAX_TYPES);
   6.259 +     chwall_bin_pol->chwall_running_types_offset = 0; /* not set */
   6.260 +     chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */
   6.261 +     ret += sizeof(struct acm_chwall_policy_buffer);
   6.262 +     /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
   6.263 +     /* check buffer size */
   6.264 +     if ((buflen - ret) < (CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t)))
   6.265 +			   return -1; /* not enough space */
   6.266 +
   6.267 +     ssidrefs = (domaintype_t *)(bufstart+ntohs(chwall_bin_pol->chwall_ssid_offset));
   6.268 +     for(i=0; i< CWALL_MAX_SSIDREFS; i++) {
   6.269 +	     for (j=0; j< CWALL_MAX_TYPES; j++)
   6.270 +		     ssidrefs[i*CWALL_MAX_TYPES + j] = htons(0);
   6.271 +	     /* here, set type i for ssidref i; generally, a ssidref can have multiple chwall types */
   6.272 +	     if (i < CWALL_MAX_SSIDREFS)
   6.273 +		     ssidrefs[i*CWALL_MAX_TYPES + i] = htons(1);
   6.274 +     }
   6.275 +     ret += CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t);
   6.276 +     if ((buflen - ret) < (CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t)))
   6.277 +			   return -1; /* not enough space */
   6.278 +
   6.279 +     /* now the chinese wall policy conflict sets*/
   6.280 +     conflicts = (domaintype_t *)(bufstart + 
   6.281 +				  ntohs(chwall_bin_pol->chwall_conflict_sets_offset));
   6.282 +     memset((void *)conflicts, 0, CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t));
   6.283 +     /* just 1 conflict set [0]={2,3}, [1]={0,5,6} */
   6.284 +     if (CWALL_MAX_TYPES > 3) {
   6.285 +	     conflicts[2] = htons(1); conflicts[3] = htons(1); /* {2,3} */
   6.286 +	     conflicts[CWALL_MAX_TYPES] = htons(1); conflicts[CWALL_MAX_TYPES+5] = htons(1); 
   6.287 +	     conflicts[CWALL_MAX_TYPES+6] = htons(1);/* {0,5,6} */
   6.288 +     }
   6.289 +     ret += sizeof(domaintype_t)*CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES;
   6.290 +     return ret;
   6.291 +}
   6.292 +
   6.293 +int acm_domain_set_stepolicy(void *bufstart, int buflen) {
   6.294 +#define STE_MAX_SSIDREFS      	5
   6.295 +#define STE_MAX_TYPES  		5
   6.296 +	
   6.297 +    struct acm_ste_policy_buffer *ste_bin_pol = (struct acm_ste_policy_buffer *)bufstart;
   6.298 +    domaintype_t *ssidrefs;
   6.299 +    int i,j, ret = 0;
   6.300 +
   6.301 +    ste_bin_pol->ste_max_types = htons(STE_MAX_TYPES);
   6.302 +    ste_bin_pol->ste_max_ssidrefs = htons(STE_MAX_SSIDREFS);
   6.303 +    ste_bin_pol->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
   6.304 +    ste_bin_pol->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer));
   6.305 +    ret += sizeof(struct acm_ste_policy_buffer);
   6.306 +    /* check buffer size */
   6.307 +    if ((buflen - ret) < (STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t)))
   6.308 +	    return -1; /* not enough space */
   6.309 +
   6.310 +     ssidrefs = (domaintype_t *)(bufstart+ntohs(ste_bin_pol->ste_ssid_offset));
   6.311 +     for(i=0; i< STE_MAX_SSIDREFS; i++) {
   6.312 +	     for (j=0; j< STE_MAX_TYPES; j++)
   6.313 +		     ssidrefs[i*STE_MAX_TYPES + j] = htons(0);
   6.314 +	     /* set type i in ssidref 0 and ssidref i */
   6.315 +	     ssidrefs[i] = htons(1); /* ssidref 0 has all types set */
   6.316 +	     if (i < STE_MAX_SSIDREFS)
   6.317 +		     ssidrefs[i*STE_MAX_TYPES + i] = htons(1);
   6.318 +     }
   6.319 +     ret += STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t);
   6.320 +     return ret;
   6.321 +}
   6.322 +
   6.323 +#define MAX_PUSH_BUFFER 	16384
   6.324 +u8 push_buffer[MAX_PUSH_BUFFER];
   6.325 +
   6.326 +int acm_domain_setpolicy(int xc_handle)
   6.327 +{
   6.328 +     int ret;
   6.329 +     struct acm_policy_buffer *bin_pol;
   6.330 +     policy_op_t op;
   6.331 +
   6.332 +     /* future: read policy from file and set it */
   6.333 +     bin_pol = (struct acm_policy_buffer *)push_buffer;
   6.334 +     bin_pol->magic = htonl(ACM_MAGIC);
   6.335 +     bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
   6.336 +     bin_pol->primary_policy_code = htons(ACM_CHINESE_WALL_POLICY);
   6.337 +     bin_pol->secondary_policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
   6.338 +
   6.339 +     bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
   6.340 +     bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
   6.341 +     ret = acm_domain_set_chwallpolicy(push_buffer + ntohs(bin_pol->primary_buffer_offset), 
   6.342 +				       MAX_PUSH_BUFFER - ntohs(bin_pol->primary_buffer_offset));
   6.343 +     if (ret < 0) {
   6.344 +	     printf("ERROR creating chwallpolicy buffer.\n");
   6.345 +	     return -1;
   6.346 +     }
   6.347 +     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
   6.348 +     bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
   6.349 +     ret = acm_domain_set_stepolicy(push_buffer + ntohs(bin_pol->secondary_buffer_offset), 
   6.350 +				    MAX_PUSH_BUFFER - ntohs(bin_pol->secondary_buffer_offset));
   6.351 +     if (ret < 0) {
   6.352 +	     printf("ERROR creating chwallpolicy buffer.\n");
   6.353 +	     return -1;
   6.354 +     }
   6.355 +     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
   6.356 +
   6.357 +     /* dump it and then push it down into xen/acm */
   6.358 +     acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
   6.359 +     op.cmd = POLICY_SETPOLICY;
   6.360 +     op.u.setpolicy.pushcache = (void *)push_buffer;
   6.361 +     op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
   6.362 +     op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
   6.363 +     ret = do_policy_op(xc_handle, &op);
   6.364 +
   6.365 +     if (ret)
   6.366 +	     printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
   6.367 +     else
   6.368 +	     printf("Successfully changed policy.\n");
   6.369 +     return ret;
   6.370 +}
   6.371 +
   6.372 +/******************************* get policy ******************************/
   6.373 +
   6.374 +#define PULL_CACHE_SIZE		8192
   6.375 +u8 pull_buffer[PULL_CACHE_SIZE];
   6.376 +int acm_domain_getpolicy(int xc_handle)
   6.377 +{
   6.378 +     policy_op_t op;
   6.379 +     int ret;
   6.380 +
   6.381 +     memset(pull_buffer, 0x00, sizeof(pull_buffer));
   6.382 +     op.cmd = POLICY_GETPOLICY;
   6.383 +     op.u.getpolicy.pullcache = (void *)pull_buffer;
   6.384 +     op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
   6.385 +     ret = do_policy_op(xc_handle, &op);
   6.386 +     /* dump policy  */
   6.387 +     acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
   6.388 +     return ret;
   6.389 +}
   6.390 +
   6.391 +/************************ load binary policy ******************************/
   6.392 +
   6.393 +int acm_domain_loadpolicy(int xc_handle,
   6.394 +                          const char *filename)
   6.395 +{
   6.396 +     struct stat mystat;
   6.397 +     int ret, fd;
   6.398 +     off_t len;
   6.399 +     u8 *buffer;
   6.400 +
   6.401 +     if ((ret = stat(filename, &mystat))) {
   6.402 +	     printf("File %s not found.\n",filename);
   6.403 +	     goto out;
   6.404 +     }
   6.405 +
   6.406 +     len = mystat.st_size;
   6.407 +     if ((buffer = malloc(len)) == NULL) {
   6.408 +	     ret = -ENOMEM;
   6.409 +	     goto out;
   6.410 +     }
   6.411 +     if ((fd = open(filename, O_RDONLY)) <= 0) {
   6.412 +	     ret = -ENOENT;
   6.413 +	     printf("File %s not found.\n",filename);
   6.414 +	     goto free_out;
   6.415 +     }
   6.416 +     if (len == read(fd, buffer, len)) {
   6.417 +	     policy_op_t op;
   6.418 +	     /* dump it and then push it down into xen/acm */
   6.419 +	     acm_dump_policy_buffer(buffer, len);
   6.420 +	     op.cmd = POLICY_SETPOLICY;
   6.421 +	     op.u.setpolicy.pushcache = (void *)buffer;
   6.422 +	     op.u.setpolicy.pushcache_size = len;
   6.423 +	     op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
   6.424 +	     ret = do_policy_op(xc_handle, &op);
   6.425 +                     
   6.426 +	     if (ret)
   6.427 +		     printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
   6.428 +	     else
   6.429 +		     printf("Successfully changed policy.\n");
   6.430 +                     
   6.431 +     } else {
   6.432 +	     ret = -1;
   6.433 +     }
   6.434 +     close(fd);
   6.435 + free_out:
   6.436 +     free(buffer);
   6.437 + out:
   6.438 +     return ret;
   6.439 +}
   6.440 +
   6.441 +/************************ dump hook statistics ******************************/
   6.442 +void 
   6.443 +dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
   6.444 +{
   6.445 +    printf("STE-Policy Security Hook Statistics:\n");
   6.446 +    printf("ste: event_channel eval_count      = %d\n", ntohl(ste_stats->ec_eval_count));
   6.447 +    printf("ste: event_channel denied_count    = %d\n", ntohl(ste_stats->ec_denied_count)); 
   6.448 +    printf("ste: event_channel cache_hit_count = %d\n", ntohl(ste_stats->ec_cachehit_count));
   6.449 +    printf("ste:\n");
   6.450 +    printf("ste: grant_table   eval_count      = %d\n", ntohl(ste_stats->gt_eval_count));
   6.451 +    printf("ste: grant_table   denied_count    = %d\n", ntohl(ste_stats->gt_denied_count)); 
   6.452 +    printf("ste: grant_table   cache_hit_count = %d\n", ntohl(ste_stats->gt_cachehit_count));
   6.453 +}
   6.454 +
   6.455 +#define PULL_STATS_SIZE		8192
   6.456 +int acm_domain_dumpstats(int xc_handle)
   6.457 +{
   6.458 +    u8 stats_buffer[PULL_STATS_SIZE];
   6.459 +    policy_op_t op;
   6.460 +    int ret;
   6.461 +    struct acm_stats_buffer *stats;
   6.462 +
   6.463 +    memset(stats_buffer, 0x00, sizeof(stats_buffer));
   6.464 +    op.cmd = POLICY_DUMPSTATS;
   6.465 +    op.u.dumpstats.pullcache = (void *)stats_buffer;
   6.466 +    op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
   6.467 +    ret = do_policy_op(xc_handle, &op);
   6.468 +
   6.469 +    if (ret < 0) {
   6.470 +	printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n"); 
   6.471 +	return ret;
   6.472 +    }
   6.473 +    stats = (struct acm_stats_buffer *)stats_buffer;
   6.474 +
   6.475 +    printf("\nPolicy dump:\n");
   6.476 +    printf("============\n");
   6.477 +    printf("Magic     = %x.\n", ntohl(stats->magic));
   6.478 +    printf("PolVer    = %x.\n", ntohl(stats->policyversion));
   6.479 +    printf("Len       = %x.\n", ntohl(stats->len));
   6.480 +
   6.481 +    switch(ntohs(stats->primary_policy_code)) {
   6.482 +    case ACM_NULL_POLICY:
   6.483 +	    printf("NULL Policy: No statistics apply.\n");
   6.484 +	    break;
   6.485 +    case ACM_CHINESE_WALL_POLICY:
   6.486 +	    printf("Chinese Wall Policy: No statistics apply.\n");
   6.487 +	    break;
   6.488 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   6.489 +	    dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->primary_stats_offset)));
   6.490 +	    break;
   6.491 +    default:
   6.492 +	    printf("UNKNOWN PRIMARY POLICY ERROR!\n");
   6.493 +    }
   6.494 +    switch(ntohs(stats->secondary_policy_code)) {
   6.495 +    case ACM_NULL_POLICY:
   6.496 +	    printf("NULL Policy: No statistics apply.\n");
   6.497 +	    break;
   6.498 +    case ACM_CHINESE_WALL_POLICY:
   6.499 +	    printf("Chinese Wall Policy: No statistics apply.\n");
   6.500 +	    break;
   6.501 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   6.502 +	    dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->secondary_stats_offset)));
   6.503 +	    break;
   6.504 +    default:
   6.505 +	    printf("UNKNOWN SECONDARY POLICY ERROR!\n");
   6.506 +    }                
   6.507 +    return ret;
   6.508 +}
   6.509 +
   6.510 +/***************************** main **************************************/
   6.511 +
   6.512 +void
   6.513 +usage(char *progname){
   6.514 +	printf("Use: %s \n"
   6.515 +	       "\t setpolicy\n"
   6.516 +	       "\t getpolicy\n"
   6.517 +	       "\t dumpstats\n"
   6.518 +	       "\t loadpolicy <binary policy file>\n", progname);
   6.519 +	exit(-1);
   6.520 +}
   6.521 +
   6.522 +int
   6.523 +main(int argc, char **argv) {
   6.524 +
   6.525 +	int policycmd_fd;
   6.526 +
   6.527 +	if (argc < 2)
   6.528 +		usage(argv[0]);
   6.529 +		
   6.530 +	if ((policycmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
   6.531 +		    printf("ERROR: Could not open xen policycmd device!\n");
   6.532 +		    exit(-1);
   6.533 +	}
   6.534 +	    
   6.535 +	if (!strcmp(argv[1], "setpolicy")) {
   6.536 +		if (argc != 2)
   6.537 +			usage(argv[0]);
   6.538 +		acm_domain_setpolicy(policycmd_fd);
   6.539 +
   6.540 +	} else if (!strcmp(argv[1], "getpolicy")) {
   6.541 +		if (argc != 2)
   6.542 +			usage(argv[0]);
   6.543 +		acm_domain_getpolicy(policycmd_fd);
   6.544 +
   6.545 +	} else if (!strcmp(argv[1], "loadpolicy")) {
   6.546 +		if (argc != 3) 
   6.547 +			usage(argv[0]);
   6.548 +		acm_domain_loadpolicy(policycmd_fd, argv[2]);
   6.549 +
   6.550 +	} else if (!strcmp(argv[1], "dumpstats")) {
   6.551 +		if (argc != 2) 
   6.552 +			usage(argv[0]);
   6.553 +		acm_domain_dumpstats(policycmd_fd);
   6.554 +
   6.555 +	} else
   6.556 +		usage(argv[0]);
   6.557 +
   6.558 +	close(policycmd_fd);
   6.559 +	return 0;
   6.560 +}
     7.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sun Jun 19 17:05:55 2005 +0000
     7.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Jun 20 22:28:08 2005 +0000
     7.3 @@ -78,13 +78,14 @@ static PyObject *pyxc_domain_create(PyOb
     7.4  
     7.5      u32          dom = 0;
     7.6      int          ret;
     7.7 +    u32          ssidref = 0xFFFFFFFF;
     7.8  
     7.9 -    static char *kwd_list[] = { "dom", NULL };
    7.10 +    static char *kwd_list[] = { "dom", "ssidref", NULL };
    7.11  
    7.12 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &dom))
    7.13 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, &dom, &ssidref))
    7.14          return NULL;
    7.15  
    7.16 -    if ( (ret = xc_domain_create(xc->xc_handle, &dom)) < 0 )
    7.17 +    if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 )
    7.18          return PyErr_SetFromErrno(xc_error);
    7.19  
    7.20      return PyInt_FromLong(dom);
    7.21 @@ -230,7 +231,7 @@ static PyObject *pyxc_domain_getinfo(PyO
    7.22          }
    7.23                   
    7.24          info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
    7.25 -                                  ",s:l,s:L,s:l,s:i}",
    7.26 +                                  ",s:l,s:L,s:l,s:i,s:i}",
    7.27                                    "dom",       info[i].domid,
    7.28                                    "vcpus",     info[i].vcpus,
    7.29                                    "dying",     info[i].dying,
    7.30 @@ -242,6 +243,7 @@ static PyObject *pyxc_domain_getinfo(PyO
    7.31                                    "mem_kb",    info[i].nr_pages*4,
    7.32                                    "cpu_time",  info[i].cpu_time,
    7.33                                    "maxmem_kb", info[i].max_memkb,
    7.34 +                                  "ssidref",   info[i].ssidref,
    7.35                                    "shutdown_reason", info[i].shutdown_reason);
    7.36          PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
    7.37          PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
     8.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sun Jun 19 17:05:55 2005 +0000
     8.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Jun 20 22:28:08 2005 +0000
     8.3 @@ -202,7 +202,9 @@ class XendDomainInfo:
     8.4          """
     8.5          db = parentdb.addChild(uuid)
     8.6          vm = cls(db)
     8.7 -        id = xc.domain_create()
     8.8 +        ssidref = int(sxp.child_value(config, 'ssidref'))
     8.9 +        log.debug('restoring with ssidref='+str(ssidref))
    8.10 +        id = xc.domain_create(ssidref = ssidref)
    8.11          vm.setdom(id)
    8.12          try:
    8.13              vm.restore = True
    8.14 @@ -241,6 +243,7 @@ class XendDomainInfo:
    8.15          self.start_time = None
    8.16          self.name = None
    8.17          self.memory = None
    8.18 +        self.ssidref = None
    8.19          self.image = None
    8.20  
    8.21          self.channel = None
    8.22 @@ -316,6 +319,7 @@ class XendDomainInfo:
    8.23          """
    8.24          self.info = info
    8.25          self.memory = self.info['mem_kb'] / 1024
    8.26 +        self.ssidref = self.info['ssidref']
    8.27  
    8.28      def state_set(self, state):
    8.29          self.state_updated.acquire()
    8.30 @@ -336,6 +340,7 @@ class XendDomainInfo:
    8.31          s += " id=" + str(self.id)
    8.32          s += " name=" + self.name
    8.33          s += " memory=" + str(self.memory)
    8.34 +        s += " ssidref=" + str(self.ssidref)
    8.35          console = self.getConsole()
    8.36          if console:
    8.37              s += " console=" + str(console.console_port)
    8.38 @@ -398,7 +403,8 @@ class XendDomainInfo:
    8.39          sxpr = ['domain',
    8.40                  ['id', self.id],
    8.41                  ['name', self.name],
    8.42 -                ['memory', self.memory] ]
    8.43 +                ['memory', self.memory],
    8.44 +                ['ssidref', self.ssidref] ]
    8.45          if self.uuid:
    8.46              sxpr.append(['uuid', self.uuid])
    8.47          if self.info:
    8.48 @@ -533,6 +539,7 @@ class XendDomainInfo:
    8.49          self.memory = int(sxp.child_value(config, 'memory'))
    8.50          if self.memory is None:
    8.51              raise VmError('missing memory size')
    8.52 +        self.ssidref = int(sxp.child_value(config, 'ssidref'))
    8.53          cpu = sxp.child_value(config, 'cpu')
    8.54          if self.recreate and self.id and cpu is not None and int(cpu) >= 0:
    8.55              xc.domain_pincpu(self.id, 0, 1<<int(cpu))
    8.56 @@ -644,7 +651,7 @@ class XendDomainInfo:
    8.57      def show(self):
    8.58          """Print virtual machine info.
    8.59          """
    8.60 -        print "[VM dom=%d name=%s memory=%d" % (self.id, self.name, self.memory)
    8.61 +        print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.id, self.name, self.memory, self.ssidref)
    8.62          print "image:"
    8.63          sxp.show(self.image)
    8.64          print "]"
    8.65 @@ -660,7 +667,7 @@ class XendDomainInfo:
    8.66              cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
    8.67          except:
    8.68              raise VmError('invalid cpu')
    8.69 -        id = self.image.initDomain(self.id, self.memory, cpu, self.cpu_weight)
    8.70 +        id = self.image.initDomain(self.id, self.memory, self.ssidref, cpu, self.cpu_weight)
    8.71          log.debug('init_domain> Created domain=%d name=%s memory=%d',
    8.72                    id, self.name, self.memory)
    8.73          self.setdom(id)
    8.74 @@ -1011,6 +1018,7 @@ addImageHandlerClass(VmxImageHandler)
    8.75  # Ignore the fields we already handle.
    8.76  add_config_handler('name',       vm_field_ignore)
    8.77  add_config_handler('memory',     vm_field_ignore)
    8.78 +add_config_handler('ssidref',    vm_field_ignore)
    8.79  add_config_handler('cpu',        vm_field_ignore)
    8.80  add_config_handler('cpu_weight', vm_field_ignore)
    8.81  add_config_handler('console',    vm_field_ignore)
     9.1 --- a/tools/python/xen/xend/image.py	Sun Jun 19 17:05:55 2005 +0000
     9.2 +++ b/tools/python/xen/xend/image.py	Mon Jun 20 22:28:08 2005 +0000
     9.3 @@ -111,7 +111,7 @@ class ImageHandler:
     9.4          except OSError, ex:
     9.5              log.warning("error removing bootloader file '%s': %s", f, ex)
     9.6  
     9.7 -    def initDomain(self, dom, memory, cpu, cpu_weight):
     9.8 +    def initDomain(self, dom, memory, ssidref, cpu, cpu_weight):
     9.9          """Initial domain create.
    9.10  
    9.11          @return domain id
    9.12 @@ -119,14 +119,14 @@ class ImageHandler:
    9.13  
    9.14          mem_kb = self.getDomainMemory(memory)
    9.15          if not self.vm.restore:
    9.16 -            dom = xc.domain_create(dom = dom or 0)
    9.17 +            dom = xc.domain_create(dom = dom or 0, ssidref = ssidref)
    9.18              # if bootloader, unlink here. But should go after buildDomain() ?
    9.19              if self.vm.bootloader:
    9.20                  self.unlink(self.kernel)
    9.21                  self.unlink(self.ramdisk)
    9.22              if dom <= 0:
    9.23                  raise VmError('Creating domain failed: name=%s' % self.vm.name)
    9.24 -        log.debug("initDomain: cpu=%d mem_kb=%d dom=%d", cpu, mem_kb, dom)
    9.25 +        log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom)
    9.26          # xc.domain_setuuid(dom, uuid)
    9.27          xc.domain_setcpuweight(dom, cpu_weight)
    9.28          xc.domain_setmaxmem(dom, mem_kb)
    10.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Sun Jun 19 17:05:55 2005 +0000
    10.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Mon Jun 20 22:28:08 2005 +0000
    10.3 @@ -142,6 +142,7 @@ class SrvDomainDir(SrvDir):
    10.4                           % (url, d.name, d.name))
    10.5                 req.write('id=%s' % d.id)
    10.6                 req.write('memory=%d'% d.memory)
    10.7 +               req.write('ssidref=%d'% d.ssidref)
    10.8                 req.write('</li>')
    10.9              req.write('</ul>')
   10.10  
    11.1 --- a/tools/python/xen/xm/create.py	Sun Jun 19 17:05:55 2005 +0000
    11.2 +++ b/tools/python/xen/xm/create.py	Mon Jun 20 22:28:08 2005 +0000
    11.3 @@ -120,6 +120,10 @@ gopts.var('memory', val='MEMORY',
    11.4            fn=set_int, default=128,
    11.5            use="Domain memory in MB.")
    11.6  
    11.7 +gopts.var('ssidref', val='SSIDREF',
    11.8 +          fn=set_u32, default=0xffffffff,
    11.9 +          use="Security Identifier.")
   11.10 +
   11.11  gopts.var('maxmem', val='MEMORY',
   11.12            fn=set_int, default=None,
   11.13            use="Maximum domain memory in MB.")
   11.14 @@ -405,7 +409,8 @@ def make_config(opts, vals):
   11.15      
   11.16      config = ['vm',
   11.17                ['name', vals.name ],
   11.18 -              ['memory', vals.memory ]]
   11.19 +              ['memory', vals.memory ],
   11.20 +              ['ssidref', vals.ssidref ]]
   11.21      if vals.maxmem:
   11.22          config.append(['maxmem', vals.maxmem])
   11.23      if vals.cpu is not None:
    12.1 --- a/tools/python/xen/xm/main.py	Sun Jun 19 17:05:55 2005 +0000
    12.2 +++ b/tools/python/xen/xm/main.py	Mon Jun 20 22:28:08 2005 +0000
    12.3 @@ -383,7 +383,7 @@ class ProgList(Prog):
    12.4              self.brief_list(doms)
    12.5  
    12.6      def brief_list(self, doms):
    12.7 -        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console'
    12.8 +        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console  SSID-REF'
    12.9          for dom in doms:
   12.10              info = server.xend_domain(dom)
   12.11              d = {}
   12.12 @@ -399,8 +399,12 @@ class ProgList(Prog):
   12.13                  d['port'] = sxp.child_value(console, 'console_port')
   12.14              else:
   12.15                  d['port'] = ''
   12.16 -            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3d  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s"
   12.17 -                   % d)
   12.18 +            if ((int(sxp.child_value(info, 'ssidref', '-1'))) != -1):
   12.19 +                d['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '-1')) & 0xffff
   12.20 +                d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '-1')) >> 16) & 0xffff
   12.21 +                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)
   12.22 +            else:
   12.23 +                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3d  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s     default" % d)
   12.24  
   12.25      def show_vcpus(self, doms):
   12.26          print 'Name              Id  VCPU  CPU  CPUMAP'
    13.1 --- a/tools/python/xen/xm/opts.py	Sun Jun 19 17:05:55 2005 +0000
    13.2 +++ b/tools/python/xen/xm/opts.py	Mon Jun 20 22:28:08 2005 +0000
    13.3 @@ -451,6 +451,13 @@ def set_bool(opt, k, v):
    13.4      else:
    13.5          opt.opts.err('Invalid value:' +v)
    13.6          
    13.7 +def set_u32(opt, k, v):
    13.8 +    """Set an option to an u32 value."""
    13.9 +    try:
   13.10 +        v = u32(v)
   13.11 +    except:
   13.12 +        opt.opts.err('Invalid value: ' + str(v))
   13.13 +    opt.set(v)
   13.14  
   13.15  def set_value(opt, k, v):
   13.16      """Set an option to a value."""
    14.1 --- a/xen/Makefile	Sun Jun 19 17:05:55 2005 +0000
    14.2 +++ b/xen/Makefile	Mon Jun 20 22:28:08 2005 +0000
    14.3 @@ -46,6 +46,7 @@ clean: delete-unfresh-files
    14.4  	$(MAKE) -C tools clean
    14.5  	$(MAKE) -C common clean
    14.6  	$(MAKE) -C drivers clean
    14.7 +	$(MAKE) -C acm clean
    14.8  	$(MAKE) -C arch/$(TARGET_ARCH) clean
    14.9  	rm -f include/asm *.o $(TARGET)* *~ core
   14.10  	rm -f include/asm-*/asm-offsets.h
   14.11 @@ -58,6 +59,7 @@ clean: delete-unfresh-files
   14.12  	$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
   14.13  	$(MAKE) -C common
   14.14  	$(MAKE) -C drivers
   14.15 +	$(MAKE) -C acm
   14.16  	$(MAKE) -C arch/$(TARGET_ARCH)
   14.17  
   14.18  # drivers/char/console.o may contain static banner/compile info. Blow it away.
   14.19 @@ -109,7 +111,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
   14.20  
   14.21  .PHONY: default debug install dist clean delete-unfresh-files TAGS tags
   14.22  
   14.23 -SUBDIRS = arch/$(TARGET_ARCH) common drivers 
   14.24 +SUBDIRS = acm arch/$(TARGET_ARCH) common drivers 
   14.25  define all_sources
   14.26      ( find include/asm-$(TARGET_ARCH) -name SCCS -prune -o -name '*.h' -print; \
   14.27        find include -type d -name SCCS -prune -o \( -name "asm-*" -o \
    15.1 --- a/xen/Rules.mk	Sun Jun 19 17:05:55 2005 +0000
    15.2 +++ b/xen/Rules.mk	Mon Jun 20 22:28:08 2005 +0000
    15.3 @@ -35,6 +35,7 @@ OBJS    += $(patsubst %.c,%.o,$(C_SRCS))
    15.4  ALL_OBJS := $(BASEDIR)/common/common.o
    15.5  ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
    15.6  ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
    15.7 +ALL_OBJS += $(BASEDIR)/acm/acm.o
    15.8  ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
    15.9  
   15.10  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/acm/Makefile	Mon Jun 20 22:28:08 2005 +0000
    16.3 @@ -0,0 +1,15 @@
    16.4 +
    16.5 +include $(BASEDIR)/Rules.mk
    16.6 +OBJS =  acm_core.o 
    16.7 +OBJS += acm_policy.o
    16.8 +OBJS += acm_simple_type_enforcement_hooks.o
    16.9 +OBJS += acm_chinesewall_hooks.o
   16.10 +OBJS += acm_null_hooks.o
   16.11 +
   16.12 +default: acm.o
   16.13 +
   16.14 +acm.o: $(OBJS)
   16.15 +	$(LD) $(LDFLAGS) -r -o acm.o $(OBJS)
   16.16 +
   16.17 +clean:
   16.18 +	rm -f *.o *~ core
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/acm/acm_chinesewall_hooks.c	Mon Jun 20 22:28:08 2005 +0000
    17.3 @@ -0,0 +1,503 @@
    17.4 +/****************************************************************
    17.5 + * acm_chinesewall_hooks.c
    17.6 + * 
    17.7 + * Copyright (C) 2005 IBM Corporation
    17.8 + *
    17.9 + * Author:
   17.10 + * Reiner Sailer <sailer@watson.ibm.com>
   17.11 + *
   17.12 + * Contributions:
   17.13 + * Stefan Berger <stefanb@watson.ibm.com>
   17.14 + *
   17.15 + * This program is free software; you can redistribute it and/or
   17.16 + * modify it under the terms of the GNU General Public License as
   17.17 + * published by the Free Software Foundation, version 2 of the
   17.18 + * License.
   17.19 + *
   17.20 + * sHype Chinese Wall Policy for Xen
   17.21 + *    This code implements the hooks that are called
   17.22 + *    throughout Xen operations and decides authorization
   17.23 + *    based on domain types and Chinese Wall conflict type 
   17.24 + *    sets. The CHWALL policy decides if a new domain can be started
   17.25 + *    based on the types of running domains and the type of the
   17.26 + *    new domain to be started. If the new domain's type is in
   17.27 + *    conflict with types of running domains, then this new domain
   17.28 + *    is not allowed to be created. A domain can have multiple types,
   17.29 + *    in which case all types of a new domain must be conflict-free
   17.30 + *    with all types of already running domains.
   17.31 + *
   17.32 + */
   17.33 +#include <xen/config.h>
   17.34 +#include <xen/errno.h>
   17.35 +#include <xen/types.h>
   17.36 +#include <xen/lib.h>
   17.37 +#include <xen/delay.h>
   17.38 +#include <xen/sched.h>
   17.39 +#include <public/acm.h>
   17.40 +#include <asm/atomic.h>
   17.41 +#include <acm/acm_core.h>
   17.42 +#include <acm/acm_hooks.h>
   17.43 +#include <acm/acm_endian.h>
   17.44 +
   17.45 +/* local cache structures for chinese wall policy */
   17.46 +struct chwall_binary_policy chwall_bin_pol;
   17.47 +
   17.48 +/*
   17.49 + * Initializing chinese wall policy (will be filled by policy partition
   17.50 + * using setpolicy command)
   17.51 + */
   17.52 +int acm_init_chwall_policy(void)
   17.53 +{
   17.54 +	/* minimal startup policy; policy write-locked already */
   17.55 +	chwall_bin_pol.max_types = 1;
   17.56 +	chwall_bin_pol.max_ssidrefs = 1;
   17.57 +	chwall_bin_pol.max_conflictsets = 1;
   17.58 +	chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
   17.59 +	chwall_bin_pol.conflict_sets = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
   17.60 +	chwall_bin_pol.running_types = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
   17.61 +	chwall_bin_pol.conflict_aggregate_set = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
   17.62 +	
   17.63 +	if ((chwall_bin_pol.conflict_sets == NULL) || (chwall_bin_pol.running_types == NULL) ||
   17.64 +	    (chwall_bin_pol.ssidrefs == NULL) || (chwall_bin_pol.conflict_aggregate_set == NULL))
   17.65 +		return ACM_INIT_SSID_ERROR;
   17.66 +
   17.67 +	/* initialize state */
   17.68 +	memset((void *)chwall_bin_pol.ssidrefs, 0, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t));
   17.69 +	memset((void *)chwall_bin_pol.conflict_sets, 0, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t));
   17.70 +	memset((void *)chwall_bin_pol.running_types, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));
   17.71 +	memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));	
   17.72 +	return ACM_OK;
   17.73 +}
   17.74 +
   17.75 +static int
   17.76 +chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
   17.77 +{
   17.78 +	struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
   17.79 +	traceprintk("%s.\n", __func__);
   17.80 +	if (chwall_ssidp == NULL)
   17.81 +		return ACM_INIT_SSID_ERROR;
   17.82 +	/* 
   17.83 +	 * depending on wheter chwall is primary or secondary, get the respective
   17.84 +	 * part of the global ssidref (same way we'll get the partial ssid pointer)
   17.85 +	 */
   17.86 +	chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
   17.87 +	if (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
   17.88 +		printkd("%s: ERROR chwall_ssidref(%x) > max(%x).\n",
   17.89 +			__func__, chwall_ssidp->chwall_ssidref, chwall_bin_pol.max_ssidrefs-1);
   17.90 +		xfree(chwall_ssidp);
   17.91 +		return ACM_INIT_SSID_ERROR;
   17.92 +	}
   17.93 +	(*chwall_ssid) = chwall_ssidp;
   17.94 +	printkd("%s: determined chwall_ssidref to %x.\n", 
   17.95 +	       __func__, chwall_ssidp->chwall_ssidref);
   17.96 +	return ACM_OK;
   17.97 +}
   17.98 +
   17.99 +static void
  17.100 +chwall_free_domain_ssid(void *chwall_ssid)
  17.101 +{
  17.102 +	traceprintk("%s.\n", __func__);
  17.103 +	if (chwall_ssid != NULL)
  17.104 +		xfree(chwall_ssid);
  17.105 +	return;
  17.106 +}
  17.107 +
  17.108 +
  17.109 +/* dump chinese wall cache; policy read-locked already */
  17.110 +static int
  17.111 +chwall_dump_policy(u8 *buf, u16 buf_size) {	
  17.112 +     struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf;
  17.113 +     int ret = 0;
  17.114 +
  17.115 +     chwall_buf->chwall_max_types = htons(chwall_bin_pol.max_types);
  17.116 +     chwall_buf->chwall_max_ssidrefs = htons(chwall_bin_pol.max_ssidrefs);
  17.117 +     chwall_buf->policy_code = htons(ACM_CHINESE_WALL_POLICY);
  17.118 +     chwall_buf->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer));
  17.119 +     chwall_buf->chwall_max_conflictsets = htons(chwall_bin_pol.max_conflictsets);
  17.120 +     chwall_buf->chwall_conflict_sets_offset =
  17.121 +	     htons(
  17.122 +		   ntohs(chwall_buf->chwall_ssid_offset) + 
  17.123 +		   sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * 
  17.124 +		   chwall_bin_pol.max_types);
  17.125 +
  17.126 +     chwall_buf->chwall_running_types_offset = 
  17.127 +	     htons(
  17.128 +		   ntohs(chwall_buf->chwall_conflict_sets_offset) +
  17.129 +		   sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets *
  17.130 +		   chwall_bin_pol.max_types);
  17.131 +
  17.132 +     chwall_buf->chwall_conflict_aggregate_offset =
  17.133 +	     htons(
  17.134 +		   ntohs(chwall_buf->chwall_running_types_offset) +
  17.135 +		   sizeof(domaintype_t) * chwall_bin_pol.max_types);
  17.136 +
  17.137 +     ret = ntohs(chwall_buf->chwall_conflict_aggregate_offset) +
  17.138 +	     sizeof(domaintype_t) * chwall_bin_pol.max_types;
  17.139 +
  17.140 +     /* now copy buffers over */
  17.141 +     arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_ssid_offset)),
  17.142 +	      chwall_bin_pol.ssidrefs,
  17.143 +	      chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
  17.144 +
  17.145 +     arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_sets_offset)),
  17.146 +	      chwall_bin_pol.conflict_sets,
  17.147 +	      chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
  17.148 +
  17.149 +     arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_running_types_offset)),
  17.150 +	      chwall_bin_pol.running_types,
  17.151 +	      chwall_bin_pol.max_types);
  17.152 +
  17.153 +     arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_aggregate_offset)),
  17.154 +	      chwall_bin_pol.conflict_aggregate_set,
  17.155 +	      chwall_bin_pol.max_types);
  17.156 +     return ret;
  17.157 +}
  17.158 +
  17.159 +/* adapt security state (running_types and conflict_aggregate_set) to all running
  17.160 + * domains; chwall_init_state is called when a policy is changed to bring the security
  17.161 + * information into a consistent state and to detect violations (return != 0).
  17.162 + * from a security point of view, we simulate that all running domains are re-started
  17.163 + */ 
  17.164 +static int
  17.165 +chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets,
  17.166 +		  domaintype_t *running_types, domaintype_t *conflict_aggregate_set)
  17.167 +{
  17.168 +	int violation = 0, i, j;
  17.169 +	struct chwall_ssid *chwall_ssid;
  17.170 +	ssidref_t chwall_ssidref;
  17.171 +	struct domain **pd;
  17.172 +
  17.173 +        write_lock(&domlist_lock);
  17.174 +	/* go through all domains and adjust policy as if this domain was started now */
  17.175 +        pd = &domain_list;
  17.176 +        for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  17.177 +		chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)(*pd)->ssid);
  17.178 +		chwall_ssidref = chwall_ssid->chwall_ssidref;
  17.179 +		traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", 
  17.180 +			__func__, (*pd)->domain_id, chwall_ssidref);
  17.181 +		/* a) adjust types ref-count for running domains */
  17.182 +		for (i=0; i< chwall_buf->chwall_max_types; i++)
  17.183 +			running_types[i] +=
  17.184 +				ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i];
  17.185 +
  17.186 +		/* b) check for conflict */
  17.187 +		for (i=0; i< chwall_buf->chwall_max_types; i++)
  17.188 +			if (conflict_aggregate_set[i] && 
  17.189 +			    ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) {
  17.190 +				printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
  17.191 +				violation = 1;
  17.192 +				goto out;
  17.193 +			}
  17.194 +		/* set violation and break out of the loop */
  17.195 +		/* c) adapt conflict aggregate set for this domain (notice conflicts) */
  17.196 +		for (i=0; i<chwall_buf->chwall_max_conflictsets; i++) {
  17.197 +			int common = 0;
  17.198 +			/* check if conflict_set_i and ssidref have common types */
  17.199 +			for (j=0; j<chwall_buf->chwall_max_types; j++)
  17.200 +				if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
  17.201 +				    ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) {
  17.202 +					common = 1;
  17.203 +					break;
  17.204 +				}
  17.205 +			if (common == 0)
  17.206 +				continue; /* try next conflict set */
  17.207 +			/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  17.208 +			for (j=0; j<chwall_buf->chwall_max_types; j++)
  17.209 +				if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
  17.210 +				    !ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j])
  17.211 +					conflict_aggregate_set[j]++;
  17.212 +		}	
  17.213 +	}
  17.214 + out:
  17.215 +        write_unlock(&domlist_lock);
  17.216 +	return violation;
  17.217 +	/* returning "violation != 0" means that the currently running set of domains would 
  17.218 +	 * not be possible if the new policy had been enforced before starting them; for chinese
  17.219 +	 * wall, this means that the new policy includes at least one conflict set of which 
  17.220 +	 * more than one type is currently running */
  17.221 +}
  17.222 +
  17.223 +static int
  17.224 +chwall_set_policy(u8 *buf, u16 buf_size) 
  17.225 +{	
  17.226 +	/* policy write-locked already */
  17.227 +	struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf;
  17.228 +	void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL;	
  17.229 +
  17.230 +        /* rewrite the policy due to endianess */
  17.231 +        chwall_buf->policy_code                      = ntohs(chwall_buf->policy_code);
  17.232 +        chwall_buf->chwall_max_types                 = ntohs(chwall_buf->chwall_max_types);
  17.233 +        chwall_buf->chwall_max_ssidrefs              = ntohs(chwall_buf->chwall_max_ssidrefs);
  17.234 +        chwall_buf->chwall_max_conflictsets          = ntohs(chwall_buf->chwall_max_conflictsets);
  17.235 +        chwall_buf->chwall_ssid_offset               = ntohs(chwall_buf->chwall_ssid_offset);
  17.236 +        chwall_buf->chwall_conflict_sets_offset      = ntohs(chwall_buf->chwall_conflict_sets_offset);
  17.237 +        chwall_buf->chwall_running_types_offset      = ntohs(chwall_buf->chwall_running_types_offset);
  17.238 +        chwall_buf->chwall_conflict_aggregate_offset = ntohs(chwall_buf->chwall_conflict_aggregate_offset);
  17.239 +
  17.240 +	/* 1. allocate new buffers */
  17.241 +	ssids = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
  17.242 +	conflict_sets = xmalloc_array(domaintype_t, chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types);
  17.243 +	running_types = xmalloc_array(domaintype_t,chwall_buf->chwall_max_types);
  17.244 +	conflict_aggregate_set = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
  17.245 +
  17.246 +	if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == NULL)||(conflict_aggregate_set == NULL))
  17.247 +		goto error_free;
  17.248 +
  17.249 +	/* 2. set new policy */
  17.250 +	if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * 
  17.251 +	    chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > buf_size)
  17.252 +		goto error_free;
  17.253 +	arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
  17.254 +	       sizeof(domaintype_t),  
  17.255 +	       chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
  17.256 +
  17.257 +	if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * 
  17.258 +	    chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets > buf_size)
  17.259 +		goto error_free;
  17.260 +
  17.261 +	arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
  17.262 +	       sizeof(domaintype_t),
  17.263 +	       chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets);
  17.264 +
  17.265 +	/* we also use new state buffers since max_types can change */
  17.266 +	memset(running_types, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
  17.267 +	memset(conflict_aggregate_set, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
  17.268 +
  17.269 +	/* 3. now re-calculate the state for the new policy based on running domains; 
  17.270 +	 *    this can fail if new policy is conflicting with running domains */
  17.271 +	if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set)) {
  17.272 +		printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
  17.273 +		goto error_free; /* new policy conflicts with running domains */
  17.274 +	}
  17.275 +	/* 4. free old policy buffers, replace with new ones */
  17.276 +	chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
  17.277 +	chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
  17.278 +	chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
  17.279 +	if (chwall_bin_pol.ssidrefs != NULL) 
  17.280 +		xfree(chwall_bin_pol.ssidrefs);
  17.281 +	if (chwall_bin_pol.conflict_aggregate_set != NULL) 
  17.282 +		xfree(chwall_bin_pol.conflict_aggregate_set);
  17.283 +	if (chwall_bin_pol.running_types != NULL) 
  17.284 +		xfree(chwall_bin_pol.running_types);
  17.285 +	if (chwall_bin_pol.conflict_sets != NULL) 
  17.286 +		xfree(chwall_bin_pol.conflict_sets);
  17.287 +	chwall_bin_pol.ssidrefs = ssids;
  17.288 +	chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
  17.289 +	chwall_bin_pol.running_types = running_types;
  17.290 +	chwall_bin_pol.conflict_sets = conflict_sets;
  17.291 +	return ACM_OK;
  17.292 +
  17.293 +error_free:
  17.294 +	printk("%s: ERROR setting policy.\n", __func__);
  17.295 +	if (ssids != NULL) xfree(ssids);
  17.296 +	if (conflict_sets != NULL) xfree(conflict_sets);
  17.297 +	if (running_types != NULL) xfree(running_types);
  17.298 +	if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set);
  17.299 +	return -EFAULT;
  17.300 +}
  17.301 +	
  17.302 +static int 
  17.303 +chwall_dump_stats(u8 *buf, u16 len)
  17.304 +{
  17.305 +	/* no stats for Chinese Wall Policy */
  17.306 +	return 0;
  17.307 +}
  17.308 +
  17.309 +/***************************
  17.310 + * Authorization functions
  17.311 + ***************************/
  17.312 +
  17.313 +
  17.314 +/* -------- DOMAIN OPERATION HOOKS -----------*/
  17.315 +
  17.316 +static int 
  17.317 +chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
  17.318 +{
  17.319 +	ssidref_t chwall_ssidref;
  17.320 +	int i,j;
  17.321 +	traceprintk("%s.\n", __func__);
  17.322 +
  17.323 +	read_lock(&acm_bin_pol_rwlock);
  17.324 +	chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  17.325 +	if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) {
  17.326 +		printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", __func__);
  17.327 +		read_unlock(&acm_bin_pol_rwlock);
  17.328 +		return ACM_ACCESS_DENIED; /* catching and indicating config error */
  17.329 +	}
  17.330 +	if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
  17.331 +		printk("%s: ERROR chwall_ssidref > max(%x).\n",
  17.332 +		       __func__, chwall_bin_pol.max_ssidrefs-1);
  17.333 +		read_unlock(&acm_bin_pol_rwlock);
  17.334 +		return ACM_ACCESS_DENIED;
  17.335 +	}
  17.336 +	/* A: chinese wall check for conflicts */
  17.337 +	for (i=0; i< chwall_bin_pol.max_types; i++)
  17.338 +		if (chwall_bin_pol.conflict_aggregate_set[i] && 
  17.339 +		    chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) {
  17.340 +			printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
  17.341 +			read_unlock(&acm_bin_pol_rwlock);
  17.342 +		        return ACM_ACCESS_DENIED;
  17.343 +		}
  17.344 +
  17.345 +	/* B: chinese wall conflict set adjustment (so that other 
  17.346 +	 *	other domains simultaneously created are evaluated against this new set)*/
  17.347 +	for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
  17.348 +		int common = 0;
  17.349 +		/* check if conflict_set_i and ssidref have common types */
  17.350 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.351 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.352 +			    chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
  17.353 +				common = 1;
  17.354 +				break;
  17.355 +			}
  17.356 +		if (common == 0)
  17.357 +			continue; /* try next conflict set */
  17.358 +		/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  17.359 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.360 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.361 +			    !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
  17.362 +				chwall_bin_pol.conflict_aggregate_set[j]++;
  17.363 +	}
  17.364 +	read_unlock(&acm_bin_pol_rwlock);
  17.365 +	return ACM_ACCESS_PERMITTED;
  17.366 +}
  17.367 +
  17.368 +static void
  17.369 +chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
  17.370 +{
  17.371 +	int i,j;
  17.372 +	ssidref_t chwall_ssidref;
  17.373 +	traceprintk("%s.\n", __func__);
  17.374 +	
  17.375 +	read_lock(&acm_bin_pol_rwlock);
  17.376 +	chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  17.377 +	/* adjust types ref-count for running domains */
  17.378 +	for (i=0; i< chwall_bin_pol.max_types; i++)
  17.379 +		chwall_bin_pol.running_types[i] +=
  17.380 +			chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
  17.381 +	if (domid) {
  17.382 +		read_unlock(&acm_bin_pol_rwlock);
  17.383 +		return;
  17.384 +	}
  17.385 +	/* Xen does not call pre-create hook for DOM0;
  17.386 +	 * to consider type conflicts of any domain with DOM0, we need
  17.387 +	 * to adjust the conflict_aggregate for DOM0 here the same way it
  17.388 +	 * is done for non-DOM0 domains in the pre-hook */
  17.389 +	printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n", 
  17.390 +		__func__, ssidref, chwall_ssidref);
  17.391 +
  17.392 +	/* chinese wall conflict set adjustment (so that other 
  17.393 +	 *	other domains simultaneously created are evaluated against this new set)*/
  17.394 +	for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
  17.395 +		int common = 0;
  17.396 +		/* check if conflict_set_i and ssidref have common types */
  17.397 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.398 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.399 +			    chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
  17.400 +				common = 1;
  17.401 +				break;
  17.402 +			}
  17.403 +		if (common == 0)
  17.404 +			continue; /* try next conflict set */
  17.405 +		/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  17.406 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.407 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.408 +			    !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
  17.409 +				chwall_bin_pol.conflict_aggregate_set[j]++;
  17.410 +	}
  17.411 +	read_unlock(&acm_bin_pol_rwlock);
  17.412 +	return;
  17.413 +}
  17.414 +
  17.415 +static void
  17.416 +chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
  17.417 +{
  17.418 +	int i, j;
  17.419 +	ssidref_t chwall_ssidref;
  17.420 +	traceprintk("%s.\n", __func__);
  17.421 +
  17.422 +	read_lock(&acm_bin_pol_rwlock);
  17.423 +	chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
  17.424 +	/* roll-back: re-adjust conflicting types aggregate */
  17.425 +	for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
  17.426 +		int common = 0;
  17.427 +		/* check if conflict_set_i and ssidref have common types */
  17.428 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.429 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.430 +			    chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
  17.431 +				common = 1;
  17.432 +				break;
  17.433 +			}
  17.434 +		if (common == 0)
  17.435 +			continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
  17.436 +		/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  17.437 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.438 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.439 +			    !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
  17.440 +				chwall_bin_pol.conflict_aggregate_set[j]--;
  17.441 +	}
  17.442 +	read_unlock(&acm_bin_pol_rwlock);
  17.443 +}
  17.444 +
  17.445 +
  17.446 +static void
  17.447 +chwall_post_domain_destroy(void *object_ssid, domid_t id) 
  17.448 +{
  17.449 +	int i,j;
  17.450 +	struct chwall_ssid *chwall_ssidp = 
  17.451 +		GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)object_ssid);
  17.452 +	ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
  17.453 +
  17.454 +	traceprintk("%s.\n", __func__);
  17.455 +
  17.456 +	read_lock(&acm_bin_pol_rwlock);
  17.457 +	/* adjust running types set */
  17.458 +	for (i=0; i< chwall_bin_pol.max_types; i++)
  17.459 +		chwall_bin_pol.running_types[i] -=
  17.460 +			chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
  17.461 +
  17.462 +	/* roll-back: re-adjust conflicting types aggregate */
  17.463 +	for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
  17.464 +		int common = 0;
  17.465 +		/* check if conflict_set_i and ssidref have common types */
  17.466 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.467 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.468 +			    chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
  17.469 +				common = 1;
  17.470 +				break;
  17.471 +			}
  17.472 +		if (common == 0)
  17.473 +			continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
  17.474 +		/* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
  17.475 +		for (j=0; j<chwall_bin_pol.max_types; j++)
  17.476 +			if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
  17.477 +			    !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
  17.478 +				chwall_bin_pol.conflict_aggregate_set[j]--;
  17.479 +	}
  17.480 +	read_unlock(&acm_bin_pol_rwlock);
  17.481 +	return;
  17.482 +}
  17.483 +
  17.484 +struct acm_operations acm_chinesewall_ops = {
  17.485 +	/* policy management services */
  17.486 +	.init_domain_ssid		= chwall_init_domain_ssid,
  17.487 +	.free_domain_ssid		= chwall_free_domain_ssid,
  17.488 +	.dump_binary_policy		= chwall_dump_policy,
  17.489 +	.set_binary_policy		= chwall_set_policy,
  17.490 +	.dump_statistics		= chwall_dump_stats,
  17.491 +	/* domain management control hooks */
  17.492 +	.pre_domain_create     		= chwall_pre_domain_create,
  17.493 +	.post_domain_create		= chwall_post_domain_create,
  17.494 +	.fail_domain_create		= chwall_fail_domain_create,
  17.495 +	.post_domain_destroy		= chwall_post_domain_destroy,
  17.496 +	/* event channel control hooks */
  17.497 +	.pre_eventchannel_unbound      	= NULL,
  17.498 +	.fail_eventchannel_unbound	= NULL,
  17.499 +	.pre_eventchannel_interdomain	= NULL,
  17.500 +	.fail_eventchannel_interdomain  = NULL,
  17.501 +	/* grant table control hooks */
  17.502 +	.pre_grant_map_ref       	= NULL,
  17.503 +	.fail_grant_map_ref		= NULL,
  17.504 +	.pre_grant_setup	       	= NULL,
  17.505 +	.fail_grant_setup		= NULL,
  17.506 +};
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/xen/acm/acm_core.c	Mon Jun 20 22:28:08 2005 +0000
    18.3 @@ -0,0 +1,205 @@
    18.4 +/****************************************************************
    18.5 + * acm_core.c
    18.6 + * 
    18.7 + * Copyright (C) 2005 IBM Corporation
    18.8 + *
    18.9 + * Author:
   18.10 + * Reiner Sailer <sailer@watson.ibm.com>
   18.11 + *
   18.12 + * This program is free software; you can redistribute it and/or
   18.13 + * modify it under the terms of the GNU General Public License as
   18.14 + * published by the Free Software Foundation, version 2 of the
   18.15 + * License.
   18.16 + *
   18.17 + * sHype access control module (ACM)
   18.18 + *       This file handles initialization of the ACM
   18.19 + *       as well as initializing/freeing security 
   18.20 + *       identifiers for domains (it calls on active
   18.21 + *       policy hook functions).
   18.22 + *
   18.23 + */
   18.24 +
   18.25 +#include <xen/config.h>
   18.26 +#include <xen/errno.h>
   18.27 +#include <xen/types.h>
   18.28 +#include <xen/lib.h>
   18.29 +#include <xen/delay.h>
   18.30 +#include <xen/sched.h>
   18.31 +#include <acm/acm_hooks.h>
   18.32 +#include <acm/acm_endian.h>
   18.33 +
   18.34 +/* debug: 
   18.35 + *   include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
   18.36 + *   define/undefine this constant to receive / suppress any
   18.37 + *   security hook debug output of sHype
   18.38 + *
   18.39 + *   include/public/acm.h defines a constant ACM_DEBUG
   18.40 + *   define/undefine this constant to receive non-hook-related
   18.41 + *   debug output.
   18.42 + */
   18.43 +
   18.44 +/* function prototypes */
   18.45 +void acm_init_chwall_policy(void);
   18.46 +void acm_init_ste_policy(void);
   18.47 +
   18.48 +extern struct acm_operations acm_chinesewall_ops, 
   18.49 +	acm_simple_type_enforcement_ops, acm_null_ops;
   18.50 +
   18.51 +/* global ops structs called by the hooks */
   18.52 +struct acm_operations *acm_primary_ops = NULL;
   18.53 +/* called in hook if-and-only-if primary succeeds */
   18.54 +struct acm_operations *acm_secondary_ops = NULL;
   18.55 +
   18.56 +/* acm global binary policy (points to 'local' primary and secondary policies */
   18.57 +struct acm_binary_policy acm_bin_pol;
   18.58 +/* acm binary policy lock */
   18.59 +rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
   18.60 +
   18.61 +/* until we have endian support in Xen, we discover it at runtime */
   18.62 +u8 little_endian = 1;
   18.63 +void acm_set_endian(void)
   18.64 +{
   18.65 +    u32 test = 1;
   18.66 +    if (*((u8 *)&test) == 1) {
   18.67 +      	printk("ACM module running in LITTLE ENDIAN.\n");
   18.68 +	little_endian = 1;
   18.69 +    } else {
   18.70 +	printk("ACM module running in BIG ENDIAN.\n");
   18.71 +	little_endian = 0;
   18.72 +    }
   18.73 +}
   18.74 +
   18.75 +/* initialize global security policy for Xen; policy write-locked already */
   18.76 +static void
   18.77 +acm_init_binary_policy(void *primary, void *secondary)
   18.78 +{
   18.79 +	acm_bin_pol.primary_policy_code = 0;
   18.80 +	acm_bin_pol.secondary_policy_code = 0;
   18.81 +	acm_bin_pol.primary_binary_policy = primary;
   18.82 +	acm_bin_pol.secondary_binary_policy = secondary;
   18.83 +}
   18.84 +
   18.85 +int
   18.86 +acm_init(void)
   18.87 +{
   18.88 +	int ret = -EINVAL;
   18.89 +
   18.90 +	acm_set_endian();
   18.91 +	write_lock(&acm_bin_pol_rwlock);
   18.92 +
   18.93 +	if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
   18.94 +		acm_init_binary_policy(NULL, NULL);
   18.95 +		acm_init_chwall_policy();
   18.96 +		acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
   18.97 +		acm_primary_ops = &acm_chinesewall_ops;
   18.98 +		acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
   18.99 +		acm_secondary_ops = &acm_null_ops;
  18.100 +		ret = ACM_OK;
  18.101 +	} else if (ACM_USE_SECURITY_POLICY == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
  18.102 +		acm_init_binary_policy(NULL, NULL);
  18.103 +		acm_init_ste_policy();
  18.104 +		acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
  18.105 +		acm_primary_ops = &acm_simple_type_enforcement_ops;
  18.106 +		acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
  18.107 +		acm_secondary_ops = &acm_null_ops;
  18.108 +		ret = ACM_OK;
  18.109 +	} else if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
  18.110 +		acm_init_binary_policy(NULL, NULL);
  18.111 +		acm_init_chwall_policy();
  18.112 +		acm_init_ste_policy();
  18.113 +		acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
  18.114 +		acm_primary_ops = &acm_chinesewall_ops;
  18.115 +		acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
  18.116 +		acm_secondary_ops = &acm_simple_type_enforcement_ops;
  18.117 +		ret = ACM_OK;
  18.118 +	} else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
  18.119 +		acm_init_binary_policy(NULL, NULL);
  18.120 +		acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
  18.121 +		acm_primary_ops = &acm_null_ops;
  18.122 +		acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
  18.123 +		acm_secondary_ops = &acm_null_ops;
  18.124 +		ret = ACM_OK;
  18.125 +	}
  18.126 +	write_unlock(&acm_bin_pol_rwlock);
  18.127 +
  18.128 +	if (ret != ACM_OK)
  18.129 +		return -EINVAL;		
  18.130 +	printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, 
  18.131 +	       ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
  18.132 +	return ACM_OK;
  18.133 +}
  18.134 +
  18.135 +
  18.136 +int
  18.137 +acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
  18.138 +{
  18.139 +	struct acm_ssid_domain *ssid;
  18.140 +	struct domain *subj = find_domain_by_id(id);
  18.141 +	int ret1, ret2;
  18.142 +	
  18.143 +	if (subj == NULL) {
  18.144 +		printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
  18.145 +		return ACM_NULL_POINTER_ERROR;
  18.146 +	}
  18.147 +	if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL)
  18.148 +		return ACM_INIT_SSID_ERROR;
  18.149 +
  18.150 +	ssid->datatype       = DOMAIN;
  18.151 +	ssid->subject  	     = subj;
  18.152 +	ssid->domainid	     = subj->domain_id;
  18.153 +	ssid->primary_ssid   = NULL;
  18.154 +	ssid->secondary_ssid = NULL;
  18.155 +
  18.156 +	if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
  18.157 +		ssid->ssidref = ssidref;
  18.158 +	else
  18.159 +		ssid->ssidref = ACM_DEFAULT_SSID;
  18.160 +
  18.161 +	subj->ssid           = ssid;
  18.162 +	/* now fill in primary and secondary parts; we only get here through hooks */
  18.163 +	if (acm_primary_ops->init_domain_ssid != NULL)
  18.164 +		ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
  18.165 +	else
  18.166 +		ret1 = ACM_OK;
  18.167 +
  18.168 +	if (acm_secondary_ops->init_domain_ssid != NULL)
  18.169 +		ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
  18.170 +	else
  18.171 +		ret2 = ACM_OK;
  18.172 +
  18.173 +	if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
  18.174 +		printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
  18.175 +		       __func__, subj->domain_id);
  18.176 +		acm_free_domain_ssid(ssid);	
  18.177 +	        put_domain(subj);
  18.178 +		return ACM_INIT_SSID_ERROR;
  18.179 +	}
  18.180 +	printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref);
  18.181 +	put_domain(subj);
  18.182 +	return ACM_OK;
  18.183 +}
  18.184 +
  18.185 +
  18.186 +int
  18.187 +acm_free_domain_ssid(struct acm_ssid_domain *ssid)
  18.188 +{
  18.189 +	domid_t id;
  18.190 +
  18.191 +	/* domain is already gone, just ssid is left */
  18.192 +	if (ssid == NULL) {
  18.193 +		printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
  18.194 +		return ACM_NULL_POINTER_ERROR;
  18.195 +	}
  18.196 +       	id = ssid->domainid;
  18.197 +	ssid->subject  	     = NULL;
  18.198 +
  18.199 +	if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
  18.200 +		acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
  18.201 +	ssid->primary_ssid = NULL;
  18.202 +	if (acm_secondary_ops->free_domain_ssid != NULL)
  18.203 +		acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
  18.204 +	ssid->secondary_ssid = NULL;
  18.205 +	xfree(ssid);
  18.206 +	printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, id);
  18.207 +	return ACM_OK;
  18.208 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/xen/acm/acm_null_hooks.c	Mon Jun 20 22:28:08 2005 +0000
    19.3 @@ -0,0 +1,76 @@
    19.4 +/****************************************************************
    19.5 + * acm_null_hooks.c
    19.6 + * 
    19.7 + * Copyright (C) 2005 IBM Corporation
    19.8 + *
    19.9 + * Author:
   19.10 + * Reiner Sailer <sailer@watson.ibm.com>
   19.11 + *
   19.12 + * This program is free software; you can redistribute it and/or
   19.13 + * modify it under the terms of the GNU General Public License as
   19.14 + * published by the Free Software Foundation, version 2 of the
   19.15 + * License.
   19.16 + */
   19.17 +#include <acm/acm_hooks.h>
   19.18 +
   19.19 +static int
   19.20 +null_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
   19.21 +{
   19.22 +	return ACM_OK;
   19.23 +}
   19.24 +
   19.25 +
   19.26 +static void
   19.27 +null_free_domain_ssid(void *chwall_ssid)
   19.28 +{
   19.29 +	return;
   19.30 +}
   19.31 +
   19.32 +
   19.33 +static int
   19.34 +null_dump_binary_policy(u8 *buf, u16 buf_size) 
   19.35 +{	
   19.36 +	return 0;
   19.37 +}
   19.38 +
   19.39 +
   19.40 +
   19.41 +static int
   19.42 +null_set_binary_policy(u8 *buf, u16 buf_size) 
   19.43 +{	
   19.44 +	return -1;
   19.45 +}
   19.46 +
   19.47 +	
   19.48 +static int 
   19.49 +null_dump_stats(u8 *buf, u16 buf_size)
   19.50 +{
   19.51 +	/* no stats for NULL policy */
   19.52 +	return 0;
   19.53 +}
   19.54 +
   19.55 +
   19.56 +/* now define the hook structure similarly to LSM */
   19.57 +struct acm_operations acm_null_ops = {
   19.58 +	.init_domain_ssid		= null_init_domain_ssid,
   19.59 +	.free_domain_ssid		= null_free_domain_ssid,
   19.60 +	.dump_binary_policy           	= null_dump_binary_policy,
   19.61 +	.set_binary_policy		= null_set_binary_policy,
   19.62 +	.dump_statistics	        = null_dump_stats,
   19.63 +	/* domain management control hooks */
   19.64 +	.pre_domain_create     		= NULL,
   19.65 +	.post_domain_create		= NULL,
   19.66 +	.fail_domain_create		= NULL,
   19.67 +	.post_domain_destroy		= NULL,
   19.68 +	/* event channel control hooks */
   19.69 +	.pre_eventchannel_unbound      	= NULL,
   19.70 +	.fail_eventchannel_unbound	= NULL,
   19.71 +	.pre_eventchannel_interdomain	= NULL,
   19.72 +	.fail_eventchannel_interdomain	= NULL,
   19.73 +	/* grant table control hooks */
   19.74 +	.pre_grant_map_ref       	= NULL,
   19.75 +	.fail_grant_map_ref		= NULL,
   19.76 +	.pre_grant_setup	       	= NULL,
   19.77 +	.fail_grant_setup		= NULL
   19.78 +
   19.79 +};
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/xen/acm/acm_policy.c	Mon Jun 20 22:28:08 2005 +0000
    20.3 @@ -0,0 +1,197 @@
    20.4 +/****************************************************************
    20.5 + * acm_policy.c
    20.6 + * 
    20.7 + * Copyright (C) 2005 IBM Corporation
    20.8 + *
    20.9 + * Author:
   20.10 + * Reiner Sailer <sailer@watson.ibm.com>
   20.11 + *
   20.12 + * Contributions:
   20.13 + * Stefan Berger <stefanb@watson.ibm.com>
   20.14 + *	support for network-byte-order binary policies
   20.15 + *
   20.16 + * This program is free software; you can redistribute it and/or
   20.17 + * modify it under the terms of the GNU General Public License as
   20.18 + * published by the Free Software Foundation, version 2 of the
   20.19 + * License.
   20.20 + *
   20.21 + * sHype access control policy management for Xen.
   20.22 + *       This interface allows policy tools in authorized
   20.23 + *       domains to interact with the Xen access control module
   20.24 + * 
   20.25 + */
   20.26 +
   20.27 +#include <xen/config.h>
   20.28 +#include <xen/errno.h>
   20.29 +#include <xen/types.h>
   20.30 +#include <xen/lib.h>
   20.31 +#include <xen/delay.h>
   20.32 +#include <xen/sched.h>
   20.33 +#include <public/policy_ops.h>
   20.34 +#include <acm/acm_core.h>
   20.35 +#include <acm/acm_hooks.h>
   20.36 +#include <acm/acm_endian.h>
   20.37 +
   20.38 +int
   20.39 +acm_set_policy(void *buf, u16 buf_size, u16 policy)
   20.40 +{
   20.41 +	u8 *policy_buffer = NULL;
   20.42 +	struct acm_policy_buffer *pol;
   20.43 +	
   20.44 +	if (policy != ACM_USE_SECURITY_POLICY) {
   20.45 +		printk("%s: Loading incompatible policy (running: %s).\n", __func__,
   20.46 +		       ACM_POLICY_NAME(ACM_USE_SECURITY_POLICY));
   20.47 +		return -EFAULT;
   20.48 +	}
   20.49 +	/* now check correct buffer sizes for policy combinations */
   20.50 +	if (policy == ACM_NULL_POLICY) {
   20.51 +		printkd("%s: NULL Policy, no policy needed.\n", __func__);
   20.52 +		goto out;
   20.53 +	}
   20.54 +     	if (buf_size < sizeof(struct acm_policy_buffer))
   20.55 +		return -EFAULT;
   20.56 +	/* 1. copy buffer from domain */
   20.57 +	if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
   20.58 +	    goto error_free;
   20.59 +        if (copy_from_user(policy_buffer, buf, buf_size)) {
   20.60 +		printk("%s: Error copying!\n",__func__);
   20.61 +		goto error_free;
   20.62 +	}
   20.63 +	/* 2. some sanity checking */
   20.64 +	pol = (struct acm_policy_buffer *)policy_buffer;
   20.65 +
   20.66 +	if ((ntohl(pol->magic) != ACM_MAGIC) || 
   20.67 +	    (ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
   20.68 +	    (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) {
   20.69 +		printkd("%s: Wrong policy magics!\n", __func__);
   20.70 +		goto error_free;
   20.71 +	}
   20.72 +	if (buf_size != ntohl(pol->len)) {
   20.73 +		printk("%s: ERROR in buf size.\n", __func__);
   20.74 +		goto error_free;
   20.75 +	}
   20.76 +
   20.77 +	/* get bin_policy lock and rewrite policy (release old one) */
   20.78 +	write_lock(&acm_bin_pol_rwlock);
   20.79 +
   20.80 +	/* 3. now get/set primary policy data */
   20.81 +	if (acm_primary_ops->set_binary_policy(buf + ntohs(pol->primary_buffer_offset), 
   20.82 +                                               ntohs(pol->secondary_buffer_offset) -
   20.83 +					       ntohs(pol->primary_buffer_offset))) {
   20.84 +		goto error_lock_free;
   20.85 +	}
   20.86 +	/* 4. now get/set secondary policy data */
   20.87 +	if (acm_secondary_ops->set_binary_policy(buf + ntohs(pol->secondary_buffer_offset),
   20.88 +						 ntohl(pol->len) - 
   20.89 +						 ntohs(pol->secondary_buffer_offset))) {
   20.90 +		goto error_lock_free;
   20.91 +	}
   20.92 +	write_unlock(&acm_bin_pol_rwlock);
   20.93 + out:
   20.94 +	printk("%s: Done .\n", __func__);
   20.95 +	if (policy_buffer != NULL)
   20.96 +		xfree(policy_buffer);
   20.97 +	return ACM_OK;
   20.98 +
   20.99 + error_lock_free:
  20.100 +	write_unlock(&acm_bin_pol_rwlock);
  20.101 + error_free:
  20.102 +	printk("%s: Error setting policy.\n", __func__);
  20.103 +	if (policy_buffer != NULL)
  20.104 +		xfree(policy_buffer);
  20.105 +	return -ENOMEM;
  20.106 +}
  20.107 +
  20.108 +int
  20.109 +acm_get_policy(void *buf, u16 buf_size)
  20.110 +{	
  20.111 +     u8 *policy_buffer;
  20.112 +     int ret;
  20.113 +     struct acm_policy_buffer *bin_pol;
  20.114 +	
  20.115 +     if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
  20.116 +	    return -ENOMEM;
  20.117 +
  20.118 +     read_lock(&acm_bin_pol_rwlock);
  20.119 +     /* future: read policy from file and set it */
  20.120 +     bin_pol = (struct acm_policy_buffer *)policy_buffer;
  20.121 +     bin_pol->magic = htonl(ACM_MAGIC);
  20.122 +     bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
  20.123 +     bin_pol->primary_policy_code = htons(acm_bin_pol.primary_policy_code);
  20.124 +     bin_pol->secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
  20.125 +
  20.126 +     bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
  20.127 +     bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
  20.128 +     bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
  20.129 +     
  20.130 +     ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohs(bin_pol->primary_buffer_offset),
  20.131 +				       buf_size - ntohs(bin_pol->primary_buffer_offset));
  20.132 +     if (ret < 0) {
  20.133 +	     printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
  20.134 +	     read_unlock(&acm_bin_pol_rwlock);
  20.135 +	     return -1;
  20.136 +     }
  20.137 +     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
  20.138 +     bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
  20.139 +
  20.140 +     ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohs(bin_pol->secondary_buffer_offset), 
  20.141 +				    buf_size - ntohs(bin_pol->secondary_buffer_offset));
  20.142 +     if (ret < 0) {
  20.143 +	     printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
  20.144 +	     read_unlock(&acm_bin_pol_rwlock);
  20.145 +	     return -1;
  20.146 +     }
  20.147 +     bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
  20.148 +     read_unlock(&acm_bin_pol_rwlock);
  20.149 +     if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
  20.150 +	     return -EFAULT;
  20.151 +     xfree(policy_buffer);
  20.152 +     return ACM_OK;
  20.153 +}
  20.154 +
  20.155 +int
  20.156 +acm_dump_statistics(void *buf, u16 buf_size)
  20.157 +{	
  20.158 +    /* send stats to user space */
  20.159 +     u8 *stats_buffer;
  20.160 +     int len1, len2;
  20.161 +     struct acm_stats_buffer acm_stats;
  20.162 +
  20.163 +     if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
  20.164 +	    return -ENOMEM;
  20.165 +
  20.166 +     read_lock(&acm_bin_pol_rwlock);
  20.167 +     
  20.168 +     len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
  20.169 +					     buf_size - sizeof(struct acm_stats_buffer));
  20.170 +     if (len1 < 0)
  20.171 +	     goto error_lock_free;
  20.172 +	     
  20.173 +     len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
  20.174 +					       buf_size - sizeof(struct acm_stats_buffer) - len1);
  20.175 +     if (len2 < 0)
  20.176 +	     goto error_lock_free;
  20.177 +
  20.178 +     acm_stats.magic = htonl(ACM_MAGIC);
  20.179 +     acm_stats.policyversion = htonl(POLICY_INTERFACE_VERSION);
  20.180 +     acm_stats.primary_policy_code = htons(acm_bin_pol.primary_policy_code);
  20.181 +     acm_stats.secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
  20.182 +     acm_stats.primary_stats_offset = htons(sizeof(struct acm_stats_buffer));
  20.183 +     acm_stats.secondary_stats_offset = htons(sizeof(struct acm_stats_buffer) + len1);
  20.184 +     acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
  20.185 +     memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
  20.186 +
  20.187 +     if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
  20.188 +	     goto error_lock_free;
  20.189 +
  20.190 +     read_unlock(&acm_bin_pol_rwlock);
  20.191 +     xfree(stats_buffer);
  20.192 +     return ACM_OK;
  20.193 +
  20.194 + error_lock_free:
  20.195 +     read_unlock(&acm_bin_pol_rwlock);
  20.196 +     xfree(stats_buffer);
  20.197 +     return -EFAULT;
  20.198 +}
  20.199 +
  20.200 +/*eof*/
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/xen/acm/acm_simple_type_enforcement_hooks.c	Mon Jun 20 22:28:08 2005 +0000
    21.3 @@ -0,0 +1,638 @@
    21.4 +/****************************************************************
    21.5 + * acm_simple_type_enforcement_hooks.c
    21.6 + * 
    21.7 + * Copyright (C) 2005 IBM Corporation
    21.8 + *
    21.9 + * Author:
   21.10 + * Reiner Sailer <sailer@watson.ibm.com>
   21.11 + *
   21.12 + * Contributors:
   21.13 + * Stefan Berger <stefanb@watson.ibm.com>
   21.14 + *         support for network order binary policies
   21.15 + *
   21.16 + * This program is free software; you can redistribute it and/or
   21.17 + * modify it under the terms of the GNU General Public License as
   21.18 + * published by the Free Software Foundation, version 2 of the
   21.19 + * License.
   21.20 + *
   21.21 + * sHype Simple Type Enforcement for Xen
   21.22 + *     STE allows to control which domains can setup sharing
   21.23 + *     (eventchannels right now) with which other domains. Hooks
   21.24 + *     are defined and called throughout Xen when domains bind to
   21.25 + *     shared resources (setup eventchannels) and a domain is allowed
   21.26 + *     to setup sharing with another domain if and only if both domains
   21.27 + *     share at least on common type.
   21.28 + *
   21.29 + */
   21.30 +#include <xen/lib.h>
   21.31 +#include <asm/types.h>
   21.32 +#include <asm/current.h>
   21.33 +#include <acm/acm_hooks.h>
   21.34 +#include <asm/atomic.h>
   21.35 +#include <acm/acm_endian.h>
   21.36 +
   21.37 +/* local cache structures for chinese wall policy */
   21.38 +struct ste_binary_policy ste_bin_pol;
   21.39 +
   21.40 +static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) {
   21.41 +	int i;
   21.42 +	for(i=0; i< ste_bin_pol.max_types; i++)
   21.43 +		if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && 
   21.44 +		     ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) {
   21.45 +			printkd("%s: common type #%02x.\n", __func__, i);
   21.46 +			return 1;
   21.47 +		}
   21.48 +	return 0;
   21.49 +}
   21.50 +
   21.51 +/* Helper function: return = (subj and obj share a common type) */
   21.52 +static int share_common_type(struct domain *subj, struct domain *obj)
   21.53 +{
   21.54 +	ssidref_t ref_s, ref_o;
   21.55 +	int ret;
   21.56 +
   21.57 +	if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL))
   21.58 +		return 0;
   21.59 +	read_lock(&acm_bin_pol_rwlock);
   21.60 +	/* lookup the policy-local ssids */
   21.61 +	ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   21.62 +				    (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref;
   21.63 +	ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
   21.64 +				    (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref;
   21.65 +        /* check whether subj and obj share a common ste type */
   21.66 +	ret = have_common_type(ref_s, ref_o);
   21.67 +	read_unlock(&acm_bin_pol_rwlock);
   21.68 +	return ret;
   21.69 +}
   21.70 +
   21.71 +/*
   21.72 + * Initializing chinese wall policy (will be filled by policy partition
   21.73 + * using setpolicy command)
   21.74 + */
   21.75 +int acm_init_ste_policy(void)
   21.76 +{
   21.77 +	/* minimal startup policy; policy write-locked already */
   21.78 +	ste_bin_pol.max_types = 1;
   21.79 +	ste_bin_pol.max_ssidrefs = 1;
   21.80 +	ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 1);
   21.81 +	
   21.82 +	if (ste_bin_pol.ssidrefs == NULL)
   21.83 +		return ACM_INIT_SSID_ERROR;
   21.84 +
   21.85 +	/* initialize state */
   21.86 +	ste_bin_pol.ssidrefs[0] = 1;
   21.87 +
   21.88 +	/* init stats */
   21.89 +	atomic_set(&(ste_bin_pol.ec_eval_count), 0);
   21.90 +	atomic_set(&(ste_bin_pol.ec_denied_count), 0); 
   21.91 +	atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
   21.92 +	atomic_set(&(ste_bin_pol.gt_eval_count), 0);
   21.93 +	atomic_set(&(ste_bin_pol.gt_denied_count), 0); 
   21.94 +	atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
   21.95 +	return ACM_OK;
   21.96 +}
   21.97 +
   21.98 +
   21.99 +/* ste initialization function hooks */
  21.100 +static int
  21.101 +ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
  21.102 +{
  21.103 +	int i;
  21.104 +	struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); 
  21.105 +	traceprintk("%s.\n", __func__);
  21.106 +
  21.107 +	if (ste_ssidp == NULL)
  21.108 +		return ACM_INIT_SSID_ERROR;
  21.109 +
  21.110 +	/* get policy-local ssid reference */
  21.111 +	ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
  21.112 +	if (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) {
  21.113 +		printkd("%s: ERROR ste_ssidref (%x) > max(%x).\n",
  21.114 +			__func__, ste_ssidp->ste_ssidref, ste_bin_pol.max_ssidrefs-1);
  21.115 +		xfree(ste_ssidp);
  21.116 +		return ACM_INIT_SSID_ERROR;
  21.117 +	}
  21.118 +	/* clean ste cache */
  21.119 +	for (i=0; i<ACM_TE_CACHE_SIZE; i++)
  21.120 +		ste_ssidp->ste_cache[i].valid = FREE;
  21.121 +
  21.122 +	(*ste_ssid) = ste_ssidp;
  21.123 +	printkd("%s: determined ste_ssidref to %x.\n", 
  21.124 +	       __func__, ste_ssidp->ste_ssidref);
  21.125 +	return ACM_OK;
  21.126 +}
  21.127 +
  21.128 +
  21.129 +static void
  21.130 +ste_free_domain_ssid(void *ste_ssid)
  21.131 +{
  21.132 +	traceprintk("%s.\n", __func__);
  21.133 +	if (ste_ssid != NULL)
  21.134 +		xfree(ste_ssid);
  21.135 +	return;
  21.136 +}
  21.137 +
  21.138 +/* dump type enforcement cache; policy read-locked already */
  21.139 +static int 
  21.140 +ste_dump_policy(u8 *buf, u16 buf_size) {
  21.141 +     struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
  21.142 +     int ret = 0;
  21.143 +
  21.144 +     ste_buf->ste_max_types = htons(ste_bin_pol.max_types);
  21.145 +     ste_buf->ste_max_ssidrefs = htons(ste_bin_pol.max_ssidrefs);
  21.146 +     ste_buf->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
  21.147 +     ste_buf->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer));
  21.148 +     ret = ntohs(ste_buf->ste_ssid_offset) +
  21.149 +	     sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
  21.150 +
  21.151 +     /* now copy buffer over */
  21.152 +     arrcpy(buf + ntohs(ste_buf->ste_ssid_offset),
  21.153 +	    ste_bin_pol.ssidrefs,
  21.154 +	    sizeof(domaintype_t),
  21.155 +             ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
  21.156 +
  21.157 +     return ret;
  21.158 +}
  21.159 +
  21.160 +/* ste_init_state is called when a policy is changed to detect violations (return != 0).
  21.161 + * from a security point of view, we simulate that all running domains are re-started and
  21.162 + * all sharing decisions are replayed to detect violations or current sharing behavior
  21.163 + * (right now: event_channels, future: also grant_tables)
  21.164 + */ 
  21.165 +static int
  21.166 +ste_init_state(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs)
  21.167 +{
  21.168 +    int violation = 1;
  21.169 +    struct ste_ssid *ste_ssid, *ste_rssid;
  21.170 +    ssidref_t ste_ssidref, ste_rssidref;
  21.171 +    struct domain **pd, *rdom;
  21.172 +    domid_t rdomid;
  21.173 +    grant_entry_t sha_copy;
  21.174 +    int port, i;
  21.175 +
  21.176 +    read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
  21.177 +    /* go through all domains and adjust policy as if this domain was started now */
  21.178 +    pd = &domain_list;
  21.179 +    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  21.180 +	    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.181 +				 (struct acm_ssid_domain *)(*pd)->ssid);
  21.182 +	    ste_ssidref = ste_ssid->ste_ssidref;
  21.183 +	    traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n",
  21.184 +		    __func__, (*pd)->domain_id, ste_ssidref);
  21.185 +	    /* a) check for event channel conflicts */
  21.186 +	    for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
  21.187 +		    spin_lock(&(*pd)->evtchn_lock);
  21.188 +		    if ((*pd)->evtchn[port] == NULL) {
  21.189 +                            spin_unlock(&(*pd)->evtchn_lock);
  21.190 +		            continue;
  21.191 +		    }
  21.192 +		    if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
  21.193 +			    rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom;
  21.194 +			    rdomid = rdom->domain_id;
  21.195 +			    /* rdom now has remote domain */
  21.196 +			    ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.197 +						  (struct acm_ssid_domain *)(rdom->ssid));
  21.198 +			    ste_rssidref = ste_rssid->ste_ssidref;
  21.199 +		    } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) {
  21.200 +			    rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid;
  21.201 +			    if ((rdom = find_domain_by_id(rdomid)) == NULL) {
  21.202 +				    printk("%s: Error finding domain to id %x!\n", __func__, rdomid);
  21.203 +				    goto out;
  21.204 +			    }
  21.205 +			    /* rdom now has remote domain */
  21.206 +			    ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.207 +						  (struct acm_ssid_domain *)(rdom->ssid));
  21.208 +			    ste_rssidref = ste_rssid->ste_ssidref;
  21.209 +			    put_domain(rdom);
  21.210 +		    } else {
  21.211 +			    spin_unlock(&(*pd)->evtchn_lock);
  21.212 +			    continue; /* port unused */
  21.213 +		    }
  21.214 +		    spin_unlock(&(*pd)->evtchn_lock);
  21.215 +
  21.216 +		    /* rdom now has remote domain */
  21.217 +		    ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.218 +					     (struct acm_ssid_domain *)(rdom->ssid));
  21.219 +		    ste_rssidref = ste_rssid->ste_ssidref;
  21.220 +		    traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", 
  21.221 +			    __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port);  
  21.222 +		    /* check whether on subj->ssid, obj->ssid share a common type*/
  21.223 +		    if (!have_common_type(ste_ssidref, ste_rssidref)) {
  21.224 +			    printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
  21.225 +				    __func__, (*pd)->domain_id, rdomid);
  21.226 +			    goto out;
  21.227 +		    }
  21.228 +	    }	
  21.229 +	    /* b) check for grant table conflicts on shared pages */
  21.230 +	    if ((*pd)->grant_table->shared == NULL) {
  21.231 +		    printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id);
  21.232 +		    continue;
  21.233 +	    }
  21.234 +	    for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) {
  21.235 +		    sha_copy =  (*pd)->grant_table->shared[i];
  21.236 +		    if ( sha_copy.flags ) {
  21.237 +			    printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
  21.238 +				    __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, 
  21.239 +				    (unsigned long)sha_copy.frame);
  21.240 +			    rdomid = sha_copy.domid;
  21.241 +			    if ((rdom = find_domain_by_id(rdomid)) == NULL) {
  21.242 +			    	    printkd("%s: domain not found ERROR!\n", __func__);
  21.243 +			    	    goto out;
  21.244 +			    };
  21.245 +			    /* rdom now has remote domain */
  21.246 +			    ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.247 +			    			  (struct acm_ssid_domain *)(rdom->ssid));
  21.248 +			    ste_rssidref = ste_rssid->ste_ssidref;
  21.249 +			    put_domain(rdom);
  21.250 +			    if (!have_common_type(ste_ssidref, ste_rssidref)) {
  21.251 +			    	    printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n",
  21.252 +			    		    __func__, (*pd)->domain_id, rdomid);
  21.253 +			    	    goto out;
  21.254 +			    }
  21.255 +		    }
  21.256 +	    }
  21.257 +    }
  21.258 +    violation = 0;
  21.259 + out:
  21.260 +    read_unlock(&domlist_lock);
  21.261 +    return violation;
  21.262 +    /* returning "violation != 0" means that existing sharing between domains would not 
  21.263 +     * have been allowed if the new policy had been enforced before the sharing; for ste, 
  21.264 +     * this means that there are at least 2 domains that have established sharing through 
  21.265 +     * event-channels or grant-tables but these two domains don't have no longer a common 
  21.266 +     * type in their typesets referenced by their ssidrefs */
  21.267 +}
  21.268 +
  21.269 +/* set new policy; policy write-locked already */
  21.270 +static int
  21.271 +ste_set_policy(u8 *buf, u16 buf_size) 
  21.272 +{
  21.273 +     struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
  21.274 +     void *ssidrefsbuf;
  21.275 +     struct ste_ssid *ste_ssid;
  21.276 +     struct domain **pd;
  21.277 +     int i;
  21.278 +
  21.279 +     /* Convert endianess of policy */
  21.280 +     ste_buf->policy_code = ntohs(ste_buf->policy_code);
  21.281 +     ste_buf->ste_max_types = ntohs(ste_buf->ste_max_types);
  21.282 +     ste_buf->ste_max_ssidrefs = ntohs(ste_buf->ste_max_ssidrefs);
  21.283 +     ste_buf->ste_ssid_offset = ntohs(ste_buf->ste_ssid_offset);
  21.284 +
  21.285 +     /* 1. create and copy-in new ssidrefs buffer */
  21.286 +     ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs);
  21.287 +     if (ssidrefsbuf == NULL) {
  21.288 +	     return -ENOMEM;
  21.289 +     }
  21.290 +     if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
  21.291 +         goto error_free;
  21.292 +
  21.293 +     arrcpy(ssidrefsbuf, 
  21.294 +            buf + ste_buf->ste_ssid_offset,
  21.295 +            sizeof(domaintype_t),
  21.296 +	    ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
  21.297 +
  21.298 +     /* 2. now re-calculate sharing decisions based on running domains; 
  21.299 +      *    this can fail if new policy is conflicting with sharing of running domains 
  21.300 +      *    now: reject violating new policy; future: adjust sharing through revoking sharing */
  21.301 +     if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) {
  21.302 +	     printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
  21.303 +	     goto error_free; /* new policy conflicts with sharing of running domains */
  21.304 +     }
  21.305 +     /* 3. replace old policy (activate new policy) */
  21.306 +     ste_bin_pol.max_types = ste_buf->ste_max_types;
  21.307 +     ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
  21.308 +     if (ste_bin_pol.ssidrefs) 
  21.309 +	     xfree(ste_bin_pol.ssidrefs);
  21.310 +     ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
  21.311 +
  21.312 +     /* clear all ste caches */
  21.313 +     read_lock(&domlist_lock);
  21.314 +     pd = &domain_list;
  21.315 +     for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  21.316 +	 ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.317 +			 (struct acm_ssid_domain *)(*pd)->ssid);
  21.318 + 	 for (i=0; i<ACM_TE_CACHE_SIZE; i++)
  21.319 +		ste_ssid->ste_cache[i].valid = FREE;
  21.320 +     }
  21.321 +     read_unlock(&domlist_lock);
  21.322 +     return ACM_OK;
  21.323 +
  21.324 +error_free:
  21.325 +	printk("%s: ERROR setting policy.\n", __func__);
  21.326 +	if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
  21.327 +	return -EFAULT;
  21.328 +}
  21.329 +
  21.330 +static int 
  21.331 +ste_dump_stats(u8 *buf, u16 buf_len)
  21.332 +{
  21.333 +    struct acm_ste_stats_buffer stats;
  21.334 +
  21.335 +#ifdef ACM_DEBUG
  21.336 +    int i;
  21.337 +    struct ste_ssid *ste_ssid;
  21.338 +    struct domain **pd;
  21.339 +
  21.340 +    printk("ste: Decision caches:\n");
  21.341 +    /* go through all domains and adjust policy as if this domain was started now */
  21.342 +    read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
  21.343 +    pd = &domain_list;
  21.344 +    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  21.345 +        printk("ste: Cache Domain %02x.\n", (*pd)->domain_id);
  21.346 +	ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.347 +			 (struct acm_ssid_domain *)(*pd)->ssid);
  21.348 +	for (i=0; i<ACM_TE_CACHE_SIZE; i++)
  21.349 +		printk("\t\tcache[%02x] = %s, domid=%x.\n", i,
  21.350 +		       (ste_ssid->ste_cache[i].valid == VALID) ? 
  21.351 +		       "VALID" : "FREE",
  21.352 +		       (ste_ssid->ste_cache[i].valid == VALID) ? 
  21.353 +		       ste_ssid->ste_cache[i].id : 0xffffffff);
  21.354 +    }
  21.355 +    read_unlock(&domlist_lock);
  21.356 +    /* init stats */
  21.357 +    printk("STE-Policy Security Hook Statistics:\n");
  21.358 +    printk("ste: event_channel eval_count      = %x\n", atomic_read(&(ste_bin_pol.ec_eval_count)));
  21.359 +    printk("ste: event_channel denied_count    = %x\n", atomic_read(&(ste_bin_pol.ec_denied_count))); 
  21.360 +    printk("ste: event_channel cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.ec_cachehit_count)));
  21.361 +    printk("ste:\n");
  21.362 +    printk("ste: grant_table   eval_count      = %x\n", atomic_read(&(ste_bin_pol.gt_eval_count)));
  21.363 +    printk("ste: grant_table   denied_count    = %x\n", atomic_read(&(ste_bin_pol.gt_denied_count))); 
  21.364 +    printk("ste: grant_table   cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.gt_cachehit_count)));
  21.365 +#endif
  21.366 +
  21.367 +    if (buf_len < sizeof(struct acm_ste_stats_buffer))
  21.368 +	    return -ENOMEM;
  21.369 +
  21.370 +    /* now send the hook counts to user space */
  21.371 +    stats.ec_eval_count = htonl(atomic_read(&ste_bin_pol.ec_eval_count));
  21.372 +    stats.gt_eval_count = htonl(atomic_read(&ste_bin_pol.gt_eval_count));
  21.373 +    stats.ec_denied_count = htonl(atomic_read(&ste_bin_pol.ec_denied_count));
  21.374 +    stats.gt_denied_count = htonl(atomic_read(&ste_bin_pol.gt_denied_count)); 
  21.375 +    stats.ec_cachehit_count = htonl(atomic_read(&ste_bin_pol.ec_cachehit_count));
  21.376 +    stats.gt_cachehit_count = htonl(atomic_read(&ste_bin_pol.gt_cachehit_count));
  21.377 +    memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));
  21.378 +    return sizeof(struct acm_ste_stats_buffer);
  21.379 +}
  21.380 +
  21.381 +
  21.382 +/* we need to go through this before calling the hooks,
  21.383 + * returns 1 == cache hit */
  21.384 +static int inline
  21.385 +check_cache(struct domain *dom, domid_t rdom) {
  21.386 +	struct ste_ssid *ste_ssid;
  21.387 +	int i;
  21.388 +
  21.389 +	printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
  21.390 +	ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.391 +			 (struct acm_ssid_domain *)(dom)->ssid);
  21.392 +
  21.393 +	for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
  21.394 +		if ((ste_ssid->ste_cache[i].valid == VALID) &&
  21.395 +		    (ste_ssid->ste_cache[i].id == rdom)) {
  21.396 +			printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id);
  21.397 +			return 1;
  21.398 +		}
  21.399 +	}
  21.400 +	return 0;
  21.401 +}
  21.402 +
  21.403 +
  21.404 +/* we only get here if there is NO entry yet; no duplication check! */
  21.405 +static void inline
  21.406 +cache_result(struct domain *subj, struct domain *obj) {
  21.407 +	struct ste_ssid *ste_ssid;
  21.408 +	int i;
  21.409 +	printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id);
  21.410 +	ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.411 +			 (struct acm_ssid_domain *)(subj)->ssid);
  21.412 +	for(i=0; i< ACM_TE_CACHE_SIZE; i++)
  21.413 +		if (ste_ssid->ste_cache[i].valid == FREE)
  21.414 +			break;
  21.415 +	if (i< ACM_TE_CACHE_SIZE) {
  21.416 +		ste_ssid->ste_cache[i].valid = VALID;
  21.417 +		ste_ssid->ste_cache[i].id = obj->domain_id;
  21.418 +	} else
  21.419 +		printk ("Cache of dom %x is full!\n", subj->domain_id);
  21.420 +}
  21.421 +
  21.422 +/* deletes entries for domain 'id' from all caches (re-use) */
  21.423 +static void inline
  21.424 +clean_id_from_cache(domid_t id) 
  21.425 +{
  21.426 +    struct ste_ssid *ste_ssid;
  21.427 +    int i;
  21.428 +    struct domain **pd;
  21.429 +
  21.430 +    printkd("deleting cache for dom %x.\n", id);
  21.431 +
  21.432 +    read_lock(&domlist_lock); /* look through caches of all domains */
  21.433 +    pd = &domain_list;
  21.434 +    for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
  21.435 +	ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
  21.436 +			 (struct acm_ssid_domain *)(*pd)->ssid);
  21.437 +	for (i=0; i<ACM_TE_CACHE_SIZE; i++)
  21.438 +	    if ((ste_ssid->ste_cache[i].valid == VALID) &&
  21.439 +		(ste_ssid->ste_cache[i].id = id))
  21.440 +		    ste_ssid->ste_cache[i].valid = FREE;
  21.441 +    }
  21.442 +    read_unlock(&domlist_lock);
  21.443 +}
  21.444 +
  21.445 +/***************************
  21.446 + * Authorization functions
  21.447 + **************************/
  21.448 +
  21.449 +static int 
  21.450 +ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
  21.451 +{      
  21.452 +    /* check for ssidref in range for policy */
  21.453 +    ssidref_t ste_ssidref;
  21.454 +    traceprintk("%s.\n", __func__);
  21.455 +
  21.456 +    read_lock(&acm_bin_pol_rwlock);
  21.457 +    ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
  21.458 +    if (ste_ssidref == ACM_DEFAULT_LOCAL_SSID) {
  21.459 +	printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__);
  21.460 +	read_unlock(&acm_bin_pol_rwlock);
  21.461 +	return ACM_ACCESS_DENIED; /* catching and indicating config error */
  21.462 +    }
  21.463 +    if (ste_ssidref >= ste_bin_pol.max_ssidrefs) {
  21.464 +	printk("%s: ERROR ste_ssidref > max(%x).\n", 
  21.465 +	       __func__, ste_bin_pol.max_ssidrefs-1);
  21.466 +	read_unlock(&acm_bin_pol_rwlock);
  21.467 +	return ACM_ACCESS_DENIED;
  21.468 +    }
  21.469 +    read_unlock(&acm_bin_pol_rwlock);
  21.470 +    return ACM_ACCESS_PERMITTED;
  21.471 +}
  21.472 +
  21.473 +static void 
  21.474 +ste_post_domain_destroy(void *subject_ssid, domid_t id)
  21.475 +{
  21.476 +    /* clean all cache entries for destroyed domain (might be re-used) */
  21.477 +    clean_id_from_cache(id);
  21.478 +}
  21.479 +
  21.480 +/* -------- EVENTCHANNEL OPERATIONS -----------*/
  21.481 +static int
  21.482 +ste_pre_eventchannel_unbound(domid_t id) {
  21.483 +	struct domain *subj, *obj;
  21.484 +	int ret;
  21.485 +	traceprintk("%s: dom%x-->dom%x.\n", 
  21.486 +		    __func__, current->domain->domain_id, id);
  21.487 +
  21.488 +	if (check_cache(current->domain, id)) {
  21.489 +		atomic_inc(&ste_bin_pol.ec_cachehit_count);
  21.490 +		return ACM_ACCESS_PERMITTED;
  21.491 +	}
  21.492 +	atomic_inc(&ste_bin_pol.ec_eval_count);
  21.493 +	subj = current->domain;
  21.494 +	obj = find_domain_by_id(id);
  21.495 +
  21.496 +	if (share_common_type(subj, obj)) {
  21.497 +		cache_result(subj, obj);
  21.498 +		ret = ACM_ACCESS_PERMITTED;
  21.499 +	} else {
  21.500 +		atomic_inc(&ste_bin_pol.ec_denied_count); 
  21.501 +		ret = ACM_ACCESS_DENIED;	
  21.502 +	}
  21.503 +	if (obj != NULL)
  21.504 +		put_domain(obj);
  21.505 +	return ret;
  21.506 +}
  21.507 +
  21.508 +static int
  21.509 +ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
  21.510 +{
  21.511 +	struct domain *subj, *obj;
  21.512 +	int ret;
  21.513 +	traceprintk("%s: dom%x-->dom%x.\n", __func__,
  21.514 +		    (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
  21.515 +		    (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
  21.516 +
  21.517 +	/* following is a bit longer but ensures that we
  21.518 +         * "put" only domains that we where "find"-ing 
  21.519 +	 */
  21.520 +	if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
  21.521 +	if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
  21.522 +
  21.523 +	subj = find_domain_by_id(id1);
  21.524 +	obj  = find_domain_by_id(id2);
  21.525 +	if ((subj == NULL) || (obj == NULL)) {
  21.526 +		ret = ACM_ACCESS_DENIED;
  21.527 +		goto out;
  21.528 +	}
  21.529 +	/* cache check late, but evtchn is not on performance critical path */
  21.530 +	if (check_cache(subj, obj->domain_id)) {
  21.531 +		atomic_inc(&ste_bin_pol.ec_cachehit_count);
  21.532 +		ret = ACM_ACCESS_PERMITTED;
  21.533 +		goto out;
  21.534 +	}
  21.535 +	atomic_inc(&ste_bin_pol.ec_eval_count);
  21.536 +
  21.537 +	if (share_common_type(subj, obj)) {
  21.538 +		cache_result(subj, obj);
  21.539 +		ret = ACM_ACCESS_PERMITTED;
  21.540 +	} else {
  21.541 +		atomic_inc(&ste_bin_pol.ec_denied_count); 
  21.542 +		ret = ACM_ACCESS_DENIED;	
  21.543 +	}
  21.544 + out:
  21.545 +	if (obj != NULL)
  21.546 +		put_domain(obj);
  21.547 +	if (subj != NULL)
  21.548 +		put_domain(subj);
  21.549 +	return ret;
  21.550 +}
  21.551 +
  21.552 +/* -------- SHARED MEMORY OPERATIONS -----------*/
  21.553 +
  21.554 +static int
  21.555 +ste_pre_grant_map_ref (domid_t id) {
  21.556 +	struct domain *obj, *subj;
  21.557 +	int ret;
  21.558 +	traceprintk("%s: dom%x-->dom%x.\n", __func__,
  21.559 +		    current->domain->domain_id, id);
  21.560 +
  21.561 +	if (check_cache(current->domain, id)) {
  21.562 +		atomic_inc(&ste_bin_pol.gt_cachehit_count);
  21.563 +		return ACM_ACCESS_PERMITTED;
  21.564 +	}
  21.565 +	atomic_inc(&ste_bin_pol.gt_eval_count);
  21.566 +	subj = current->domain;
  21.567 +	obj = find_domain_by_id(id);
  21.568 +
  21.569 +	if (share_common_type(subj, obj)) {
  21.570 +		cache_result(subj, obj);
  21.571 +		ret = ACM_ACCESS_PERMITTED;
  21.572 +	} else {
  21.573 +		atomic_inc(&ste_bin_pol.gt_denied_count); 
  21.574 +		printkd("%s: ACCESS DENIED!\n", __func__);
  21.575 +		ret = ACM_ACCESS_DENIED;	
  21.576 +	}
  21.577 +	if (obj != NULL)
  21.578 +		put_domain(obj);
  21.579 +	return ret;
  21.580 +}
  21.581 +
  21.582 +/* since setting up grant tables involves some implicit information
  21.583 +   flow from the creating domain to the domain that is setup, we 
  21.584 +   check types in addition to the general authorization */
  21.585 +static int
  21.586 +ste_pre_grant_setup (domid_t id) {
  21.587 +	struct domain *obj, *subj;
  21.588 +	int ret;
  21.589 +	traceprintk("%s: dom%x-->dom%x.\n", __func__,
  21.590 +		    current->domain->domain_id, id);
  21.591 +
  21.592 +	if (check_cache(current->domain, id)) {
  21.593 +		atomic_inc(&ste_bin_pol.gt_cachehit_count);
  21.594 +		return ACM_ACCESS_PERMITTED;
  21.595 +	}
  21.596 +	atomic_inc(&ste_bin_pol.gt_eval_count);
  21.597 +	/* a) check authorization (eventually use specific capabilities) */
  21.598 +	if (!IS_PRIV(current->domain)) {
  21.599 +		printk("%s: Grant table management authorization denied ERROR!\n", __func__);
  21.600 +		return ACM_ACCESS_DENIED;
  21.601 +	}
  21.602 +	/* b) check types */
  21.603 +	subj = current->domain;
  21.604 +	obj = find_domain_by_id(id);
  21.605 +
  21.606 +	if (share_common_type(subj, obj)) {
  21.607 +		cache_result(subj, obj);
  21.608 +		ret = ACM_ACCESS_PERMITTED;
  21.609 +	} else {
  21.610 +		atomic_inc(&ste_bin_pol.gt_denied_count); 
  21.611 +		ret = ACM_ACCESS_DENIED;	
  21.612 +	}
  21.613 +	if (obj != NULL)
  21.614 +		put_domain(obj);
  21.615 +	return ret;
  21.616 +}
  21.617 +
  21.618 +/* now define the hook structure similarly to LSM */
  21.619 +struct acm_operations acm_simple_type_enforcement_ops = {
  21.620 +	/* policy management services */
  21.621 +	.init_domain_ssid		= ste_init_domain_ssid,
  21.622 +	.free_domain_ssid		= ste_free_domain_ssid,
  21.623 +	.dump_binary_policy    	       	= ste_dump_policy,
  21.624 +	.set_binary_policy     		= ste_set_policy,
  21.625 +	.dump_statistics		= ste_dump_stats,
  21.626 +	/* domain management control hooks */
  21.627 +	.pre_domain_create     		= ste_pre_domain_create,
  21.628 +	.post_domain_create		= NULL,
  21.629 +	.fail_domain_create		= NULL,
  21.630 +	.post_domain_destroy		= ste_post_domain_destroy,
  21.631 +	/* event channel control hooks */
  21.632 +	.pre_eventchannel_unbound      	= ste_pre_eventchannel_unbound,
  21.633 +	.fail_eventchannel_unbound	= NULL,
  21.634 +	.pre_eventchannel_interdomain	= ste_pre_eventchannel_interdomain,
  21.635 +	.fail_eventchannel_interdomain  = NULL,
  21.636 +	/* grant table control hooks */
  21.637 +	.pre_grant_map_ref       	= ste_pre_grant_map_ref,
  21.638 +	.fail_grant_map_ref		= NULL,
  21.639 +	.pre_grant_setup	       	= ste_pre_grant_setup,
  21.640 +	.fail_grant_setup		= NULL,
  21.641 +};
    22.1 --- a/xen/arch/x86/setup.c	Sun Jun 19 17:05:55 2005 +0000
    22.2 +++ b/xen/arch/x86/setup.c	Mon Jun 20 22:28:08 2005 +0000
    22.3 @@ -20,6 +20,7 @@
    22.4  #include <asm/desc.h>
    22.5  #include <asm/shadow.h>
    22.6  #include <asm/e820.h>
    22.7 +#include <public/acm_dom0_setup.h>
    22.8  
    22.9  extern void dmi_scan_machine(void);
   22.10  extern void generic_apic_probe(void);
   22.11 @@ -393,12 +394,17 @@ void __init __start_xen(multiboot_info_t
   22.12  
   22.13      shadow_mode_init();
   22.14  
   22.15 +    /* initialize access control security module */
   22.16 +    acm_init();
   22.17 +
   22.18      /* Create initial domain 0. */
   22.19      dom0 = do_createdomain(0, 0);
   22.20      if ( dom0 == NULL )
   22.21          panic("Error creating domain 0\n");
   22.22  
   22.23      set_bit(_DOMF_privileged, &dom0->domain_flags);
   22.24 +    /* post-create hooks sets security label */
   22.25 +    acm_post_domain0_create(dom0->domain_id);
   22.26  
   22.27      /* Grab the DOM0 command line. */
   22.28      cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
    23.1 --- a/xen/arch/x86/x86_32/entry.S	Sun Jun 19 17:05:55 2005 +0000
    23.2 +++ b/xen/arch/x86/x86_32/entry.S	Mon Jun 20 22:28:08 2005 +0000
    23.3 @@ -751,6 +751,7 @@ ENTRY(hypercall_table)
    23.4          .long do_boot_vcpu
    23.5          .long do_ni_hypercall       /* 25 */
    23.6          .long do_mmuext_op
    23.7 +	 .long do_policy_op          /* 27 */
    23.8          .rept NR_hypercalls-((.-hypercall_table)/4)
    23.9          .long do_ni_hypercall
   23.10          .endr
    24.1 --- a/xen/common/dom0_ops.c	Sun Jun 19 17:05:55 2005 +0000
    24.2 +++ b/xen/common/dom0_ops.c	Mon Jun 20 22:28:08 2005 +0000
    24.3 @@ -19,6 +19,7 @@
    24.4  #include <asm/current.h>
    24.5  #include <public/dom0_ops.h>
    24.6  #include <public/sched_ctl.h>
    24.7 +#include <acm/acm_hooks.h>
    24.8  
    24.9  extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
   24.10  extern void arch_getdomaininfo_ctxt(
   24.11 @@ -91,6 +92,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   24.12  {
   24.13      long ret = 0;
   24.14      dom0_op_t curop, *op = &curop;
   24.15 +    void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
   24.16  
   24.17      if ( !IS_PRIV(current->domain) )
   24.18          return -EPERM;
   24.19 @@ -101,6 +103,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   24.20      if ( op->interface_version != DOM0_INTERFACE_VERSION )
   24.21          return -EACCES;
   24.22  
   24.23 +    if ( acm_pre_dom0_op(op, &ssid) )
   24.24 +        return -EACCES;
   24.25 +
   24.26      switch ( op->cmd )
   24.27      {
   24.28  
   24.29 @@ -357,6 +362,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   24.30              ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) |
   24.31              d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
   24.32  
   24.33 +        if (d->ssid != NULL)
   24.34 +            op->u.getdomaininfo.ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref;
   24.35 +        else    
   24.36 +            op->u.getdomaininfo.ssidref = ACM_DEFAULT_SSID;
   24.37 +
   24.38          op->u.getdomaininfo.tot_pages   = d->tot_pages;
   24.39          op->u.getdomaininfo.max_pages   = d->max_pages;
   24.40          op->u.getdomaininfo.shared_info_frame = 
   24.41 @@ -493,7 +503,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   24.42          ret = arch_do_dom0_op(op,u_dom0_op);
   24.43  
   24.44      }
   24.45 -
   24.46 +    if (!ret)
   24.47 +        acm_post_dom0_op(op, ssid);
   24.48 +    else
   24.49 +        acm_fail_dom0_op(op, ssid);
   24.50      return ret;
   24.51  }
   24.52  
    25.1 --- a/xen/common/event_channel.c	Sun Jun 19 17:05:55 2005 +0000
    25.2 +++ b/xen/common/event_channel.c	Mon Jun 20 22:28:08 2005 +0000
    25.3 @@ -26,6 +26,7 @@
    25.4  
    25.5  #include <public/xen.h>
    25.6  #include <public/event_channel.h>
    25.7 +#include <acm/acm_hooks.h>
    25.8  
    25.9  #define bucket_from_port(d,p) \
   25.10      ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
   25.11 @@ -587,6 +588,9 @@ long do_event_channel_op(evtchn_op_t *uo
   25.12      if ( copy_from_user(&op, uop, sizeof(op)) != 0 )
   25.13          return -EFAULT;
   25.14  
   25.15 +    if (acm_pre_event_channel(&op))
   25.16 +        return -EACCES;
   25.17 +
   25.18      switch ( op.cmd )
   25.19      {
   25.20      case EVTCHNOP_alloc_unbound:
    26.1 --- a/xen/common/grant_table.c	Sun Jun 19 17:05:55 2005 +0000
    26.2 +++ b/xen/common/grant_table.c	Mon Jun 20 22:28:08 2005 +0000
    26.3 @@ -30,6 +30,7 @@
    26.4  #include <xen/sched.h>
    26.5  #include <xen/shadow.h>
    26.6  #include <xen/mm.h>
    26.7 +#include <acm/acm_hooks.h>
    26.8  
    26.9  #define PIN_FAIL(_lbl, _rc, _f, _a...)   \
   26.10      do {                           \
   26.11 @@ -357,6 +358,11 @@ static int
   26.12          return GNTST_bad_gntref;
   26.13      }
   26.14  
   26.15 +    if (acm_pre_grant_map_ref(dom)) {
   26.16 +        (void)__put_user(GNTST_permission_denied, &uop->handle);
   26.17 +        return GNTST_permission_denied;
   26.18 +    }
   26.19 +
   26.20      if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   26.21           unlikely(ld == rd) )
   26.22      {
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/xen/common/policy_ops.c	Mon Jun 20 22:28:08 2005 +0000
    27.3 @@ -0,0 +1,117 @@
    27.4 +/******************************************************************************
    27.5 + *policy_ops.c
    27.6 + * 
    27.7 + * Copyright (C) 2005 IBM Corporation
    27.8 + *
    27.9 + * Author:
   27.10 + * Reiner Sailer <sailer@watson.ibm.com>
   27.11 + *
   27.12 + * This program is free software; you can redistribute it and/or
   27.13 + * modify it under the terms of the GNU General Public License as
   27.14 + * published by the Free Software Foundation, version 2 of the
   27.15 + * License.
   27.16 + *
   27.17 + * Process policy command requests from guest OS.
   27.18 + *
   27.19 + */
   27.20 +#include <xen/config.h>
   27.21 +#include <xen/types.h>
   27.22 +#include <xen/lib.h>
   27.23 +#include <xen/mm.h>
   27.24 +#include <public/policy_ops.h>
   27.25 +#include <xen/sched.h>
   27.26 +#include <xen/event.h>
   27.27 +#include <xen/trace.h>
   27.28 +#include <xen/console.h>
   27.29 +#include <asm/shadow.h>
   27.30 +#include <public/sched_ctl.h>
   27.31 +#include <acm/acm_hooks.h>
   27.32 +
   27.33 +/* function prototypes defined in acm/acm_policy.c */
   27.34 +int acm_set_policy(void *buf, u16 buf_size, u16 policy);
   27.35 +int acm_get_policy(void *buf, u16 buf_size);
   27.36 +int acm_dump_statistics(void *buf, u16 buf_size);
   27.37 +
   27.38 +typedef enum policyoperation {
   27.39 +	POLICY,     /* access to policy interface (early drop) */
   27.40 +	GETPOLICY,  /* dump policy cache */
   27.41 +	SETPOLICY,  /* set policy cache (controls security) */
   27.42 +	DUMPSTATS   /* dump policy statistics */
   27.43 +} policyoperation_t;
   27.44 +
   27.45 +int
   27.46 +acm_authorize_policyops(struct domain *d, policyoperation_t pops)
   27.47 +{
   27.48 +	/* currently, all policy management functions are restricted to privileged domains,
   27.49 +	 * soon we will introduce finer-grained privileges for policy operations 
   27.50 +	 */
   27.51 +	if (!IS_PRIV(d)) {
   27.52 +		printk("%s: Policy management authorization denied ERROR!\n", __func__);
   27.53 +		return ACM_ACCESS_DENIED;
   27.54 +	}
   27.55 +	return ACM_ACCESS_PERMITTED;
   27.56 +}
   27.57 +
   27.58 +long do_policy_op(policy_op_t *u_policy_op)
   27.59 +{
   27.60 +    long ret = 0;
   27.61 +    policy_op_t curop, *op = &curop;
   27.62 +
   27.63 +    /* check here policy decision for policy commands */
   27.64 +    /* for now allow DOM0 only, later indepedently    */
   27.65 +    if (acm_authorize_policyops(current->domain, POLICY))
   27.66 +	    return -EACCES;
   27.67 +
   27.68 +    if ( copy_from_user(op, u_policy_op, sizeof(*op)) )
   27.69 +        return -EFAULT;
   27.70 +
   27.71 +    if ( op->interface_version != POLICY_INTERFACE_VERSION )
   27.72 +        return -EACCES;
   27.73 +
   27.74 +    switch ( op->cmd )
   27.75 +    {
   27.76 +    case POLICY_SETPOLICY:
   27.77 +    {
   27.78 +        if (acm_authorize_policyops(current->domain, SETPOLICY))
   27.79 +		return -EACCES;
   27.80 +	printkd("%s: setting policy.\n", __func__);
   27.81 +	ret = acm_set_policy(op->u.setpolicy.pushcache, op->u.setpolicy.pushcache_size, op->u.setpolicy.policy_type);
   27.82 +        if (ret == ACM_OK)
   27.83 +            ret = 0;
   27.84 +        else
   27.85 +            ret = -ESRCH;
   27.86 +    }
   27.87 +    break;
   27.88 +
   27.89 +    case POLICY_GETPOLICY:
   27.90 +    {
   27.91 +        if (acm_authorize_policyops(current->domain, GETPOLICY))
   27.92 +		return -EACCES;
   27.93 +        printkd("%s: getting policy.\n", __func__);
   27.94 +	ret = acm_get_policy(op->u.getpolicy.pullcache, op->u.getpolicy.pullcache_size);
   27.95 +        if (ret == ACM_OK)
   27.96 +            ret = 0;
   27.97 +        else
   27.98 +            ret = -ESRCH;
   27.99 +    }
  27.100 +    break;
  27.101 +
  27.102 +    case POLICY_DUMPSTATS:
  27.103 +    {
  27.104 +        if (acm_authorize_policyops(current->domain, DUMPSTATS))
  27.105 +		return -EACCES;
  27.106 +	printkd("%s: dumping statistics.\n", __func__);
  27.107 +	ret = acm_dump_statistics(op->u.dumpstats.pullcache, op->u.dumpstats.pullcache_size);
  27.108 +        if (ret == ACM_OK)
  27.109 +            ret = 0;
  27.110 +        else
  27.111 +            ret = -ESRCH;
  27.112 +    }
  27.113 +    break;
  27.114 +
  27.115 +    default:
  27.116 +        ret = -ESRCH;
  27.117 +
  27.118 +    }
  27.119 +    return ret;
  27.120 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/xen/include/acm/acm_core.h	Mon Jun 20 22:28:08 2005 +0000
    28.3 @@ -0,0 +1,117 @@
    28.4 +/****************************************************************
    28.5 + * acm_core.h 
    28.6 + * 
    28.7 + * Copyright (C) 2005 IBM Corporation
    28.8 + *
    28.9 + * Author:
   28.10 + * Reiner Sailer <sailer@watson.ibm.com>
   28.11 + *
   28.12 + * This program is free software; you can redistribute it and/or
   28.13 + * modify it under the terms of the GNU General Public License as
   28.14 + * published by the Free Software Foundation, version 2 of the
   28.15 + * License.
   28.16 + *
   28.17 + * sHype header file describing core data types and constants
   28.18 + *    for the access control module and relevant policies
   28.19 + *
   28.20 + */
   28.21 +#ifndef _ACM_CORE_H
   28.22 +#define _ACM_CORE_H
   28.23 +
   28.24 +#include <xen/spinlock.h>
   28.25 +#include <public/acm.h>
   28.26 +#include <public/policy_ops.h>
   28.27 +
   28.28 +/* Xen-internal representation of the binary policy */
   28.29 +struct acm_binary_policy {
   28.30 +	u16 primary_policy_code;
   28.31 +	u16 secondary_policy_code;
   28.32 +	void *primary_binary_policy;                                 
   28.33 +	void *secondary_binary_policy;
   28.34 +	
   28.35 +};
   28.36 +
   28.37 +struct chwall_binary_policy {
   28.38 +	u16 max_types;
   28.39 +	u16 max_ssidrefs;
   28.40 +	u16 max_conflictsets;
   28.41 +	domaintype_t *ssidrefs;			/* [max_ssidrefs][max_types] 	*/
   28.42 +	domaintype_t *conflict_aggregate_set; 	/* [max_types] 			*/
   28.43 +	domaintype_t *running_types; 		/* [max_types] 			*/
   28.44 +	domaintype_t *conflict_sets;		/* [max_conflictsets][max_types]*/
   28.45 +};
   28.46 +
   28.47 +struct ste_binary_policy {
   28.48 +	u16 max_types;
   28.49 +	u16 max_ssidrefs;
   28.50 +	domaintype_t *ssidrefs;			/* [max_ssidrefs][max_types] 	*/
   28.51 +	atomic_t ec_eval_count, gt_eval_count;
   28.52 +	atomic_t ec_denied_count, gt_denied_count; 
   28.53 +	atomic_t ec_cachehit_count, gt_cachehit_count;
   28.54 +};
   28.55 +
   28.56 +/* global acm policy */
   28.57 +extern struct acm_binary_policy acm_bin_pol;
   28.58 +extern struct chwall_binary_policy chwall_bin_pol;
   28.59 +extern struct ste_binary_policy ste_bin_pol;
   28.60 +/* use the lock when reading / changing binary policy ! */
   28.61 +extern rwlock_t acm_bin_pol_rwlock;
   28.62 +
   28.63 +/* subject and object type definitions */
   28.64 +enum acm_datatype { DOMAIN };
   28.65 +
   28.66 +/* defines number of access decisions to other domains can be cached
   28.67 + * one entry per domain, TE does not distinguish evtchn or grant_table */
   28.68 +#define ACM_TE_CACHE_SIZE	8
   28.69 +enum acm_ste_flag { VALID, FREE };
   28.70 +
   28.71 +/* cache line:
   28.72 + * if cache_line.valid==VALID, then
   28.73 + *    STE decision is cached as "permitted" 
   28.74 + *                 on domain cache_line.id
   28.75 + */
   28.76 +struct acm_ste_cache_line {
   28.77 +	enum acm_ste_flag valid;
   28.78 +	domid_t id;
   28.79 +};
   28.80 +
   28.81 +/* general definition of a subject security id */
   28.82 +struct acm_ssid_domain {
   28.83 +	enum acm_datatype datatype;		/* type of subject (e.g., partition) */
   28.84 +	ssidref_t	  ssidref;		/* combined security reference */
   28.85 +	void           	  *primary_ssid; 	/* primary policy ssid part (e.g. chinese wall) */
   28.86 +	void	          *secondary_ssid;  	/* secondary policy ssid part (e.g. type enforcement) */
   28.87 +	struct domain     *subject;	       	/* backpointer to subject structure */
   28.88 +	domid_t		  domainid;		/* replicate id */
   28.89 +};
   28.90 +
   28.91 +/* chinese wall ssid type */
   28.92 +struct chwall_ssid {
   28.93 +	ssidref_t chwall_ssidref;
   28.94 +};
   28.95 +
   28.96 +/* simple type enforcement ssid type */
   28.97 +struct ste_ssid {
   28.98 +	ssidref_t ste_ssidref;
   28.99 +	struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */
  28.100 +};
  28.101 +
  28.102 +/* macros to access ssidref for primary / secondary policy 
  28.103 + *	primary ssidref   = lower 16 bit
  28.104 + *      secondary ssidref = higher 16 bit
  28.105 + */
  28.106 +#define GET_SSIDREF(POLICY, ssidref) \
  28.107 +	((POLICY) == acm_bin_pol.primary_policy_code) ? \
  28.108 +	((ssidref) & 0xffff) : ((ssidref) >> 16)
  28.109 +
  28.110 +/* macros to access ssid pointer for primary / secondary policy */
  28.111 +#define GET_SSIDP(POLICY, ssid) \
  28.112 +	((POLICY) == acm_bin_pol.primary_policy_code) ? \
  28.113 +	((ssid)->primary_ssid) : ((ssid)->secondary_ssid)
  28.114 +
  28.115 +/* protos */
  28.116 +int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
  28.117 +int acm_free_domain_ssid(struct acm_ssid_domain *ssid);
  28.118 +
  28.119 +#endif
  28.120 +
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/xen/include/acm/acm_endian.h	Mon Jun 20 22:28:08 2005 +0000
    29.3 @@ -0,0 +1,88 @@
    29.4 +/****************************************************************
    29.5 + * acm_endian.h 
    29.6 + * 
    29.7 + * Copyright (C) 2005 IBM Corporation
    29.8 + *
    29.9 + * Author:
   29.10 + * Stefan Berger <stefanb@watson.ibm.com>
   29.11 + * 
   29.12 + * Contributions:
   29.13 + * Reiner Sailer <sailer@watson.ibm.com>
   29.14 + *
   29.15 + * This program is free software; you can redistribute it and/or
   29.16 + * modify it under the terms of the GNU General Public License as
   29.17 + * published by the Free Software Foundation, version 2 of the
   29.18 + * License.
   29.19 + *
   29.20 + * sHype header file defining endian-dependent functions for the
   29.21 + * big-endian policy interface
   29.22 + *
   29.23 + */
   29.24 +#ifndef _ACM_ENDIAN_H
   29.25 +#define _ACM_ENDIAN_H
   29.26 +
   29.27 +/* don't use these functions in performance critical sections! */
   29.28 +
   29.29 +/* set during initialization by testing */
   29.30 +extern u8 little_endian;
   29.31 +
   29.32 +static inline u32 ntohl(u32 x) 
   29.33 +{
   29.34 +    if (little_endian)
   29.35 +        return 
   29.36 +	    ( (((x) >> 24) & 0xff      )| 
   29.37 +	      (((x) >>  8) & 0xff00    )| 
   29.38 +	      (((x) <<  8) & 0xff0000  )|
   29.39 +	      (((x) << 24) & 0xff000000) );
   29.40 +    else
   29.41 +        return x;
   29.42 +}
   29.43 +
   29.44 +static inline u16 ntohs(u16 x) 
   29.45 +{
   29.46 +    if (little_endian)
   29.47 +        return 
   29.48 +	    ( (((x) >> 8) & 0xff   )|
   29.49 +	      (((x) << 8) & 0xff00 ) );
   29.50 +    else
   29.51 +	return x;
   29.52 +}
   29.53 +
   29.54 +#define htonl(x) ntohl(x)
   29.55 +#define htons(x) ntohs(x)
   29.56 +
   29.57 +static inline void arrcpy16(u16 *dest, const u16 *src, size_t n)
   29.58 +{
   29.59 +    unsigned int i = 0;
   29.60 +    while (i < n) {
   29.61 +       	dest[i] = htons(src[i]);
   29.62 +       	i++;
   29.63 +    }
   29.64 +}
   29.65 +
   29.66 +static inline void arrcpy32(u32 *dest, const u32 *src, size_t n)
   29.67 +{
   29.68 +    unsigned int i = 0;
   29.69 +    while (i < n) {
   29.70 +	dest[i] = htonl(src[i]);
   29.71 +	i++;
   29.72 +    }
   29.73 +}
   29.74 +
   29.75 +static inline void arrcpy(void *dest, const void *src, unsigned int elsize, size_t n)
   29.76 +{
   29.77 +    switch (elsize) {
   29.78 +    case sizeof(u16):
   29.79 +        arrcpy16((u16 *)dest, (u16 *)src, n);
   29.80 +        break;
   29.81 +
   29.82 +    case sizeof(u32):
   29.83 +        arrcpy32((u32 *)dest, (u32 *)src, n);
   29.84 +        break;
   29.85 +
   29.86 +    default:
   29.87 +        memcpy(dest, src, elsize*n);
   29.88 +    }
   29.89 +}
   29.90 +
   29.91 +#endif
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/xen/include/acm/acm_hooks.h	Mon Jun 20 22:28:08 2005 +0000
    30.3 @@ -0,0 +1,337 @@
    30.4 +/****************************************************************
    30.5 + * acm_hooks.h 
    30.6 + * 
    30.7 + * Copyright (C) 2005 IBM Corporation
    30.8 + *
    30.9 + * Author:
   30.10 + * Reiner Sailer <sailer@watson.ibm.com>
   30.11 + *
   30.12 + * This program is free software; you can redistribute it and/or
   30.13 + * modify it under the terms of the GNU General Public License as
   30.14 + * published by the Free Software Foundation, version 2 of the
   30.15 + * License.
   30.16 + *
   30.17 + * acm header file implementing the global (policy-independent)
   30.18 + *      sHype hooks that are called throughout Xen.
   30.19 + * 
   30.20 + */
   30.21 +#ifndef _ACM_HOOKS_H
   30.22 +#define _ACM_HOOKS_H
   30.23 +
   30.24 +#include <xen/config.h>
   30.25 +#include <xen/errno.h>
   30.26 +#include <xen/types.h>
   30.27 +#include <xen/lib.h>
   30.28 +#include <xen/delay.h>
   30.29 +#include <xen/sched.h>
   30.30 +#include <public/acm.h>
   30.31 +#include <acm/acm_core.h>
   30.32 +#include <public/dom0_ops.h>
   30.33 +#include <public/event_channel.h>
   30.34 +#include <asm/current.h>
   30.35 +
   30.36 +/* if ACM_TRACE_MODE defined, all hooks should
   30.37 + * print a short trace message */
   30.38 +/* #define ACM_TRACE_MODE */
   30.39 +
   30.40 +#ifdef ACM_TRACE_MODE
   30.41 +#  define traceprintk(fmt, args...) printk(fmt,## args)
   30.42 +#else
   30.43 +#  define traceprintk(fmt, args...)
   30.44 +#endif
   30.45 +
   30.46 +/* global variables */
   30.47 +extern struct acm_operations *acm_primary_ops;
   30.48 +extern struct acm_operations *acm_secondary_ops;
   30.49 +
   30.50 +/**********************************************************************************************
   30.51 + * HOOK structure and meaning (justifies a few words about our model):
   30.52 + * 
   30.53 + * General idea: every policy-controlled system operation is reflected in a 
   30.54 + *               transaction in the system's security state
   30.55 + *
   30.56 + *	Keeping the security state consistent requires "atomic" transactions.
   30.57 + *      The name of the hooks to place around policy-controlled transactions
   30.58 + *      reflects this. If authorizations do not involve security state changes,
   30.59 + *      then and only then POST and FAIL hooks remain empty since we don't care
   30.60 + *      about the eventual outcome of the operation from a security viewpoint.
   30.61 + *
   30.62 + *	PURPOSE of hook types:
   30.63 + *      ======================
   30.64 + *      PRE-Hooks
   30.65 + *		a) general authorization to guard a controlled system operation
   30.66 + *		b) prepare security state change (means: fail hook must be able to "undo" this)
   30.67 + *
   30.68 + *	POST-Hooks
   30.69 + *		a) commit prepared state change
   30.70 + *
   30.71 + *      FAIL-Hooks
   30.72 + *		a) roll-back prepared security state change from PRE-Hook
   30.73 + *
   30.74 + *
   30.75 + *      PLACEMENT of hook types:
   30.76 + *      ========================
   30.77 + *	PRE-Hooks must be called:
   30.78 + *		a) before a guarded/controlled system operation is started
   30.79 + *		(return is ACM_ACCESS_PERMITTED or ACM_ACCESS_DENIED or error)
   30.80 + *		   --> operation must be aborted if return is != ACM_ACCESS_PERMITTED
   30.81 + *
   30.82 + *	POST-Hooks must be called:
   30.83 + *		a) after successful transaction (no return value; commit shall never fail)
   30.84 + *
   30.85 + *	FAIL-Hooks must be called:
   30.86 + *		a) if system transaction (operation) fails somewhen after calling the PRE-hook
   30.87 + *		   (obviously the POST-Hook is not called in this case)
   30.88 + *		b) if another (secondary) policy denies access in its PRE-Hook
   30.89 + *		   (policy layering is useful but requires additional handling)
   30.90 + *
   30.91 + *
   30.92 + *
   30.93 + *       Hook model from a security transaction viewpoint:
   30.94 + *
   30.95 + *          start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success
   30.96 + *                          (pre-hook)  \           (post-hook)
   30.97 + *                                       \
   30.98 + *                                       fail
   30.99 + *                                         \
  30.100 + *                                          \
  30.101 + *                                        roll-back
  30.102 + *                                       (fail-hook)
  30.103 + *                                             \
  30.104 + *                                            sys-ops error
  30.105 + *
  30.106 + *************************************************************************************************/
  30.107 +
  30.108 +struct acm_operations {
  30.109 +	/* policy management functions (must always be defined!) */
  30.110 +	int  (*init_domain_ssid)	       	(void **ssid, ssidref_t ssidref);
  30.111 +	void (*free_domain_ssid)	       	(void *ssid);
  30.112 +	int  (*dump_binary_policy)		(u8 *buffer, u16 buf_size);
  30.113 +	int  (*set_binary_policy)		(u8 *buffer, u16 buf_size);	
  30.114 +	int  (*dump_statistics)			(u8 *buffer, u16 buf_size);
  30.115 +	/* domain management control hooks (can be NULL) */
  30.116 +	int  (*pre_domain_create)              	(void *subject_ssid, ssidref_t ssidref);
  30.117 +	void (*post_domain_create) 		(domid_t domid, ssidref_t ssidref);
  30.118 +	void (*fail_domain_create)             	(void *subject_ssid, ssidref_t ssidref);
  30.119 +	void (*post_domain_destroy)		(void *object_ssid, domid_t id);
  30.120 +	/* event channel control hooks  (can be NULL) */
  30.121 +	int  (*pre_eventchannel_unbound)       	(domid_t id);
  30.122 +	void (*fail_eventchannel_unbound)      	(domid_t id);
  30.123 +	int  (*pre_eventchannel_interdomain)	(domid_t id1, domid_t id2);
  30.124 +	int  (*fail_eventchannel_interdomain)	(domid_t id1, domid_t id2);
  30.125 +	/* grant table control hooks (can be NULL)  */
  30.126 +	int  (*pre_grant_map_ref)       	(domid_t id);
  30.127 +	void (*fail_grant_map_ref)		(domid_t id);
  30.128 +	int  (*pre_grant_setup)       		(domid_t id);
  30.129 +	void (*fail_grant_setup)		(domid_t id);
  30.130 +};
  30.131 +
  30.132 +static inline int acm_pre_domain_create (void *subject_ssid, ssidref_t ssidref)
  30.133 +{
  30.134 +	if ((acm_primary_ops->pre_domain_create != NULL) && 
  30.135 +		 acm_primary_ops->pre_domain_create (subject_ssid, ssidref))
  30.136 +		return ACM_ACCESS_DENIED;
  30.137 +	else if ((acm_secondary_ops->pre_domain_create != NULL) && 
  30.138 +		 acm_secondary_ops->pre_domain_create (subject_ssid, ssidref)) {
  30.139 +		/* roll-back primary */
  30.140 +		if (acm_primary_ops->fail_domain_create != NULL)
  30.141 +			acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
  30.142 +		return ACM_ACCESS_DENIED;
  30.143 +	} else
  30.144 +		return ACM_ACCESS_PERMITTED;
  30.145 +}
  30.146 +
  30.147 +static inline void acm_post_domain_create (domid_t domid, ssidref_t ssidref)
  30.148 +{
  30.149 +	if (acm_primary_ops->post_domain_create != NULL)
  30.150 +		acm_primary_ops->post_domain_create (domid, ssidref);
  30.151 +	if (acm_secondary_ops->post_domain_create != NULL)
  30.152 +		acm_secondary_ops->post_domain_create (domid, ssidref);
  30.153 +}
  30.154 +
  30.155 +static inline void acm_fail_domain_create (void *subject_ssid, ssidref_t ssidref)
  30.156 +{
  30.157 +	if (acm_primary_ops->fail_domain_create != NULL)
  30.158 +		acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
  30.159 +	if (acm_secondary_ops->fail_domain_create != NULL)
  30.160 +		acm_secondary_ops->fail_domain_create (subject_ssid, ssidref);
  30.161 +}
  30.162 +
  30.163 +static inline void acm_post_domain_destroy (void *object_ssid, domid_t id)
  30.164 +{
  30.165 +	if (acm_primary_ops->post_domain_destroy != NULL)
  30.166 +		acm_primary_ops->post_domain_destroy (object_ssid, id);
  30.167 +	if (acm_secondary_ops->post_domain_destroy != NULL)
  30.168 +		acm_secondary_ops->post_domain_destroy (object_ssid, id);
  30.169 +	return;
  30.170 +}
  30.171 +
  30.172 +/*   event channel ops */
  30.173 +
  30.174 +static inline int acm_pre_eventchannel_unbound (domid_t id)
  30.175 +{
  30.176 +	if ((acm_primary_ops->pre_eventchannel_unbound != NULL) && 
  30.177 +	    acm_primary_ops->pre_eventchannel_unbound (id))
  30.178 +		return ACM_ACCESS_DENIED;
  30.179 +	else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) && 
  30.180 +		 acm_secondary_ops->pre_eventchannel_unbound (id)) {
  30.181 +		/* roll-back primary */
  30.182 +		if (acm_primary_ops->fail_eventchannel_unbound != NULL)
  30.183 +			acm_primary_ops->fail_eventchannel_unbound (id);
  30.184 +		return ACM_ACCESS_DENIED;
  30.185 +	} else
  30.186 +		return ACM_ACCESS_PERMITTED;
  30.187 +}
  30.188 +
  30.189 +static inline int acm_pre_eventchannel_interdomain (domid_t id1, domid_t id2)
  30.190 +{	
  30.191 +	if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
  30.192 +	    acm_primary_ops->pre_eventchannel_interdomain (id1, id2))
  30.193 +		return ACM_ACCESS_DENIED;
  30.194 +	else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
  30.195 +		 acm_secondary_ops->pre_eventchannel_interdomain (id1, id2)) {
  30.196 +		/* roll-back primary */
  30.197 +		if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
  30.198 +			acm_primary_ops->fail_eventchannel_interdomain (id1, id2);
  30.199 +		return ACM_ACCESS_DENIED;
  30.200 +	} else
  30.201 +		return ACM_ACCESS_PERMITTED;
  30.202 +}
  30.203 +
  30.204 +/************ Xen inline hooks ***************/
  30.205 +
  30.206 +/* small macro to make the hooks more readable 
  30.207 + * (eliminates hooks if NULL policy is active)
  30.208 + */
  30.209 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
  30.210 +static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) 
  30.211 +{ return 0; }
  30.212 +#else
  30.213 +static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid) 
  30.214 +{
  30.215 +	int ret = -EACCES;
  30.216 +	struct domain *d;
  30.217 +
  30.218 +	switch(op->cmd) {
  30.219 +	case DOM0_CREATEDOMAIN:
  30.220 +		ret = acm_pre_domain_create(current->domain->ssid, op->u.createdomain.ssidref);
  30.221 +		break;
  30.222 +	case DOM0_DESTROYDOMAIN:
  30.223 +		d = find_domain_by_id(op->u.destroydomain.domain);
  30.224 +		if (d != NULL) {
  30.225 +			*ssid = d->ssid; /* save for post destroy when d is gone */
  30.226 +			/* no policy-specific hook */
  30.227 +			put_domain(d);
  30.228 +			ret = 0;
  30.229 +		}
  30.230 +		break;
  30.231 +	default:
  30.232 +		ret = 0; /* ok */
  30.233 +	}
  30.234 +	return ret;
  30.235 +}
  30.236 +#endif
  30.237 +
  30.238 +
  30.239 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
  30.240 +static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) 
  30.241 +{ return; }
  30.242 +#else
  30.243 +static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid) 
  30.244 +{
  30.245 +	switch(op->cmd) {
  30.246 +	case DOM0_CREATEDOMAIN:
  30.247 +		/* initialialize shared sHype security labels for new domain */
  30.248 +		acm_init_domain_ssid(op->u.createdomain.domain, op->u.createdomain.ssidref);
  30.249 +		acm_post_domain_create(op->u.createdomain.domain, op->u.createdomain.ssidref);
  30.250 +		break;
  30.251 +	case DOM0_DESTROYDOMAIN:
  30.252 +		acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
  30.253 +		/* free security ssid for the destroyed domain (also if running null policy */
  30.254 +		acm_free_domain_ssid((struct acm_ssid_domain *)ssid);
  30.255 +		break;
  30.256 +	}
  30.257 +}
  30.258 +#endif
  30.259 +
  30.260 +
  30.261 +#if (ACM_USE_SECURITY_POLICy == ACM_NULL_POLICY)
  30.262 +static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid) 
  30.263 +{ return; }
  30.264 +#else
  30.265 +static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid) 
  30.266 +{
  30.267 +	switch(op->cmd) {
  30.268 +	case DOM0_CREATEDOMAIN:
  30.269 +		acm_fail_domain_create(current->domain->ssid, op->u.createdomain.ssidref);
  30.270 +		break;
  30.271 +	}
  30.272 +}
  30.273 +#endif
  30.274 +
  30.275 +
  30.276 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
  30.277 +static inline int acm_pre_event_channel(evtchn_op_t *op) 
  30.278 +{ return 0; }
  30.279 +#else
  30.280 +static inline int acm_pre_event_channel(evtchn_op_t *op) 
  30.281 +{
  30.282 +	int ret = -EACCES;
  30.283 +
  30.284 +	switch(op->cmd) {
  30.285 +	case EVTCHNOP_alloc_unbound:
  30.286 +		ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom);
  30.287 +		break;
  30.288 +	case EVTCHNOP_bind_interdomain:
  30.289 +		ret = acm_pre_eventchannel_interdomain(op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2);
  30.290 +		break;
  30.291 +	default:
  30.292 +		ret = 0; /* ok */
  30.293 +	}
  30.294 +	return ret;
  30.295 +}
  30.296 +#endif
  30.297 +
  30.298 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
  30.299 +static inline int acm_pre_grant_map_ref(domid_t id) 
  30.300 +{ return 0; }
  30.301 +#else
  30.302 +static inline int acm_pre_grant_map_ref (domid_t id)
  30.303 +{
  30.304 +	if ((acm_primary_ops->pre_grant_map_ref != NULL) &&
  30.305 +	    acm_primary_ops->pre_grant_map_ref (id))
  30.306 +		return ACM_ACCESS_DENIED;
  30.307 +	else if ((acm_secondary_ops->pre_grant_map_ref != NULL) &&
  30.308 +		 acm_secondary_ops->pre_grant_map_ref (id)) {
  30.309 +		/* roll-back primary */
  30.310 +		if (acm_primary_ops->fail_grant_map_ref != NULL)
  30.311 +			acm_primary_ops->fail_grant_map_ref (id);
  30.312 +		return ACM_ACCESS_DENIED;
  30.313 +	} else
  30.314 +		return ACM_ACCESS_PERMITTED;
  30.315 +}
  30.316 +#endif
  30.317 +
  30.318 +
  30.319 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
  30.320 +static inline int acm_pre_grant_setup(domid_t id) 
  30.321 +{ return 0; }
  30.322 +#else
  30.323 +static inline int acm_pre_grant_setup (domid_t id)
  30.324 +{
  30.325 +	if ((acm_primary_ops->pre_grant_setup != NULL) &&
  30.326 +	    acm_primary_ops->pre_grant_setup (id))
  30.327 +		return ACM_ACCESS_DENIED;
  30.328 +	else if ((acm_secondary_ops->pre_grant_setup != NULL) &&
  30.329 +		 acm_secondary_ops->pre_grant_setup (id)) {
  30.330 +		/* roll-back primary */
  30.331 +		if (acm_primary_ops->fail_grant_setup != NULL)
  30.332 +			acm_primary_ops->fail_grant_setup (id);
  30.333 +		return ACM_ACCESS_DENIED;
  30.334 +	} else
  30.335 +		return ACM_ACCESS_PERMITTED;
  30.336 +}
  30.337 +#endif
  30.338 +
  30.339 +
  30.340 +#endif
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/xen/include/public/acm.h	Mon Jun 20 22:28:08 2005 +0000
    31.3 @@ -0,0 +1,161 @@
    31.4 +/****************************************************************
    31.5 + * acm.h
    31.6 + * 
    31.7 + * Copyright (C) 2005 IBM Corporation
    31.8 + *
    31.9 + * Author:
   31.10 + * Reiner Sailer <sailer@watson.ibm.com>
   31.11 + *
   31.12 + * Contributors:
   31.13 + * Stefan Berger <stefanb@watson.ibm.com> 
   31.14 + *	added network byte order support for binary policies
   31.15 + *
   31.16 + * This program is free software; you can redistribute it and/or
   31.17 + * modify it under the terms of the GNU General Public License as
   31.18 + * published by the Free Software Foundation, version 2 of the
   31.19 + * License.
   31.20 + *
   31.21 + * sHype general access control module header file.
   31.22 + *     here are all definitions that are shared between
   31.23 + *     xen-core, guest-kernels, and applications.
   31.24 + *
   31.25 + * todo: move from static policy choice to compile option.
   31.26 + */
   31.27 +
   31.28 +#ifndef _XEN_PUBLIC_SHYPE_H
   31.29 +#define _XEN_PUBLIC_SHYPE_H
   31.30 +
   31.31 +#include "xen.h"
   31.32 +#include "sched_ctl.h"
   31.33 +
   31.34 +/* if ACM_DEBUG defined, all hooks should
   31.35 + * print a short trace message (comment it out
   31.36 + * when not in testing mode )
   31.37 + */
   31.38 +/* #define ACM_DEBUG */
   31.39 +
   31.40 +#ifdef ACM_DEBUG
   31.41 +#  define printkd(fmt, args...) printk(fmt,## args)
   31.42 +#else
   31.43 +#  define printkd(fmt, args...)
   31.44 +#endif
   31.45 +
   31.46 +/* default ssid reference value if not supplied */
   31.47 +#define ACM_DEFAULT_SSID 	0xffffffff
   31.48 +#define ACM_DEFAULT_LOCAL_SSID  0xffff
   31.49 +
   31.50 +/* Internal ACM ERROR types */
   31.51 +#define ACM_OK				 0
   31.52 +#define ACM_UNDEF			-1
   31.53 +#define ACM_INIT_SSID_ERROR		-2
   31.54 +#define ACM_INIT_SOID_ERROR		-3
   31.55 +#define ACM_ERROR		        -4
   31.56 +
   31.57 +/* External ACCESS DECISIONS */
   31.58 +#define ACM_ACCESS_PERMITTED		0
   31.59 +#define ACM_ACCESS_DENIED		-111
   31.60 +#define ACM_NULL_POINTER_ERROR		-200
   31.61 +
   31.62 +#define ACM_MAX_POLICY  3
   31.63 +
   31.64 +#define ACM_NULL_POLICY	0
   31.65 +#define ACM_CHINESE_WALL_POLICY	1
   31.66 +#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
   31.67 +#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3
   31.68 +
   31.69 +/* policy: */
   31.70 +#define ACM_POLICY_NAME(X) \
   31.71 +	(X == ACM_NULL_POLICY) ? "NULL policy" : \
   31.72 +	(X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \
   31.73 +	(X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT policy" : \
   31.74 +	(X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
   31.75 +	"UNDEFINED policy"
   31.76 +
   31.77 +#ifndef ACM_USE_SECURITY_POLICY
   31.78 +#define ACM_USE_SECURITY_POLICY ACM_NULL_POLICY
   31.79 +#endif
   31.80 +
   31.81 +/* defines a ssid reference used by xen */
   31.82 +typedef u32 ssidref_t;
   31.83 +
   31.84 +/* -------security policy relevant type definitions-------- */
   31.85 +
   31.86 +/* type identifier; compares to "equal" or "not equal" */
   31.87 +typedef u16 domaintype_t;
   31.88 +
   31.89 +/* CHINESE WALL POLICY DATA STRUCTURES
   31.90 + *
   31.91 + * current accumulated conflict type set:
   31.92 + * When a domain is started and has a type that is in
   31.93 + * a conflict set, the conflicting types are incremented in
   31.94 + * the aggregate set. When a domain is destroyed, the 
   31.95 + * conflicting types to its type are decremented.
   31.96 + * If a domain has multiple types, this procedure works over
   31.97 + * all those types.
   31.98 + *
   31.99 + * conflict_aggregate_set[i] holds the number of
  31.100 + *   running domains that have a conflict with type i.
  31.101 + *
  31.102 + * running_types[i] holds the number of running domains
  31.103 + *        that include type i in their ssidref-referenced type set
  31.104 + *
  31.105 + * conflict_sets[i][j] is "0" if type j has no conflict
  31.106 + *    with type i and is "1" otherwise.
  31.107 + */
  31.108 +/* high-16 = version, low-16 = check magic */
  31.109 +#define ACM_MAGIC		0x0001debc
  31.110 +
  31.111 +/* each offset in bytes from start of the struct they
  31.112 + *   the are part of */
  31.113 +/* each buffer consists of all policy information for
  31.114 + * the respective policy given in the policy code
  31.115 + */
  31.116 +struct acm_policy_buffer {
  31.117 +        u32 magic;
  31.118 +	u32 policyversion;
  31.119 +	u32 len;
  31.120 +	u16 primary_policy_code;
  31.121 +	u16 primary_buffer_offset;
  31.122 +	u16 secondary_policy_code;
  31.123 +	u16 secondary_buffer_offset;
  31.124 +};
  31.125 +
  31.126 +struct acm_chwall_policy_buffer {
  31.127 +	u16 policy_code;
  31.128 +	u16 chwall_max_types;
  31.129 +	u16 chwall_max_ssidrefs;
  31.130 +	u16 chwall_max_conflictsets;
  31.131 +	u16 chwall_ssid_offset;
  31.132 +	u16 chwall_conflict_sets_offset;
  31.133 +	u16 chwall_running_types_offset;
  31.134 +	u16 chwall_conflict_aggregate_offset;
  31.135 +};
  31.136 +
  31.137 +struct acm_ste_policy_buffer {
  31.138 +	u16 policy_code;
  31.139 +	u16 ste_max_types;
  31.140 +	u16 ste_max_ssidrefs;
  31.141 +	u16 ste_ssid_offset;
  31.142 +};
  31.143 +
  31.144 +struct acm_stats_buffer {
  31.145 +        u32 magic;
  31.146 +	u32 policyversion;
  31.147 +	u32 len;
  31.148 +	u16 primary_policy_code;
  31.149 +	u16 primary_stats_offset;
  31.150 +	u16 secondary_policy_code;
  31.151 +	u16 secondary_stats_offset;
  31.152 +};
  31.153 +
  31.154 +struct acm_ste_stats_buffer {
  31.155 +	u32 ec_eval_count;
  31.156 +	u32 gt_eval_count;
  31.157 +	u32 ec_denied_count;
  31.158 +	u32 gt_denied_count; 
  31.159 +	u32 ec_cachehit_count;
  31.160 +	u32 gt_cachehit_count;
  31.161 +};
  31.162 +
  31.163 +
  31.164 +#endif
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/xen/include/public/acm_dom0_setup.h	Mon Jun 20 22:28:08 2005 +0000
    32.3 @@ -0,0 +1,34 @@
    32.4 +/****************************************************************
    32.5 + * acm_dom0_setup.h
    32.6 + * 
    32.7 + * Copyright (C) 2005 IBM Corporation
    32.8 + *
    32.9 + * Author:
   32.10 + * Reiner Sailer <sailer@watson.ibm.com>
   32.11 + *
   32.12 + * Includes necessary definitions to bring-up dom0
   32.13 + */
   32.14 +#include <acm/acm_hooks.h>
   32.15 +
   32.16 +extern int acm_init(void);
   32.17 +
   32.18 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
   32.19 +
   32.20 +static inline void acm_post_domain0_create(domid_t domid) 
   32.21 +{ 
   32.22 +	return; 
   32.23 +}
   32.24 +
   32.25 +#else
   32.26 +
   32.27 +/* predefined ssidref for DOM0 used by xen when creating DOM0 */
   32.28 +#define ACM_DOM0_SSIDREF	0
   32.29 +
   32.30 +static inline void acm_post_domain0_create(domid_t domid)
   32.31 +{
   32.32 +	/* initialialize shared sHype security labels for new domain */
   32.33 +	acm_init_domain_ssid(domid, ACM_DOM0_SSIDREF);
   32.34 +	acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
   32.35 +}
   32.36 +
   32.37 +#endif
    33.1 --- a/xen/include/public/dom0_ops.h	Sun Jun 19 17:05:55 2005 +0000
    33.2 +++ b/xen/include/public/dom0_ops.h	Mon Jun 20 22:28:08 2005 +0000
    33.3 @@ -43,6 +43,8 @@ typedef struct sched_adjdom_cmd dom0_adj
    33.4  
    33.5  #define DOM0_CREATEDOMAIN      8
    33.6  typedef struct {
    33.7 +    /* IN parameters */
    33.8 +    u32 ssidref;
    33.9      /* IN/OUT parameters. */
   33.10      /* Identifier for new domain (auto-allocate if zero is specified). */
   33.11      domid_t domain;
   33.12 @@ -88,6 +90,7 @@ typedef struct {
   33.13      u32      n_vcpu;
   33.14      s32      vcpu_to_cpu[MAX_VIRT_CPUS];  /* current mapping   */
   33.15      cpumap_t cpumap[MAX_VIRT_CPUS];       /* allowable mapping */
   33.16 +    u32	     ssidref;
   33.17  } dom0_getdomaininfo_t;
   33.18  
   33.19  #define DOM0_SETDOMAININFO      13
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/xen/include/public/policy_ops.h	Mon Jun 20 22:28:08 2005 +0000
    34.3 @@ -0,0 +1,74 @@
    34.4 +/******************************************************************************
    34.5 + * policy_ops.h
    34.6 + * 
    34.7 + * Copyright (C) 2005 IBM Corporation
    34.8 + *
    34.9 + * Author:
   34.10 + * Reiner Sailer <sailer@watson.ibm.com>
   34.11 + *
   34.12 + * This program is free software; you can redistribute it and/or
   34.13 + * modify it under the terms of the GNU General Public License as
   34.14 + * published by the Free Software Foundation, version 2 of the
   34.15 + * License. 
   34.16 + *
   34.17 + * Process policy command requests from guest OS.
   34.18 + * access checked by policy; not restricted to DOM0
   34.19 + * 
   34.20 + */
   34.21 +
   34.22 +
   34.23 +#ifndef __XEN_PUBLIC_POLICY_OPS_H__
   34.24 +#define __XEN_PUBLIC_POLICY_OPS_H__
   34.25 +
   34.26 +#include "xen.h"
   34.27 +#include "sched_ctl.h"
   34.28 +
   34.29 +/*
   34.30 + * Make sure you increment the interface version whenever you modify this file!
   34.31 + * This makes sure that old versions of policy tools will stop working in a
   34.32 + * well-defined way (rather than crashing the machine, for instance).
   34.33 + */
   34.34 +#define POLICY_INTERFACE_VERSION   0xAAAA0001
   34.35 +
   34.36 +/************************************************************************/
   34.37 +
   34.38 +#define POLICY_SETPOLICY        	4
   34.39 +typedef struct {
   34.40 +    /* IN variables. */
   34.41 +    u16           policy_type;
   34.42 +    u16		  padding1;
   34.43 +    /* OUT variables */
   34.44 +    void  	  *pushcache;
   34.45 +    u16           pushcache_size;
   34.46 +} PACKED policy_setpolicy_t;          
   34.47 +
   34.48 +
   34.49 +#define POLICY_GETPOLICY        	5
   34.50 +typedef struct {
   34.51 +    /* IN variables. */
   34.52 +    u16           policy_type;
   34.53 +    u16		  padding1;
   34.54 +    /* OUT variables */
   34.55 +    void  	  *pullcache;
   34.56 +    u16           pullcache_size;
   34.57 +} PACKED policy_getpolicy_t;       
   34.58 +
   34.59 +#define POLICY_DUMPSTATS        	6
   34.60 +typedef struct {
   34.61 +    void  	  *pullcache;
   34.62 +    u16           pullcache_size;
   34.63 +} PACKED policy_dumpstats_t;            
   34.64 + 
   34.65 +
   34.66 +typedef struct {
   34.67 +    u32 cmd;                          /* 0 */
   34.68 +    u32 interface_version;            /* 4 */ /* POLICY_INTERFACE_VERSION */
   34.69 +	union {			      /* 8 */
   34.70 +        u32	                 dummy[14];  /* 72bytes */
   34.71 +	policy_setpolicy_t       setpolicy;
   34.72 +        policy_getpolicy_t       getpolicy;
   34.73 +	policy_dumpstats_t	 dumpstats;
   34.74 +    } PACKED u;
   34.75 +} PACKED policy_op_t;            /* 80 bytes */
   34.76 +
   34.77 +#endif /* __XEN_PUBLIC_POLICY_OPS_H__ */
    35.1 --- a/xen/include/public/xen.h	Sun Jun 19 17:05:55 2005 +0000
    35.2 +++ b/xen/include/public/xen.h	Mon Jun 20 22:28:08 2005 +0000
    35.3 @@ -58,6 +58,7 @@
    35.4  #define __HYPERVISOR_boot_vcpu            24
    35.5  #define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
    35.6  #define __HYPERVISOR_mmuext_op            26
    35.7 +#define __HYPERVISOR_policy_op		  27
    35.8  
    35.9  /* 
   35.10   * VIRTUAL INTERRUPTS
    36.1 --- a/xen/include/xen/sched.h	Sun Jun 19 17:05:55 2005 +0000
    36.2 +++ b/xen/include/xen/sched.h	Mon Jun 20 22:28:08 2005 +0000
    36.3 @@ -137,6 +137,8 @@ struct domain
    36.4      cpumask_t        cpumask;
    36.5  
    36.6      struct arch_domain arch;
    36.7 +
    36.8 +    void *ssid; /* sHype security subject identifier */
    36.9  };
   36.10  
   36.11  struct domain_setup_info