ia64/xen-unstable

changeset 5958:433402c64c77

Remainder of ACM patch (hgrrrr).

Signed-off-by: Reiner Sailer <sailer@watson.ibm.com>
Signed-off-by: Steven Hand <steven@xensource.com>
author smh22@firebug.cl.cam.ac.uk
date Tue Aug 02 10:15:17 2005 +0000 (2005-08-02)
parents d18f732c0a5f
children e8178f0adc91 d709f743dd33
files tools/misc/policyprocessor/Makefile tools/misc/policyprocessor/c2j_include.c tools/security/Makefile tools/security/secpol_tool.c xen/common/acm_ops.c xen/include/public/acm_ops.h
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/misc/policyprocessor/Makefile	Tue Aug 02 10:15:17 2005 +0000
     1.3 @@ -0,0 +1,42 @@
     1.4 +XEN_ROOT = ../../..
     1.5 +include $(XEN_ROOT)/tools/Rules.mk
     1.6 +
     1.7 +CFLAGS   += -static
     1.8 +CFLAGS   += -Wall
     1.9 +CFLAGS   += -Werror
    1.10 +CFLAGS   += -O3
    1.11 +CFLAGS   += -fno-strict-aliasing
    1.12 +CFLAGS   += -I.
    1.13 +
    1.14 +all: build
    1.15 +
    1.16 +build: mk-symlinks
    1.17 +	$(MAKE) xml_to_bin
    1.18 +
    1.19 +default: all
    1.20 +
    1.21 +install: all
    1.22 +
    1.23 +xml_to_bin : make_include XmlToBin.java XmlToBinInterface.java SsidsEntry.java SecurityLabel.java myHandler.java
    1.24 +	javac XmlToBin.java
    1.25 +
    1.26 +make_include : c2j_include
    1.27 +	./c2j_include
    1.28 +
    1.29 +c2j_include: c2j_include.c
    1.30 +	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
    1.31 +
    1.32 +clean:
    1.33 +	rm -rf *.class xen c2j_include policy_version.java *.bin
    1.34 +
    1.35 +
    1.36 +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
    1.37 +mk-symlinks:
    1.38 +	[ -e xen/linux ] || mkdir -p xen/linux
    1.39 +	[ -e xen/io ]    || mkdir -p xen/io
    1.40 +	( cd xen >/dev/null ; \
    1.41 +	  ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
    1.42 +	( cd xen/io >/dev/null ; \
    1.43 +	  ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
    1.44 +	( cd xen/linux >/dev/null ; \
    1.45 +	  ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/misc/policyprocessor/c2j_include.c	Tue Aug 02 10:15:17 2005 +0000
     2.3 @@ -0,0 +1,57 @@
     2.4 +/****************************************************************
     2.5 + * c2j_include.c
     2.6 + *
     2.7 + * Copyright (C) 2005 IBM Corporation
     2.8 + *
     2.9 + * Authors:
    2.10 + * Reiner Sailer <sailer@watson.ibm.com>
    2.11 + *
    2.12 + * This program is free software; you can redistribute it and/or
    2.13 + * modify it under the terms of the GNU General Public License as
    2.14 + * published by the Free Software Foundation, version 2 of the
    2.15 + * License.
    2.16 + *
    2.17 + * This tool makes some constants from acm.h available to the
    2.18 + * java policyprocessor for version checking.
    2.19 + */
    2.20 +#include <stdio.h>
    2.21 +#include <errno.h>
    2.22 +#include <stdlib.h>
    2.23 +#include <stdint.h>
    2.24 +
    2.25 +typedef uint8_t  u8;
    2.26 +typedef uint16_t u16;
    2.27 +typedef uint32_t u32;
    2.28 +typedef uint64_t u64;
    2.29 +typedef int8_t   s8;
    2.30 +typedef int16_t  s16;
    2.31 +typedef int32_t  s32;
    2.32 +typedef int64_t  s64;
    2.33 +
    2.34 +#include <xen/acm.h>
    2.35 +
    2.36 +char *filename = "policy_version.java";
    2.37 +
    2.38 +int main(int argc, char **argv)
    2.39 +{
    2.40 +
    2.41 +    FILE *fd;
    2.42 +    if ((fd = fopen(filename, "w")) <= 0)
    2.43 +    {
    2.44 +        printf("File %s not found.\n", filename);
    2.45 +        exit(-ENOENT);
    2.46 +    }
    2.47 +
    2.48 +    fprintf(fd, "/*\n * This file was automatically generated\n");
    2.49 +    fprintf(fd, " * Do not change it manually!\n */\n");
    2.50 +    fprintf(fd, "public class policy_version {\n");
    2.51 +    fprintf(fd, "	final int ACM_POLICY_VERSION = %x;\n",
    2.52 +            ACM_POLICY_VERSION);
    2.53 +    fprintf(fd, "	final int ACM_CHWALL_VERSION = %x;\n",
    2.54 +            ACM_CHWALL_VERSION);
    2.55 +    fprintf(fd, "	final int ACM_STE_VERSION = %x;\n",
    2.56 +            ACM_STE_VERSION);
    2.57 +    fprintf(fd, "}\n");
    2.58 +    fclose(fd);
    2.59 +    return 0;
    2.60 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/security/Makefile	Tue Aug 02 10:15:17 2005 +0000
     3.3 @@ -0,0 +1,36 @@
     3.4 +XEN_ROOT = ../..
     3.5 +include $(XEN_ROOT)/tools/Rules.mk
     3.6 +
     3.7 +SRCS     = secpol_tool.c
     3.8 +CFLAGS   += -static
     3.9 +CFLAGS   += -Wall
    3.10 +CFLAGS   += -Werror
    3.11 +CFLAGS   += -O3
    3.12 +CFLAGS   += -fno-strict-aliasing
    3.13 +CFLAGS   += -I.
    3.14 +
    3.15 +all: build
    3.16 +build: mk-symlinks
    3.17 +	$(MAKE) secpol_tool
    3.18 +
    3.19 +default: all
    3.20 +
    3.21 +install: all
    3.22 +
    3.23 +secpol_tool : secpol_tool.c
    3.24 +	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
    3.25 +
    3.26 +clean:
    3.27 +	rm -rf secpol_tool xen
    3.28 +
    3.29 +
    3.30 +LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
    3.31 +mk-symlinks:
    3.32 +	[ -e xen/linux ] || mkdir -p xen/linux
    3.33 +	[ -e xen/io ]    || mkdir -p xen/io
    3.34 +	( cd xen >/dev/null ; \
    3.35 +	  ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
    3.36 +	( cd xen/io >/dev/null ; \
    3.37 +	  ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
    3.38 +	( cd xen/linux >/dev/null ; \
    3.39 +	  ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/security/secpol_tool.c	Tue Aug 02 10:15:17 2005 +0000
     4.3 @@ -0,0 +1,648 @@
     4.4 +/****************************************************************
     4.5 + * secpol_tool.c
     4.6 + *
     4.7 + * Copyright (C) 2005 IBM Corporation
     4.8 + *
     4.9 + * Authors:
    4.10 + * Reiner Sailer <sailer@watson.ibm.com>
    4.11 + * Stefan Berger <stefanb@watson.ibm.com>
    4.12 + *
    4.13 + * This program is free software; you can redistribute it and/or
    4.14 + * modify it under the terms of the GNU General Public License as
    4.15 + * published by the Free Software Foundation, version 2 of the
    4.16 + * License.
    4.17 + *
    4.18 + * sHype policy management tool. This code runs in a domain and
    4.19 + *     manages the Xen security policy by interacting with the
    4.20 + *     Xen access control module via a /proc/xen/privcmd proc-ioctl,
    4.21 + *     which is translated into a acm_op hypercall into Xen.
    4.22 + *
    4.23 + * indent -i4 -kr -nut
    4.24 + */
    4.25 +
    4.26 +
    4.27 +#include <unistd.h>
    4.28 +#include <stdio.h>
    4.29 +#include <errno.h>
    4.30 +#include <fcntl.h>
    4.31 +#include <sys/mman.h>
    4.32 +#include <sys/types.h>
    4.33 +#include <sys/stat.h>
    4.34 +#include <stdlib.h>
    4.35 +#include <sys/ioctl.h>
    4.36 +#include <string.h>
    4.37 +#include <stdint.h>
    4.38 +#include <netinet/in.h>
    4.39 +
    4.40 +typedef uint8_t u8;
    4.41 +typedef uint16_t u16;
    4.42 +typedef uint32_t u32;
    4.43 +typedef uint64_t u64;
    4.44 +typedef int8_t s8;
    4.45 +typedef int16_t s16;
    4.46 +typedef int32_t s32;
    4.47 +typedef int64_t s64;
    4.48 +
    4.49 +#include <xen/acm.h>
    4.50 +#include <xen/acm_ops.h>
    4.51 +#include <xen/linux/privcmd.h>
    4.52 +
    4.53 +#define PERROR(_m, _a...) \
    4.54 +fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,	\
    4.55 +                errno, strerror(errno))
    4.56 +
    4.57 +static inline int do_policycmd(int xc_handle, unsigned int cmd,
    4.58 +                               unsigned long data)
    4.59 +{
    4.60 +    return ioctl(xc_handle, cmd, data);
    4.61 +}
    4.62 +
    4.63 +static inline int do_xen_hypercall(int xc_handle,
    4.64 +                                   privcmd_hypercall_t * hypercall)
    4.65 +{
    4.66 +    return do_policycmd(xc_handle,
    4.67 +                        IOCTL_PRIVCMD_HYPERCALL,
    4.68 +                        (unsigned long) hypercall);
    4.69 +}
    4.70 +
    4.71 +static inline int do_acm_op(int xc_handle, acm_op_t * op)
    4.72 +{
    4.73 +    int ret = -1;
    4.74 +    privcmd_hypercall_t hypercall;
    4.75 +
    4.76 +    op->interface_version = ACM_INTERFACE_VERSION;
    4.77 +
    4.78 +    hypercall.op = __HYPERVISOR_acm_op;
    4.79 +    hypercall.arg[0] = (unsigned long) op;
    4.80 +
    4.81 +    if (mlock(op, sizeof(*op)) != 0)
    4.82 +    {
    4.83 +        PERROR("Could not lock memory for Xen policy hypercall");
    4.84 +        goto out1;
    4.85 +    }
    4.86 +
    4.87 +    if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
    4.88 +    {
    4.89 +        if (errno == EACCES)
    4.90 +            fprintf(stderr, "ACM operation failed -- need to"
    4.91 +                    " rebuild the user-space tool set?\n");
    4.92 +        goto out2;
    4.93 +    }
    4.94 +
    4.95 +  out2:(void) munlock(op, sizeof(*op));
    4.96 +  out1:return ret;
    4.97 +}
    4.98 +
    4.99 +/*************************** DUMPS *******************************/
   4.100 +
   4.101 +void acm_dump_chinesewall_buffer(void *buf, int buflen)
   4.102 +{
   4.103 +
   4.104 +    struct acm_chwall_policy_buffer *cwbuf =
   4.105 +        (struct acm_chwall_policy_buffer *) buf;
   4.106 +    domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
   4.107 +    int i, j;
   4.108 +
   4.109 +
   4.110 +    if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY)
   4.111 +    {
   4.112 +        printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
   4.113 +        return;
   4.114 +    }
   4.115 +    printf("\n\nChinese Wall policy:\n");
   4.116 +    printf("====================\n");
   4.117 +    printf("Policy version= %x.\n", ntohl(cwbuf->policy_version));
   4.118 +    printf("Max Types     = %x.\n", ntohl(cwbuf->chwall_max_types));
   4.119 +    printf("Max Ssidrefs  = %x.\n", ntohl(cwbuf->chwall_max_ssidrefs));
   4.120 +    printf("Max ConfSets  = %x.\n", ntohl(cwbuf->chwall_max_conflictsets));
   4.121 +    printf("Ssidrefs Off  = %x.\n", ntohl(cwbuf->chwall_ssid_offset));
   4.122 +    printf("Conflicts Off = %x.\n",
   4.123 +           ntohl(cwbuf->chwall_conflict_sets_offset));
   4.124 +    printf("Runing T. Off = %x.\n",
   4.125 +           ntohl(cwbuf->chwall_running_types_offset));
   4.126 +    printf("C. Agg. Off   = %x.\n",
   4.127 +           ntohl(cwbuf->chwall_conflict_aggregate_offset));
   4.128 +    printf("\nSSID To CHWALL-Type matrix:\n");
   4.129 +
   4.130 +    ssids = (domaintype_t *) (buf + ntohl(cwbuf->chwall_ssid_offset));
   4.131 +    for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++)
   4.132 +    {
   4.133 +        printf("\n   ssidref%2x:  ", i);
   4.134 +        for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
   4.135 +            printf("%02x ",
   4.136 +                   ntohs(ssids[i * ntohl(cwbuf->chwall_max_types) + j]));
   4.137 +    }
   4.138 +    printf("\n\nConfict Sets:\n");
   4.139 +    conflicts =
   4.140 +        (domaintype_t *) (buf + ntohl(cwbuf->chwall_conflict_sets_offset));
   4.141 +    for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++)
   4.142 +    {
   4.143 +        printf("\n   c-set%2x:    ", i);
   4.144 +        for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
   4.145 +            printf("%02x ",
   4.146 +                   ntohs(conflicts
   4.147 +                         [i * ntohl(cwbuf->chwall_max_types) + j]));
   4.148 +    }
   4.149 +    printf("\n");
   4.150 +
   4.151 +    printf("\nRunning\nTypes:         ");
   4.152 +    if (ntohl(cwbuf->chwall_running_types_offset))
   4.153 +    {
   4.154 +        running_types =
   4.155 +            (domaintype_t *) (buf +
   4.156 +                              ntohl(cwbuf->chwall_running_types_offset));
   4.157 +        for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
   4.158 +        {
   4.159 +            printf("%02x ", ntohs(running_types[i]));
   4.160 +        }
   4.161 +        printf("\n");
   4.162 +    } else {
   4.163 +        printf("Not Reported!\n");
   4.164 +    }
   4.165 +    printf("\nConflict\nAggregate Set: ");
   4.166 +    if (ntohl(cwbuf->chwall_conflict_aggregate_offset))
   4.167 +    {
   4.168 +        conflict_aggregate =
   4.169 +            (domaintype_t *) (buf +
   4.170 +                              ntohl(cwbuf->chwall_conflict_aggregate_offset));
   4.171 +        for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
   4.172 +        {
   4.173 +            printf("%02x ", ntohs(conflict_aggregate[i]));
   4.174 +        }
   4.175 +        printf("\n\n");
   4.176 +    } else {
   4.177 +        printf("Not Reported!\n");
   4.178 +    }
   4.179 +}
   4.180 +
   4.181 +void acm_dump_ste_buffer(void *buf, int buflen)
   4.182 +{
   4.183 +
   4.184 +    struct acm_ste_policy_buffer *stebuf =
   4.185 +        (struct acm_ste_policy_buffer *) buf;
   4.186 +    domaintype_t *ssids;
   4.187 +    int i, j;
   4.188 +
   4.189 +
   4.190 +    if (ntohl(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
   4.191 +        printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
   4.192 +        return;
   4.193 +    }
   4.194 +    printf("\nSimple Type Enforcement policy:\n");
   4.195 +    printf("===============================\n");
   4.196 +    printf("Policy version= %x.\n", ntohl(stebuf->policy_version));
   4.197 +    printf("Max Types     = %x.\n", ntohl(stebuf->ste_max_types));
   4.198 +    printf("Max Ssidrefs  = %x.\n", ntohl(stebuf->ste_max_ssidrefs));
   4.199 +    printf("Ssidrefs Off  = %x.\n", ntohl(stebuf->ste_ssid_offset));
   4.200 +    printf("\nSSID To STE-Type matrix:\n");
   4.201 +
   4.202 +    ssids = (domaintype_t *) (buf + ntohl(stebuf->ste_ssid_offset));
   4.203 +    for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++)
   4.204 +    {
   4.205 +        printf("\n   ssidref%2x: ", i);
   4.206 +        for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
   4.207 +            printf("%02x ", ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
   4.208 +    }
   4.209 +    printf("\n\n");
   4.210 +}
   4.211 +
   4.212 +void acm_dump_policy_buffer(void *buf, int buflen)
   4.213 +{
   4.214 +    struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
   4.215 +
   4.216 +    printf("\nPolicy dump:\n");
   4.217 +    printf("============\n");
   4.218 +    printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
   4.219 +    printf("Magic     = %x.\n", ntohl(pol->magic));
   4.220 +    printf("Len       = %x.\n", ntohl(pol->len));
   4.221 +    printf("Primary   = %s (c=%x, off=%x).\n",
   4.222 +           ACM_POLICY_NAME(ntohl(pol->primary_policy_code)),
   4.223 +           ntohl(pol->primary_policy_code),
   4.224 +           ntohl(pol->primary_buffer_offset));
   4.225 +    printf("Secondary = %s (c=%x, off=%x).\n",
   4.226 +           ACM_POLICY_NAME(ntohl(pol->secondary_policy_code)),
   4.227 +           ntohl(pol->secondary_policy_code),
   4.228 +           ntohl(pol->secondary_buffer_offset));
   4.229 +    switch (ntohl(pol->primary_policy_code))
   4.230 +    {
   4.231 +    case ACM_CHINESE_WALL_POLICY:
   4.232 +        acm_dump_chinesewall_buffer(buf +
   4.233 +                                    ntohl(pol->primary_buffer_offset),
   4.234 +                                    ntohl(pol->len) -
   4.235 +                                    ntohl(pol->primary_buffer_offset));
   4.236 +        break;
   4.237 +
   4.238 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   4.239 +        acm_dump_ste_buffer(buf + ntohl(pol->primary_buffer_offset),
   4.240 +                            ntohl(pol->len) -
   4.241 +                            ntohl(pol->primary_buffer_offset));
   4.242 +        break;
   4.243 +
   4.244 +    case ACM_NULL_POLICY:
   4.245 +        printf("Primary policy is NULL Policy (n/a).\n");
   4.246 +        break;
   4.247 +
   4.248 +    default:
   4.249 +        printf("UNKNOWN POLICY!\n");
   4.250 +    }
   4.251 +
   4.252 +    switch (ntohl(pol->secondary_policy_code))
   4.253 +    {
   4.254 +    case ACM_CHINESE_WALL_POLICY:
   4.255 +        acm_dump_chinesewall_buffer(buf +
   4.256 +                                    ntohl(pol->secondary_buffer_offset),
   4.257 +                                    ntohl(pol->len) -
   4.258 +                                    ntohl(pol->secondary_buffer_offset));
   4.259 +        break;
   4.260 +
   4.261 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   4.262 +        acm_dump_ste_buffer(buf + ntohl(pol->secondary_buffer_offset),
   4.263 +                            ntohl(pol->len) -
   4.264 +                            ntohl(pol->secondary_buffer_offset));
   4.265 +        break;
   4.266 +
   4.267 +    case ACM_NULL_POLICY:
   4.268 +        printf("Secondary policy is NULL Policy (n/a).\n");
   4.269 +        break;
   4.270 +
   4.271 +    default:
   4.272 +        printf("UNKNOWN POLICY!\n");
   4.273 +    }
   4.274 +}
   4.275 +
   4.276 +/*************************** set policy ****************************/
   4.277 +
   4.278 +int acm_domain_set_chwallpolicy(void *bufstart, int buflen)
   4.279 +{
   4.280 +#define CWALL_MAX_SSIDREFS      	6
   4.281 +#define CWALL_MAX_TYPES             10
   4.282 +#define CWALL_MAX_CONFLICTSETS		2
   4.283 +
   4.284 +    struct acm_chwall_policy_buffer *chwall_bin_pol =
   4.285 +        (struct acm_chwall_policy_buffer *) bufstart;
   4.286 +    domaintype_t *ssidrefs, *conflicts;
   4.287 +    int ret = 0;
   4.288 +    int j;
   4.289 +
   4.290 +    chwall_bin_pol->chwall_max_types = htonl(CWALL_MAX_TYPES);
   4.291 +    chwall_bin_pol->chwall_max_ssidrefs = htonl(CWALL_MAX_SSIDREFS);
   4.292 +    chwall_bin_pol->policy_code = htonl(ACM_CHINESE_WALL_POLICY);
   4.293 +    chwall_bin_pol->policy_version = htonl(ACM_CHWALL_VERSION);
   4.294 +    chwall_bin_pol->chwall_ssid_offset =
   4.295 +        htonl(sizeof(struct acm_chwall_policy_buffer));
   4.296 +    chwall_bin_pol->chwall_max_conflictsets =
   4.297 +        htonl(CWALL_MAX_CONFLICTSETS);
   4.298 +    chwall_bin_pol->chwall_conflict_sets_offset =
   4.299 +        htonl(ntohl(chwall_bin_pol->chwall_ssid_offset) +
   4.300 +              sizeof(domaintype_t) * CWALL_MAX_SSIDREFS * CWALL_MAX_TYPES);
   4.301 +    chwall_bin_pol->chwall_running_types_offset = 0;    /* not set */
   4.302 +    chwall_bin_pol->chwall_conflict_aggregate_offset = 0;       /* not set */
   4.303 +    ret += sizeof(struct acm_chwall_policy_buffer);
   4.304 +    /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
   4.305 +    /* check buffer size */
   4.306 +    if ((buflen - ret) <
   4.307 +        (CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t)))
   4.308 +        return -1;              /* not enough space */
   4.309 +
   4.310 +    ssidrefs = (domaintype_t *) (bufstart +
   4.311 +                          ntohl(chwall_bin_pol->chwall_ssid_offset));
   4.312 +    memset(ssidrefs, 0,
   4.313 +           CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t));
   4.314 +
   4.315 +    /* now set type j-1 for ssidref i+1 */
   4.316 +    for (j = 0; j <= CWALL_MAX_SSIDREFS; j++)
   4.317 +        if ((0 < j) && (j <= CWALL_MAX_TYPES))
   4.318 +            ssidrefs[j * CWALL_MAX_TYPES + j - 1] = htons(1);
   4.319 +
   4.320 +    ret += CWALL_MAX_TYPES * CWALL_MAX_SSIDREFS * sizeof(domaintype_t);
   4.321 +    if ((buflen - ret) <
   4.322 +        (CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES * sizeof(domaintype_t)))
   4.323 +        return -1;              /* not enough space */
   4.324 +
   4.325 +    /* now the chinese wall policy conflict sets */
   4.326 +    conflicts = (domaintype_t *) (bufstart +
   4.327 +                                  ntohl(chwall_bin_pol->
   4.328 +                                        chwall_conflict_sets_offset));
   4.329 +    memset((void *) conflicts, 0,
   4.330 +           CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES *
   4.331 +           sizeof(domaintype_t));
   4.332 +    /* just 1 conflict set [0]={2,3}, [1]={1,5,6} */
   4.333 +    if (CWALL_MAX_TYPES > 3)
   4.334 +    {
   4.335 +        conflicts[2] = htons(1);
   4.336 +        conflicts[3] = htons(1);        /* {2,3} */
   4.337 +        conflicts[CWALL_MAX_TYPES + 1] = htons(1);
   4.338 +        conflicts[CWALL_MAX_TYPES + 5] = htons(1);
   4.339 +        conflicts[CWALL_MAX_TYPES + 6] = htons(1);      /* {0,5,6} */
   4.340 +    }
   4.341 +    ret += sizeof(domaintype_t) * CWALL_MAX_CONFLICTSETS * CWALL_MAX_TYPES;
   4.342 +    return ret;
   4.343 +}
   4.344 +
   4.345 +int acm_domain_set_stepolicy(void *bufstart, int buflen)
   4.346 +{
   4.347 +#define STE_MAX_SSIDREFS        6
   4.348 +#define STE_MAX_TYPES  	        5
   4.349 +
   4.350 +    struct acm_ste_policy_buffer *ste_bin_pol =
   4.351 +        (struct acm_ste_policy_buffer *) bufstart;
   4.352 +    domaintype_t *ssidrefs;
   4.353 +    int j, ret = 0;
   4.354 +
   4.355 +    ste_bin_pol->ste_max_types = htonl(STE_MAX_TYPES);
   4.356 +    ste_bin_pol->ste_max_ssidrefs = htonl(STE_MAX_SSIDREFS);
   4.357 +    ste_bin_pol->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
   4.358 +    ste_bin_pol->policy_version = htonl(ACM_STE_VERSION);
   4.359 +    ste_bin_pol->ste_ssid_offset =
   4.360 +        htonl(sizeof(struct acm_ste_policy_buffer));
   4.361 +    ret += sizeof(struct acm_ste_policy_buffer);
   4.362 +    /* check buffer size */
   4.363 +    if ((buflen - ret) <
   4.364 +        (STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t)))
   4.365 +        return -1;              /* not enough space */
   4.366 +
   4.367 +    ssidrefs =
   4.368 +        (domaintype_t *) (bufstart + ntohl(ste_bin_pol->ste_ssid_offset));
   4.369 +    memset(ssidrefs, 0,
   4.370 +           STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t));
   4.371 +    /* all types 1 for ssidref 1 */
   4.372 +    for (j = 0; j < STE_MAX_TYPES; j++)
   4.373 +        ssidrefs[1 * STE_MAX_TYPES + j] = htons(1);
   4.374 +    /* now set type j-1 for ssidref j */
   4.375 +    for (j = 0; j < STE_MAX_SSIDREFS; j++)
   4.376 +        if ((0 < j) && (j <= STE_MAX_TYPES))
   4.377 +            ssidrefs[j * STE_MAX_TYPES + j - 1] = htons(1);
   4.378 +    ret += STE_MAX_TYPES * STE_MAX_SSIDREFS * sizeof(domaintype_t);
   4.379 +    return ret;
   4.380 +}
   4.381 +
   4.382 +#define MAX_PUSH_BUFFER 	16384
   4.383 +u8 push_buffer[MAX_PUSH_BUFFER];
   4.384 +
   4.385 +int acm_domain_setpolicy(int xc_handle)
   4.386 +{
   4.387 +    int ret;
   4.388 +    struct acm_policy_buffer *bin_pol;
   4.389 +    acm_op_t op;
   4.390 +
   4.391 +    /* future: read policy from file and set it */
   4.392 +    bin_pol = (struct acm_policy_buffer *) push_buffer;
   4.393 +    bin_pol->policy_version = htonl(ACM_POLICY_VERSION);
   4.394 +    bin_pol->magic = htonl(ACM_MAGIC);
   4.395 +    bin_pol->primary_policy_code = htonl(ACM_CHINESE_WALL_POLICY);
   4.396 +    bin_pol->secondary_policy_code =
   4.397 +        htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
   4.398 +
   4.399 +    bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
   4.400 +    bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len));
   4.401 +    ret =
   4.402 +        acm_domain_set_chwallpolicy(push_buffer +
   4.403 +                                    ntohl(bin_pol->primary_buffer_offset),
   4.404 +                                    MAX_PUSH_BUFFER -
   4.405 +                                    ntohl(bin_pol->primary_buffer_offset));
   4.406 +    if (ret < 0)
   4.407 +    {
   4.408 +        printf("ERROR creating chwallpolicy buffer.\n");
   4.409 +        return -1;
   4.410 +    }
   4.411 +    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
   4.412 +    bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
   4.413 +    ret = acm_domain_set_stepolicy(push_buffer +
   4.414 +                                 ntohl(bin_pol->secondary_buffer_offset),
   4.415 +                                 MAX_PUSH_BUFFER -
   4.416 +                                 ntohl(bin_pol->secondary_buffer_offset));
   4.417 +    if (ret < 0)
   4.418 +    {
   4.419 +        printf("ERROR creating chwallpolicy buffer.\n");
   4.420 +        return -1;
   4.421 +    }
   4.422 +    bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
   4.423 +
   4.424 +    /* dump it and then push it down into xen/acm */
   4.425 +    acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
   4.426 +
   4.427 +    op.cmd = ACM_SETPOLICY;
   4.428 +    op.interface_version = ACM_INTERFACE_VERSION;
   4.429 +    op.u.setpolicy.pushcache = (void *) push_buffer;
   4.430 +    op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
   4.431 +    ret = do_acm_op(xc_handle, &op);
   4.432 +
   4.433 +    if (ret)
   4.434 +        printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
   4.435 +    else
   4.436 +        printf("Successfully changed policy.\n");
   4.437 +
   4.438 +    return ret;
   4.439 +}
   4.440 +
   4.441 +/******************************* get policy ******************************/
   4.442 +
   4.443 +#define PULL_CACHE_SIZE		8192
   4.444 +u8 pull_buffer[PULL_CACHE_SIZE];
   4.445 +int acm_domain_getpolicy(int xc_handle)
   4.446 +{
   4.447 +    acm_op_t op;
   4.448 +    int ret;
   4.449 +
   4.450 +    memset(pull_buffer, 0x00, sizeof(pull_buffer));
   4.451 +    op.cmd = ACM_GETPOLICY;
   4.452 +    op.interface_version = ACM_INTERFACE_VERSION;
   4.453 +    op.u.getpolicy.pullcache = (void *) pull_buffer;
   4.454 +    op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
   4.455 +    ret = do_acm_op(xc_handle, &op);
   4.456 +    /* dump policy  */
   4.457 +    acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
   4.458 +    return ret;
   4.459 +}
   4.460 +
   4.461 +/************************ load binary policy ******************************/
   4.462 +
   4.463 +int acm_domain_loadpolicy(int xc_handle, const char *filename)
   4.464 +{
   4.465 +    struct stat mystat;
   4.466 +    int ret, fd;
   4.467 +    off_t len;
   4.468 +    u8 *buffer;
   4.469 +
   4.470 +    if ((ret = stat(filename, &mystat)))
   4.471 +    {
   4.472 +        printf("File %s not found.\n", filename);
   4.473 +        goto out;
   4.474 +    }
   4.475 +
   4.476 +    len = mystat.st_size;
   4.477 +    if ((buffer = malloc(len)) == NULL)
   4.478 +    {
   4.479 +        ret = -ENOMEM;
   4.480 +        goto out;
   4.481 +    }
   4.482 +    if ((fd = open(filename, O_RDONLY)) <= 0)
   4.483 +    {
   4.484 +        ret = -ENOENT;
   4.485 +        printf("File %s not found.\n", filename);
   4.486 +        goto free_out;
   4.487 +    }
   4.488 +    if (len == read(fd, buffer, len))
   4.489 +    {
   4.490 +        acm_op_t op;
   4.491 +        /* dump it and then push it down into xen/acm */
   4.492 +        acm_dump_policy_buffer(buffer, len);
   4.493 +        op.cmd = ACM_SETPOLICY;
   4.494 +        op.interface_version = ACM_INTERFACE_VERSION;
   4.495 +        op.u.setpolicy.pushcache = (void *) buffer;
   4.496 +        op.u.setpolicy.pushcache_size = len;
   4.497 +        ret = do_acm_op(xc_handle, &op);
   4.498 +
   4.499 +        if (ret)
   4.500 +            printf
   4.501 +                ("ERROR setting policy. Use 'xm dmesg' to see details.\n");
   4.502 +        else
   4.503 +            printf("Successfully changed policy.\n");
   4.504 +
   4.505 +    } else {
   4.506 +        ret = -1;
   4.507 +    }
   4.508 +    close(fd);
   4.509 +  free_out:
   4.510 +    free(buffer);
   4.511 +  out:
   4.512 +    return ret;
   4.513 +}
   4.514 +
   4.515 +/************************ dump hook statistics ******************************/
   4.516 +void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
   4.517 +{
   4.518 +    printf("STE-Policy Security Hook Statistics:\n");
   4.519 +    printf("ste: event_channel eval_count      = %d\n",
   4.520 +           ntohl(ste_stats->ec_eval_count));
   4.521 +    printf("ste: event_channel denied_count    = %d\n",
   4.522 +           ntohl(ste_stats->ec_denied_count));
   4.523 +    printf("ste: event_channel cache_hit_count = %d\n",
   4.524 +           ntohl(ste_stats->ec_cachehit_count));
   4.525 +    printf("ste:\n");
   4.526 +    printf("ste: grant_table   eval_count      = %d\n",
   4.527 +           ntohl(ste_stats->gt_eval_count));
   4.528 +    printf("ste: grant_table   denied_count    = %d\n",
   4.529 +           ntohl(ste_stats->gt_denied_count));
   4.530 +    printf("ste: grant_table   cache_hit_count = %d\n",
   4.531 +           ntohl(ste_stats->gt_cachehit_count));
   4.532 +}
   4.533 +
   4.534 +#define PULL_STATS_SIZE		8192
   4.535 +int acm_domain_dumpstats(int xc_handle)
   4.536 +{
   4.537 +    u8 stats_buffer[PULL_STATS_SIZE];
   4.538 +    acm_op_t op;
   4.539 +    int ret;
   4.540 +    struct acm_stats_buffer *stats;
   4.541 +
   4.542 +    memset(stats_buffer, 0x00, sizeof(stats_buffer));
   4.543 +    op.cmd = ACM_DUMPSTATS;
   4.544 +    op.interface_version = ACM_INTERFACE_VERSION;
   4.545 +    op.u.dumpstats.pullcache = (void *) stats_buffer;
   4.546 +    op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
   4.547 +    ret = do_acm_op(xc_handle, &op);
   4.548 +
   4.549 +    if (ret < 0)
   4.550 +    {
   4.551 +        printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
   4.552 +        return ret;
   4.553 +    }
   4.554 +    stats = (struct acm_stats_buffer *) stats_buffer;
   4.555 +
   4.556 +    printf("\nPolicy dump:\n");
   4.557 +    printf("============\n");
   4.558 +    printf("Magic     = %x.\n", ntohl(stats->magic));
   4.559 +    printf("Len       = %x.\n", ntohl(stats->len));
   4.560 +
   4.561 +    switch (ntohl(stats->primary_policy_code))
   4.562 +    {
   4.563 +    case ACM_NULL_POLICY:
   4.564 +        printf("NULL Policy: No statistics apply.\n");
   4.565 +        break;
   4.566 +
   4.567 +    case ACM_CHINESE_WALL_POLICY:
   4.568 +        printf("Chinese Wall Policy: No statistics apply.\n");
   4.569 +        break;
   4.570 +
   4.571 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   4.572 +        dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
   4.573 +                                                        ntohl(stats->
   4.574 +                                                              primary_stats_offset)));
   4.575 +        break;
   4.576 +
   4.577 +    default:
   4.578 +        printf("UNKNOWN PRIMARY POLICY ERROR!\n");
   4.579 +    }
   4.580 +
   4.581 +    switch (ntohl(stats->secondary_policy_code))
   4.582 +    {
   4.583 +    case ACM_NULL_POLICY:
   4.584 +        printf("NULL Policy: No statistics apply.\n");
   4.585 +        break;
   4.586 +
   4.587 +    case ACM_CHINESE_WALL_POLICY:
   4.588 +        printf("Chinese Wall Policy: No statistics apply.\n");
   4.589 +        break;
   4.590 +
   4.591 +    case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
   4.592 +        dump_ste_stats((struct acm_ste_stats_buffer *) (stats_buffer +
   4.593 +                                                        ntohl(stats->
   4.594 +                                                              secondary_stats_offset)));
   4.595 +        break;
   4.596 +
   4.597 +    default:
   4.598 +        printf("UNKNOWN SECONDARY POLICY ERROR!\n");
   4.599 +    }
   4.600 +    return ret;
   4.601 +}
   4.602 +
   4.603 +/***************************** main **************************************/
   4.604 +
   4.605 +void usage(char *progname)
   4.606 +{
   4.607 +    printf("Use: %s \n"
   4.608 +           "\t setpolicy\n"
   4.609 +           "\t getpolicy\n"
   4.610 +           "\t dumpstats\n"
   4.611 +           "\t loadpolicy <binary policy file>\n", progname);
   4.612 +    exit(-1);
   4.613 +}
   4.614 +
   4.615 +int main(int argc, char **argv)
   4.616 +{
   4.617 +
   4.618 +    int acm_cmd_fd, ret;
   4.619 +
   4.620 +    if (argc < 2)
   4.621 +        usage(argv[0]);
   4.622 +
   4.623 +    if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0)
   4.624 +    {
   4.625 +        printf("ERROR: Could not open xen privcmd device!\n");
   4.626 +        exit(-1);
   4.627 +    }
   4.628 +
   4.629 +    if (!strcmp(argv[1], "setpolicy"))
   4.630 +    {
   4.631 +        if (argc != 2)
   4.632 +            usage(argv[0]);
   4.633 +        ret = acm_domain_setpolicy(acm_cmd_fd);
   4.634 +    } else if (!strcmp(argv[1], "getpolicy")) {
   4.635 +        if (argc != 2)
   4.636 +            usage(argv[0]);
   4.637 +        ret = acm_domain_getpolicy(acm_cmd_fd);
   4.638 +    } else if (!strcmp(argv[1], "loadpolicy")) {
   4.639 +        if (argc != 3)
   4.640 +            usage(argv[0]);
   4.641 +        ret = acm_domain_loadpolicy(acm_cmd_fd, argv[2]);
   4.642 +    } else if (!strcmp(argv[1], "dumpstats")) {
   4.643 +        if (argc != 2)
   4.644 +            usage(argv[0]);
   4.645 +        ret = acm_domain_dumpstats(acm_cmd_fd);
   4.646 +    } else
   4.647 +        usage(argv[0]);
   4.648 +
   4.649 +    close(acm_cmd_fd);
   4.650 +    return ret;
   4.651 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/common/acm_ops.c	Tue Aug 02 10:15:17 2005 +0000
     5.3 @@ -0,0 +1,127 @@
     5.4 +/******************************************************************************
     5.5 + * acm_ops.c
     5.6 + *
     5.7 + * Copyright (C) 2005 IBM Corporation
     5.8 + *
     5.9 + * Author:
    5.10 + * Reiner Sailer <sailer@watson.ibm.com>
    5.11 + *
    5.12 + * This program is free software; you can redistribute it and/or
    5.13 + * modify it under the terms of the GNU General Public License as
    5.14 + * published by the Free Software Foundation, version 2 of the
    5.15 + * License.
    5.16 + *
    5.17 + * Process acm command requests from guest OS.
    5.18 + *
    5.19 + */
    5.20 +
    5.21 +#include <xen/config.h>
    5.22 +#include <xen/types.h>
    5.23 +#include <xen/lib.h>
    5.24 +#include <xen/mm.h>
    5.25 +#include <public/acm_ops.h>
    5.26 +#include <xen/sched.h>
    5.27 +#include <xen/event.h>
    5.28 +#include <xen/trace.h>
    5.29 +#include <xen/console.h>
    5.30 +#include <asm/shadow.h>
    5.31 +#include <public/sched_ctl.h>
    5.32 +#include <acm/acm_hooks.h>
    5.33 +
    5.34 +#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
    5.35 +
    5.36 +long do_acm_op(acm_op_t * u_acm_op)
    5.37 +{
    5.38 +    return -ENOSYS;
    5.39 +}
    5.40 +
    5.41 +#else
    5.42 +
    5.43 +typedef enum acm_operation {
    5.44 +    POLICY,                     /* access to policy interface (early drop) */
    5.45 +    GETPOLICY,                  /* dump policy cache */
    5.46 +    SETPOLICY,                  /* set policy cache (controls security) */
    5.47 +    DUMPSTATS                   /* dump policy statistics */
    5.48 +} acm_operation_t;
    5.49 +
    5.50 +int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops)
    5.51 +{
    5.52 +    /* all policy management functions are restricted to privileged domains,
    5.53 +     * soon we will introduce finer-grained privileges for policy operations
    5.54 +     */
    5.55 +    if (!IS_PRIV(d))
    5.56 +    {
    5.57 +        printk("%s: ACM management authorization denied ERROR!\n", __func__);
    5.58 +        return ACM_ACCESS_DENIED;
    5.59 +    }
    5.60 +    return ACM_ACCESS_PERMITTED;
    5.61 +}
    5.62 +
    5.63 +long do_acm_op(acm_op_t * u_acm_op)
    5.64 +{
    5.65 +    long ret = 0;
    5.66 +    acm_op_t curop, *op = &curop;
    5.67 +
    5.68 +    /* check here policy decision for policy commands */
    5.69 +    /* for now allow DOM0 only, later indepedently    */
    5.70 +    if (acm_authorize_acm_ops(current->domain, POLICY))
    5.71 +        return -EACCES;
    5.72 +
    5.73 +    if (copy_from_user(op, u_acm_op, sizeof(*op)))
    5.74 +        return -EFAULT;
    5.75 +
    5.76 +    if (op->interface_version != ACM_INTERFACE_VERSION)
    5.77 +        return -EACCES;
    5.78 +
    5.79 +    switch (op->cmd)
    5.80 +    {
    5.81 +    case ACM_SETPOLICY:
    5.82 +        {
    5.83 +            if (acm_authorize_acm_ops(current->domain, SETPOLICY))
    5.84 +                return -EACCES;
    5.85 +            printkd("%s: setting policy.\n", __func__);
    5.86 +            ret = acm_set_policy(op->u.setpolicy.pushcache,
    5.87 +                                 op->u.setpolicy.pushcache_size, 1);
    5.88 +            if (ret == ACM_OK)
    5.89 +                ret = 0;
    5.90 +            else
    5.91 +                ret = -ESRCH;
    5.92 +        }
    5.93 +        break;
    5.94 +
    5.95 +    case ACM_GETPOLICY:
    5.96 +        {
    5.97 +            if (acm_authorize_acm_ops(current->domain, GETPOLICY))
    5.98 +                return -EACCES;
    5.99 +            printkd("%s: getting policy.\n", __func__);
   5.100 +            ret = acm_get_policy(op->u.getpolicy.pullcache,
   5.101 +                                 op->u.getpolicy.pullcache_size);
   5.102 +            if (ret == ACM_OK)
   5.103 +                ret = 0;
   5.104 +            else
   5.105 +                ret = -ESRCH;
   5.106 +        }
   5.107 +        break;
   5.108 +
   5.109 +    case ACM_DUMPSTATS:
   5.110 +        {
   5.111 +            if (acm_authorize_acm_ops(current->domain, DUMPSTATS))
   5.112 +                return -EACCES;
   5.113 +            printkd("%s: dumping statistics.\n", __func__);
   5.114 +            ret = acm_dump_statistics(op->u.dumpstats.pullcache,
   5.115 +                                      op->u.dumpstats.pullcache_size);
   5.116 +            if (ret == ACM_OK)
   5.117 +                ret = 0;
   5.118 +            else
   5.119 +                ret = -ESRCH;
   5.120 +        }
   5.121 +        break;
   5.122 +
   5.123 +    default:
   5.124 +        ret = -ESRCH;
   5.125 +
   5.126 +    }
   5.127 +    return ret;
   5.128 +}
   5.129 +
   5.130 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/include/public/acm_ops.h	Tue Aug 02 10:15:17 2005 +0000
     6.3 @@ -0,0 +1,66 @@
     6.4 +/******************************************************************************
     6.5 + * acm_ops.h
     6.6 + *
     6.7 + * Copyright (C) 2005 IBM Corporation
     6.8 + *
     6.9 + * Author:
    6.10 + * Reiner Sailer <sailer@watson.ibm.com>
    6.11 + *
    6.12 + * This program is free software; you can redistribute it and/or
    6.13 + * modify it under the terms of the GNU General Public License as
    6.14 + * published by the Free Software Foundation, version 2 of the
    6.15 + * License.
    6.16 + *
    6.17 + * Process acm policy command requests from guest OS.
    6.18 + * access checked by policy; not restricted to DOM0
    6.19 + *
    6.20 + */
    6.21 +
    6.22 +#ifndef __XEN_PUBLIC_ACM_OPS_H__
    6.23 +#define __XEN_PUBLIC_ACM_OPS_H__
    6.24 +
    6.25 +#include "xen.h"
    6.26 +#include "sched_ctl.h"
    6.27 +
    6.28 +/*
    6.29 + * Make sure you increment the interface version whenever you modify this file!
    6.30 + * This makes sure that old versions of acm tools will stop working in a
    6.31 + * well-defined way (rather than crashing the machine, for instance).
    6.32 + */
    6.33 +#define ACM_INTERFACE_VERSION   0xAAAA0003
    6.34 +
    6.35 +/************************************************************************/
    6.36 +
    6.37 +#define ACM_SETPOLICY        	4
    6.38 +typedef struct acm_setpolicy {
    6.39 +    /* OUT variables */
    6.40 +    void *pushcache;
    6.41 +    u16 pushcache_size;
    6.42 +} acm_setpolicy_t;
    6.43 +
    6.44 +
    6.45 +#define ACM_GETPOLICY        	5
    6.46 +typedef struct acm_getpolicy {
    6.47 +    /* OUT variables */
    6.48 +    void *pullcache;
    6.49 +    u16 pullcache_size;
    6.50 +} acm_getpolicy_t;
    6.51 +
    6.52 +#define ACM_DUMPSTATS        	6
    6.53 +typedef struct acm_dumpstats {
    6.54 +    void *pullcache;
    6.55 +    u16 pullcache_size;
    6.56 +} acm_dumpstats_t;
    6.57 +
    6.58 +
    6.59 +typedef struct acm_op {
    6.60 +    u32 cmd;
    6.61 +    u32 interface_version;      /* ACM_INTERFACE_VERSION */
    6.62 +    union {
    6.63 +        acm_setpolicy_t setpolicy;
    6.64 +        acm_getpolicy_t getpolicy;
    6.65 +        acm_dumpstats_t dumpstats;
    6.66 +    } u;
    6.67 +} acm_op_t;
    6.68 +
    6.69 +#endif                          /* __XEN_PUBLIC_ACM_OPS_H__ */