* [patches] shype for xen / patches
@ 2005-03-30 5:11 Reiner Sailer
0 siblings, 0 replies; 3+ messages in thread
From: Reiner Sailer @ 2005-03-30 5:11 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 3268 bytes --]
Hi all,
For the past two months our team has worked to integrate the sHype
security architecture into Xen. sHype was initially discussed on the Xen
development emailing list in
http://lists.xensource.com/archives/html/xen-devel/2005-01/msg00519.html
and the implementation described here is based on the design published in
http://www.research.ibm.com/secure_systems_department/projects/hypervisor.
We have attached the stable patches of our port for the group to evaluate.
The code successfully enforces "sample" security policies and demonstrates
the minimal impact sHype has on both the main Xen code base and on Xen's
run-time performance. (I post the patches here tonight, and will follow
up by Thursday with a README and some examples.) The security enforcement
hooks cover domain operations, event channels, and also --as far as
available-- grant tables. These hooks will also cover save/restore/migrate
once these operations are working and stable.
Please note that the default policy under these patches is a "NULL"
policy. This means that, even after the patches are applied, there will
be *no* change to the user or administrator experience until a security
policy is explicitly enabled.
The sHype port consists of three patches (tested on the xeno-unstable.bk
version from March 29 th):
1. shype_4_xeno-unstable.bk_v0.2_xen.diff .. patch that includes the
security enforcement code and access control module, the heart of shype;
2. shype_4_xeno-unstable.bk_v0.2_sparse.diff .. kernel patch that includes
an additional /proc/xen/policycmd interface using a new policy hypercall
to communicate policies between xen and the policy management tool;
3. shype_4_xeno-unstable.bk_v0.2_tools.diff .. tools patch that includes
support for a new parameter security subject identifier reference
(ssidref) in the domain configuration, as well as a v-e-r-y simple policy
tool to set binary policies in xen and to retrieve and dump enforced
policies from xen (tools/policytool); in a future version, this tool will
read user-defined policies and compile them into the binary policies to be
downloaded into xen.
If you install the patches, please start with a clean xeno-unstable.bk
tree: make mrproper; make uninstall; >patch the code here<; make;
./install.sh. More instructions to follow.
Comments/feedback related to these patches are very welcome. Note that I
will not be able to read my email from April 1st to 11th. If anyone has
any quick questions I will try to answer them before I leave; otherwise,
please look through the code at your convenience and let us discuss
details once I am back. (Note that the code is still "under development"
-- for example, work continues on save/restore support & on revoking
resources to enable policy changes at run-time, as well as moving the
enforced policy from a hard-coded parameter to a compile-time option).
Kindest Regards
Reiner
Signed-off-by: Reiner Sailer
__________________________________________________________
Reiner Sailer, Research Staff Member, Secure Systems Department
IBM T J Watson Research Ctr, 19 Skyline Drive, Hawthorne NY 10532
Phone: 914 784 6280 (t/l 863) Fax: 914 784 6205, sailer@us.ibm.com
http://www.research.ibm.com/people/s/sailer/
[-- Attachment #1.2: Type: text/html, Size: 3995 bytes --]
[-- Attachment #2: shype_4_xeno-unstable.bk_v0.2_xen.diff --]
[-- Type: application/octet-stream, Size: 94654 bytes --]
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_chinesewall_hooks.c xeno-unstable.bk/xen/acm/acm_chinesewall_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_chinesewall_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_chinesewall_hooks.c 2005-03-29 23:18:49.462452328 -0500
@@ -0,0 +1,473 @@
+/****************************************************************
+ * acm_chinesewall_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype Chinese Wall Policy for Xen
+ * This code implements the hooks that are called
+ * throughout Xen operations and decides authorization
+ * based on domain types and Chinese Wall conflict type
+ * sets. The CHWALL policy decides if a new domain can be started
+ * based on the types of running domains and the type of the
+ * new domain to be started. If the new domain's type is in
+ * conflict with types of running domains, then this new domain
+ * is not allowed to be created. A domain can have multiple types,
+ * in which case all types of a new domain must be conflict-free
+ * with all types of already running domains.
+ *
+ */
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/acm.h>
+#include <acm/acm_core.h>
+#include <acm/acm_hooks.h>
+
+/* local cache structures for chinese wall policy */
+chwall_binary_policy_t chwall_bin_pol;
+
+/*
+ * Initializing chinese wall policy (will be filled by policy partition
+ * using setpolicy command)
+ */
+int acm_init_chwall_policy(void)
+{
+ /* minimal startup policy; policy write-locked already */
+ chwall_bin_pol.max_types = 1;
+ chwall_bin_pol.max_ssidrefs = 1;
+ chwall_bin_pol.max_conflictsets = 1;
+ chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
+ chwall_bin_pol.conflict_sets = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
+ chwall_bin_pol.running_types = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
+ chwall_bin_pol.conflict_aggregate_set = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
+
+ if ((chwall_bin_pol.conflict_sets == NULL) || (chwall_bin_pol.running_types == NULL) ||
+ (chwall_bin_pol.ssidrefs == NULL) || (chwall_bin_pol.conflict_aggregate_set == NULL))
+ return ACM_INIT_SSID_ERROR;
+
+ /* initialize state */
+ memset((void *)chwall_bin_pol.ssidrefs, 0, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.conflict_sets, 0, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.running_types, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));
+ return ACM_OK;
+}
+
+static int
+chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+{
+ chwall_ssid_t *chwall_ssidp = xmalloc(chwall_ssid_t);
+ traceprintk("%s.\n", __func__);
+ if (chwall_ssidp == NULL)
+ return ACM_INIT_SSID_ERROR;
+ /*
+ * depending on wheter chwall is primary or secondary, get the respective
+ * part of the global ssidref (same way we'll get the partial ssid pointer)
+ */
+ chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ if (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
+ printkd("%s: ERROR chwall_ssidref(%x) > max(%x).\n",
+ __func__, chwall_ssidp->chwall_ssidref, chwall_bin_pol.max_ssidrefs-1);
+ xfree(chwall_ssidp);
+ return ACM_INIT_SSID_ERROR;
+ }
+ (*chwall_ssid) = chwall_ssidp;
+ printkd("%s: determined chwall_ssidref to %x.\n",
+ __func__, chwall_ssidp->chwall_ssidref);
+ return ACM_OK;
+}
+
+static void
+chwall_free_domain_ssid(void *chwall_ssid)
+{
+ traceprintk("%s.\n", __func__);
+ if (chwall_ssid != NULL)
+ xfree(chwall_ssid);
+ return;
+}
+
+
+/* dump chinese wall cache; policy read-locked already */
+static int
+chwall_dump_policy(u8 *buf, u16 buf_size) {
+ acm_chwall_policy_buffer_t *chwall_buf = (acm_chwall_policy_buffer_t *)buf;;
+ int ret = 0;
+
+ chwall_buf->chwall_max_types = chwall_bin_pol.max_types;
+ chwall_buf->chwall_max_ssidrefs = chwall_bin_pol.max_ssidrefs;
+ chwall_buf->policy_code = ACM_CHINESE_WALL_POLICY;
+ chwall_buf->chwall_ssid_offset = sizeof(acm_chwall_policy_buffer_t);
+ chwall_buf->chwall_max_conflictsets = chwall_bin_pol.max_conflictsets;
+ chwall_buf->chwall_conflict_sets_offset =
+ chwall_buf->chwall_ssid_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types;
+
+ chwall_buf->chwall_running_types_offset =
+ chwall_buf->chwall_conflict_sets_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types;
+
+ chwall_buf->chwall_conflict_aggregate_offset =
+ chwall_buf->chwall_running_types_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_types;
+
+ ret = chwall_buf->chwall_conflict_aggregate_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_types;
+
+ /* now copy buffers over */
+ memcpy(buf + chwall_buf->chwall_ssid_offset,
+ chwall_bin_pol.ssidrefs,
+ sizeof(domaintype_t)*chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_conflict_sets_offset,
+ chwall_bin_pol.conflict_sets,
+ sizeof(domaintype_t)*chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_running_types_offset,
+ chwall_bin_pol.running_types,
+ sizeof(domaintype_t)*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_conflict_aggregate_offset,
+ chwall_bin_pol.conflict_aggregate_set,
+ sizeof(domaintype_t)*chwall_bin_pol.max_types);
+ return ret;
+}
+
+/* adapt security state (running_types and conflict_aggregate_set) to all running
+ * domains; chwall_init_state is called when a policy is changed to bring the security
+ * information into a consistent state and to detect violations (return != 0).
+ * from a security point of view, we simulate that all running domains are re-started
+ */
+static int
+chwall_init_state(acm_chwall_policy_buffer_t *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets,
+ domaintype_t *running_types, domaintype_t *conflict_aggregate_set)
+{
+ int violation = 0, i, j;
+ chwall_ssid_t *chwall_ssid;
+ ssidref_t chwall_ssidref;
+ struct domain **pd;
+
+ write_lock(&domlist_lock);
+ /* go through all domains and adjust policy as if this domain was started now */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list ) {
+ chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)(*pd)->ssid);
+ chwall_ssidref = chwall_ssid->chwall_ssidref;
+ traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
+ __func__, (*pd)->id, chwall_ssidref);
+ /* a) adjust types ref-count for running domains */
+ for (i=0; i< chwall_buf->chwall_max_types; i++)
+ running_types[i] +=
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i];
+
+ /* b) check for conflict */
+ for (i=0; i< chwall_buf->chwall_max_types; i++)
+ if (conflict_aggregate_set[i] &&
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) {
+ printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
+ violation = 1;
+ goto out;
+ }
+ /* set violation and break out of the loop */
+ /* c) adapt conflict aggregate set for this domain (notice conflicts) */
+ for (i=0; i<chwall_buf->chwall_max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_buf->chwall_max_types; j++)
+ if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_buf->chwall_max_types; j++)
+ if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
+ !ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j])
+ conflict_aggregate_set[j]++;
+ }
+ }
+ out:
+ write_unlock(&domlist_lock);
+ return violation;
+ /* returning "violation != 0" means that the currently running set of domains would
+ * not be possible if the new policy had been enforced before starting them; for chinese
+ * wall, this means that the new policy includes at least one conflict set of which
+ * more than one type is currently running */
+}
+
+static int
+chwall_set_policy(u8 *buf, u16 buf_size)
+{
+ /* policy write-locked already */
+ acm_chwall_policy_buffer_t *chwall_buf = (acm_chwall_policy_buffer_t *)buf;
+ void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL;
+
+ /* 1. allocate new buffers */
+ ssids = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
+ conflict_sets = xmalloc_array(domaintype_t, chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types);
+ running_types = xmalloc_array(domaintype_t,chwall_buf->chwall_max_types);
+ conflict_aggregate_set = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
+
+ if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == NULL)||(conflict_aggregate_set == NULL))
+ goto error_free;
+
+ /* 2. set new policy */
+ memcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
+ sizeof(domaintype_t)*chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
+ memcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
+ sizeof(domaintype_t)*chwall_buf->chwall_max_types*chwall_buf->chwall_max_conflictsets);
+ /* we also use new state buffers since max_types can change */
+ memset(running_types, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
+ memset(conflict_aggregate_set, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
+
+ /* 3. now re-calculate the state for the new policy based on running domains;
+ * this can fail if new policy is conflicting with running domains */
+ if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set)) {
+ printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
+ goto error_free; /* new policy conflicts with running domains */
+ }
+ /* 4. free old policy buffers, replace with new ones */
+ chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
+ chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
+ chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
+ if (chwall_bin_pol.ssidrefs != NULL)
+ xfree(chwall_bin_pol.ssidrefs);
+ if (chwall_bin_pol.conflict_aggregate_set != NULL)
+ xfree(chwall_bin_pol.conflict_aggregate_set);
+ if (chwall_bin_pol.running_types != NULL)
+ xfree(chwall_bin_pol.running_types);
+ if (chwall_bin_pol.conflict_sets != NULL)
+ xfree(chwall_bin_pol.conflict_sets);
+ chwall_bin_pol.ssidrefs = ssids;
+ chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
+ chwall_bin_pol.running_types = running_types;
+ chwall_bin_pol.conflict_sets = conflict_sets;
+ return ACM_OK;
+
+error_free:
+ printk("%s: ERROR setting policy.\n", __func__);
+ if (ssids != NULL) xfree(ssids);
+ if (conflict_sets != NULL) xfree(conflict_sets);
+ if (running_types != NULL) xfree(running_types);
+ if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set);
+ return -EFAULT;
+}
+
+/***************************
+ * Authorization functions
+ ***************************/
+
+
+/* -------- DOMAIN OPERATION HOOKS -----------*/
+
+static int
+chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ ssidref_t chwall_ssidref;
+ int i,j;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
+ printk("%s: ERROR chwall_ssidref > max(%x).\n",
+ __func__, chwall_bin_pol.max_ssidrefs-1);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+ /* A: chinese wall check for conflicts */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ if (chwall_bin_pol.conflict_aggregate_set[i] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) {
+ printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+
+ /* B: chinese wall conflict set adjustment (so that other
+ * other domains simultaneously created are evaluated against this new set)*/
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]++;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_PERMITTED;
+}
+
+static void
+chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
+{
+ int i,j;
+ ssidref_t chwall_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ /* adjust types ref-count for running domains */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ chwall_bin_pol.running_types[i] +=
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
+ if (domid) {
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+ }
+ /* Xen does not call pre-create hook for DOM0;
+ * to consider type conflicts of any domain with DOM0, we need
+ * to adjust the conflict_aggregate for DOM0 here the same way it
+ * is done for non-DOM0 domains in the pre-hook */
+ printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n",
+ __func__, ssidref, chwall_ssidref);
+
+ /* chinese wall conflict set adjustment (so that other
+ * other domains simultaneously created are evaluated against this new set)*/
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]++;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+}
+
+static void
+chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ int i, j;
+ ssidref_t chwall_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ /* roll-back: re-adjust conflicting types aggregate */
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]--;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+}
+
+
+static void
+chwall_post_domain_destroy(void *object_ssid)
+{
+ int i,j;
+ chwall_ssid_t *chwall_ssidp =
+ GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)object_ssid);
+ ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
+
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ /* adjust running types set */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ chwall_bin_pol.running_types[i] -=
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
+
+ /* roll-back: re-adjust conflicting types aggregate */
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]--;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+}
+
+struct acm_operations acm_chinesewall_ops = {
+ /* domain management control hooks */
+ .init_domain_ssid = chwall_init_domain_ssid,
+ .free_domain_ssid = chwall_free_domain_ssid,
+ .dump_binary_policy = chwall_dump_policy,
+ .set_binary_policy = chwall_set_policy,
+ .pre_domain_create = chwall_pre_domain_create,
+ .post_domain_create = chwall_post_domain_create,
+ .fail_domain_create = chwall_fail_domain_create,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = chwall_post_domain_destroy,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_core.c xeno-unstable.bk/xen/acm/acm_core.c
--- xeno-unstable.bk_orig/xen/acm/acm_core.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_core.c 2005-03-29 23:19:38.501997184 -0500
@@ -0,0 +1,182 @@
+/****************************************************************
+ * acm_core.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype access control module (ACM)
+ * This file handles initialization of the ACM
+ * as well as initializing/freeing security
+ * identifiers for domains (it calls on active
+ * policy hook functions).
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <acm/acm_hooks.h>
+
+/* debug:
+ * include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
+ * define/undefine this constant to receive / suppress any
+ * security hook debug output of sHype
+ *
+ * include/public/acm.h defines a constant ACM_DEBUG
+ * define/undefine this constant to receive non-hook-related
+ * debug output.
+ */
+
+/* function prototypes */
+void acm_init_chwall_policy(void);
+void acm_init_ste_policy(void);
+
+extern struct acm_operations acm_chinesewall_ops,
+ acm_simple_type_enforcement_ops, acm_null_ops;
+
+/* global ops structs called by the hooks */
+struct acm_operations *acm_primary_ops = NULL;
+/* called in hook if-and-only-if primary succeeds */
+struct acm_operations *acm_secondary_ops = NULL;
+
+/* acm global binary policy (points to 'local' primary and secondary policies */
+acm_binary_policy_t acm_bin_pol;
+/* acm binary policy lock */
+rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
+
+/* initialize global security policy for Xen; policy write-locked already */
+static void
+acm_init_binary_policy(void *primary, void *secondary)
+{
+ acm_bin_pol.primary_policy_code = 0;
+ acm_bin_pol.secondary_policy_code = 0;
+ acm_bin_pol.primary_binary_policy = primary;
+ acm_bin_pol.secondary_binary_policy = secondary;
+}
+
+int
+acm_init(void)
+{
+ int ret = -EINVAL;
+
+ write_lock(&acm_bin_pol_rwlock);
+
+ if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_chwall_policy();
+ acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ acm_primary_ops = &acm_chinesewall_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_ste_policy();
+ acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ acm_primary_ops = &acm_simple_type_enforcement_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_chwall_policy();
+ acm_init_ste_policy();
+ acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ acm_primary_ops = &acm_chinesewall_ops;
+ acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ acm_secondary_ops = &acm_simple_type_enforcement_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
+ acm_primary_ops = &acm_null_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ }
+ write_unlock(&acm_bin_pol_rwlock);
+
+ if (ret != ACM_OK)
+ return -EINVAL;
+ printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__,
+ ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
+ return ACM_OK;
+}
+
+
+int
+acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
+{
+ struct acm_ssid_domain *ssid;
+ struct domain *subj = find_domain_by_id(id);
+ int ret1, ret2;
+
+ if (subj == NULL) {
+ printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) {
+ return ACM_INIT_SSID_ERROR;
+ }
+ ssid->datatype = DOMAIN;
+ ssid->subject = subj;
+ ssid->domainid = subj->id;
+ ssid->ssidref = ssidref;
+ ssid->primary_ssid = NULL;
+ ssid->secondary_ssid = NULL;
+ subj->ssid = ssid;
+ /* now fill in primary and secondary parts; we only get here through hooks */
+ if (acm_primary_ops->init_domain_ssid != NULL)
+ ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
+ else
+ ret1 = ACM_OK;
+ if (acm_secondary_ops->init_domain_ssid != NULL)
+ ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
+ else
+ ret2 = ACM_OK;
+ if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
+ printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
+ __func__, subj->id);
+ acm_free_domain_ssid(ssid);
+ put_domain(subj);
+ return ACM_INIT_SSID_ERROR;
+ }
+ printkd("%s: Instantiated individual ssid for domain 0x%02x.\n",
+ __func__, subj->id);
+ put_domain(subj);
+ return ACM_OK;
+}
+
+
+int
+acm_free_domain_ssid(struct acm_ssid_domain *ssid)
+{
+ domid_t id;
+
+ if (ssid == NULL) {
+ printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ id = ssid->domainid;
+ ssid->subject = NULL;
+
+ if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
+ acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
+ ssid->primary_ssid = NULL;
+ if (acm_secondary_ops->free_domain_ssid != NULL)
+ acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
+ ssid->secondary_ssid = NULL;
+ xfree(ssid);
+ printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, id);
+ return ACM_OK;
+}
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_null_hooks.c xeno-unstable.bk/xen/acm/acm_null_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_null_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_null_hooks.c 2005-03-29 23:22:22.499065840 -0500
@@ -0,0 +1,54 @@
+/****************************************************************
+ * acm_null_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+#include <acm/acm_hooks.h>
+
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_null_ops = {
+ .init_domain_ssid = NULL,
+ .free_domain_ssid = NULL,
+ .dump_binary_policy = NULL,
+ .set_binary_policy = NULL,
+ /* domain management control hooks */
+ .pre_domain_create = NULL,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = NULL,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_policy.c xeno-unstable.bk/xen/acm/acm_policy.c
--- xeno-unstable.bk_orig/xen/acm/acm_policy.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_policy.c 2005-03-29 23:21:00.060598392 -0500
@@ -0,0 +1,148 @@
+/****************************************************************
+ * acm_policy.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype access control policy management for Xen.
+ * This interface allows policy tools in authorized
+ * domains to interact with the Xen access control module
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/policy_ops.h>
+#include <acm/acm_core.h>
+#include <acm/acm_hooks.h>
+
+int
+acm_set_policy(void *buf, u16 buf_size, u16 policy)
+{
+ u8 *policy_buffer = NULL;
+ acm_policy_buffer_t *pol;
+
+ if (policy != ACM_USE_SECURITY_POLICY) {
+ printk("%s: Loading incompatible policy (running: %s).\n", __func__,
+ ACM_POLICY_NAME(ACM_USE_SECURITY_POLICY));
+ return -EFAULT;
+ }
+ /* now check correct buffer sizes for policy combinations */
+ if (policy == ACM_NULL_POLICY) {
+ printkd("%s: NULL Policy, no policy needed.\n", __func__);
+ goto out;
+ }
+ if (buf_size < sizeof(acm_policy_buffer_t))
+ return -EFAULT;
+ /* 1. copy buffer from domain */
+ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ goto error_free;
+ if (copy_from_user(policy_buffer, buf, buf_size))
+ goto error_free;
+ /* 2. some sanity checking */
+ pol = (acm_policy_buffer_t *)policy_buffer;
+ if ((pol->magic != ACM_MAGIC) ||
+ (pol->primary_policy_code != acm_bin_pol.primary_policy_code) ||
+ (pol->secondary_policy_code != acm_bin_pol.secondary_policy_code)) {
+ printkd("%s: Wrong policy magics!\n", __func__);
+ goto error_free;
+ }
+ if (buf_size != pol->len) {
+ printk("%s: ERROR in buf size.\n", __func__);
+ goto error_free;
+ }
+ /* get bin_policy lock and rewrite policy (release old one) */
+ write_lock(&acm_bin_pol_rwlock);
+
+ /* 3. now get/set primary policy data */
+ if (acm_primary_ops->set_binary_policy(buf + pol->primary_buffer_offset,
+ pol->secondary_buffer_offset -
+ pol->primary_buffer_offset)) {
+ goto error_lock_free;
+ }
+ /* 4. now get/set secondary policy data */
+ if (acm_secondary_ops->set_binary_policy(buf + pol->secondary_buffer_offset,
+ pol->len -
+ pol->secondary_buffer_offset)) {
+ goto error_lock_free;
+ }
+ write_unlock(&acm_bin_pol_rwlock);
+ out:
+ printk("%s: Done .\n", __func__);
+ if (policy_buffer != NULL)
+ xfree(policy_buffer);
+ return ACM_OK;
+
+ error_lock_free:
+ write_unlock(&acm_bin_pol_rwlock);
+ error_free:
+ printk("%s: Error setting policy.\n", __func__);
+ if (policy_buffer != NULL)
+ xfree(policy_buffer);
+ return -ENOMEM;
+}
+
+int
+acm_get_policy(void *buf, u16 buf_size)
+{
+ u8 *policy_buffer;
+ int ret;
+ acm_policy_buffer_t *bin_pol;
+
+ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ return -ENOMEM;
+
+ read_lock(&acm_bin_pol_rwlock);
+ /* future: read policy from file and set it */
+ bin_pol = (acm_policy_buffer_t *)policy_buffer;
+ bin_pol->magic = ACM_MAGIC;
+ bin_pol->policyversion = POLICY_INTERFACE_VERSION;
+ bin_pol->primary_policy_code = acm_bin_pol.primary_policy_code;
+ bin_pol->secondary_policy_code = acm_bin_pol.secondary_policy_code;
+
+ bin_pol->len = sizeof(acm_policy_buffer_t);
+ bin_pol->primary_buffer_offset = bin_pol->len;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ if (acm_primary_ops->dump_binary_policy == NULL)
+ goto out_lock_free;
+
+ ret = acm_primary_ops->dump_binary_policy (policy_buffer + bin_pol->primary_buffer_offset,
+ buf_size - bin_pol->primary_buffer_offset);
+ if (ret < 0) {
+ printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return -1;
+ }
+ bin_pol->len += ret;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ if (acm_secondary_ops->dump_binary_policy == NULL)
+ goto out_lock_free;
+
+ ret = acm_secondary_ops->dump_binary_policy(policy_buffer + bin_pol->secondary_buffer_offset,
+ buf_size - bin_pol->secondary_buffer_offset);
+ if (ret < 0) {
+ printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return -1;
+ }
+ bin_pol->len += ret;
+
+ out_lock_free:
+ read_unlock(&acm_bin_pol_rwlock);
+ if (copy_to_user(buf, policy_buffer, bin_pol->len))
+ return -EFAULT;
+ xfree(policy_buffer);
+ return ACM_OK;
+}
+/*eof*/
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_simple_type_enforcement_hooks.c xeno-unstable.bk/xen/acm/acm_simple_type_enforcement_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_simple_type_enforcement_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_simple_type_enforcement_hooks.c 2005-03-29 23:21:41.529294192 -0500
@@ -0,0 +1,413 @@
+/****************************************************************
+ * acm_simple_type_enforcement_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype Simple Type Enforcement for Xen
+ * STE allows to control which domains can setup sharing
+ * (eventchannels right now) with which other domains. Hooks
+ * are defined and called throughout Xen when domains bind to
+ * shared resources (setup eventchannels) and a domain is allowed
+ * to setup sharing with another domain if and only if both domains
+ * share at least on common type.
+ *
+ */
+#include <acm/acm_hooks.h>
+
+/* local cache structures for chinese wall policy */
+ste_binary_policy_t ste_bin_pol;
+
+/*
+ * Initializing chinese wall policy (will be filled by policy partition
+ * using setpolicy command)
+ */
+int acm_init_ste_policy(void)
+{
+ /* minimal startup policy; policy write-locked already */
+ ste_bin_pol.max_types = 1;
+ ste_bin_pol.max_ssidrefs = 1;
+ ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 1);
+
+ if (ste_bin_pol.ssidrefs == NULL)
+ return ACM_INIT_SSID_ERROR;
+
+ /* initialize state */
+ ste_bin_pol.ssidrefs[0] = 1;
+
+ return ACM_OK;
+}
+
+
+/* ste initialization function hooks */
+static int
+ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
+{
+ ste_ssid_t *ste_ssidp = xmalloc(ste_ssid_t);
+ traceprintk("%s.\n", __func__);
+ if (ste_ssidp == NULL)
+ return ACM_INIT_SSID_ERROR;
+ /*
+ * depending on wheter chwall is primary or secondary, get the respective
+ * part of the global ssidref (same way we'll get the partial ssid pointer)
+ */
+ ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
+ if (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) {
+ printkd("%s: ERROR ste_ssidref (%x) > max(%x).\n",
+ __func__, ste_ssidp->ste_ssidref, ste_bin_pol.max_ssidrefs-1);
+ xfree(ste_ssidp);
+ return ACM_INIT_SSID_ERROR;
+ }
+ (*ste_ssid) = ste_ssidp;
+ printkd("%s: determined ste_ssidref to %x.\n",
+ __func__, ste_ssidp->ste_ssidref);
+ return ACM_OK;
+}
+
+static void
+ste_free_domain_ssid(void *ste_ssid)
+{
+ traceprintk("%s.\n", __func__);
+ if (ste_ssid != NULL)
+ xfree(ste_ssid);
+ return;
+}
+
+/* dump type enforcement cache; policy read-locked already */
+static int
+ste_dump_policy(u8 *buf, u16 buf_size) {
+ acm_ste_policy_buffer_t *ste_buf = (acm_ste_policy_buffer_t *)buf;
+ int ret = 0;
+
+ ste_buf->ste_max_types = ste_bin_pol.max_types;
+ ste_buf->ste_max_ssidrefs = ste_bin_pol.max_ssidrefs;
+ ste_buf->policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ste_buf->ste_ssid_offset = sizeof(acm_ste_policy_buffer_t);
+ ret = ste_buf->ste_ssid_offset +
+ sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
+
+ /* now copy buffer over */
+ memcpy(buf + ste_buf->ste_ssid_offset,
+ ste_bin_pol.ssidrefs,
+ sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
+
+ return ret;
+}
+
+/* ste_init_state is called when a policy is changed to detect violations (return != 0).
+ * from a security point of view, we simulate that all running domains are re-started and
+ * all sharing decisions are replayed to detect violations or current sharing behavior
+ * (right now: event_channels, future: also grant_tables)
+ */
+static int
+ste_init_state(acm_ste_policy_buffer_t *ste_buf, domaintype_t *ssidrefs)
+{
+ int violation = 0;
+ ste_ssid_t *ste_ssid, *ste_rssid;
+ ssidref_t ste_ssidref, ste_rssidref;
+ struct domain **pd, *rdom;
+ domid_t rdomid;
+ int port, i, common;
+
+ write_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
+ /* go through all domains and adjust policy as if this domain was started now */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list ) {
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(*pd)->ssid);
+ ste_ssidref = ste_ssid->ste_ssidref;
+ traceprintk("%s: validating policy for domain %x (ste-Ref=%x).\n",
+ __func__, (*pd)->id, ste_ssidref);
+ /* a) check for event channel conflicts */
+ for (port=0; port < (*pd)->max_event_channel; port++) {
+ if ((*pd)->event_channel[port].state == ECS_INTERDOMAIN) {
+ rdom = (*pd)->event_channel[port].u.interdomain.remote_dom->domain;
+ rdomid = rdom->id;
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ } else if ((*pd)->event_channel[port].state == ECS_UNBOUND) {
+ rdomid = (*pd)->event_channel[port].u.unbound.remote_domid;
+ if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+ printk("%s: Error finding domain to id %x!\n", __func__, rdomid);
+ violation = 1;
+ goto out;
+ }
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ put_domain(rdom);
+ } else
+ continue; /* port unused */
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ traceprintk("%s: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n",
+ __func__, (*pd)->id, ste_ssidref, rdom->id, ste_rssidref, port);
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ssidrefs[ste_ssidref*ste_buf->ste_max_types + i] &&
+ ssidrefs[ste_rssidref*ste_buf->ste_max_types + i]) {
+ common = 1;
+ break;
+ }
+ if (!common) {
+ printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
+ __func__, (*pd)->id, rdomid);
+ violation = 1;
+ goto out;
+ }
+ }
+ /* b) check for grant table conflicts */
+ /* todo once grant tables are available */
+ }
+ out:
+ write_unlock(&domlist_lock);
+ return violation;
+ /* returning "violation != 0" means that existing sharing between domains would not
+ * have been allowed if the new policy had been enforced before the sharing; for ste,
+ * this means that there are at least 2 domains that have established sharing through
+ * event-channels or grant-tables but these two domains don't have no longer a common
+ * type in their typesets referenced by their ssidrefs */
+}
+
+/* set new policy; policy write-locked already */
+static int
+ste_set_policy(u8 *buf, u16 buf_size)
+{
+ acm_ste_policy_buffer_t *ste_buf = (acm_ste_policy_buffer_t *)buf;
+ void *ssidrefsbuf;
+
+ /* 1. create and copy-in new ssidrefs buffer */
+ ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs);
+ if (ssidrefsbuf == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(ssidrefsbuf, buf + ste_buf->ste_ssid_offset,
+ sizeof(domaintype_t)*ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
+ /* 2. now re-calculate sharing decisions based on running domains;
+ * this can fail if new policy is conflicting with sharing of running domains
+ * now: reject violating new policy; future: adjust sharing through revoking sharing */
+ if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) {
+ printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
+ goto error_free; /* new policy conflicts with sharing of running domains */
+ }
+ /* 3. replace old policy (activate new policy) */
+ ste_bin_pol.max_types = ste_buf->ste_max_types;
+ ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
+ if (ste_bin_pol.ssidrefs)
+ xfree(ste_bin_pol.ssidrefs);
+ ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
+ return ACM_OK;
+
+error_free:
+ printk("%s: ERROR setting policy.\n", __func__);
+ if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
+ return -EFAULT;
+}
+
+/***************************
+ * Authorization functions
+ **************************/
+
+static int
+ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ /* check for ssidref in range for policy */
+ ssidref_t ste_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
+ if (ste_ssidref >= ste_bin_pol.max_ssidrefs) {
+ printk("%s: ERROR ste_ssidref > max(%x).\n", __func__, ste_bin_pol.max_ssidrefs-1);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_PERMITTED;
+}
+
+/* -------- EVENTCHANNEL OPERATIONS -----------*/
+static int
+ste_pre_eventchannel_unbound(domid_t id) {
+ struct domain *obj = find_domain_by_id(id);
+ struct domain *subj = current->domain;
+ int i, common;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+
+ traceprintk("%s.\n", __func__);
+ if ((obj == NULL) || (obj->ssid == NULL) || (subj->ssid == NULL)) {
+ printk("%s: NULL POINTER ERROR!\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (evtchn %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ /* chinese wall does not apply */
+ read_unlock(&acm_bin_pol_rwlock);
+ put_domain(obj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+static int
+ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
+{
+ struct domain *subj, *obj;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+ int i, common;
+ traceprintk("%s.\n", __func__);
+
+ if (id1 == DOMID_SELF)
+ id1 = current->domain->id;
+ if (id2 == DOMID_SELF)
+ id2 = current->domain->id;
+
+ if ((subj = find_domain_by_id(id1)) == NULL)
+ return ACM_NULL_POINTER_ERROR;
+
+ if ((obj = find_domain_by_id(id2)) == NULL) {
+ put_domain(subj);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (evtchn %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ put_domain(obj);
+ put_domain(subj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+/* -------- SHARED MEMORY OPERATIONS -----------*/
+static int
+acm_pre_grant_map_ref (domid_t id) {
+ /* fill in */
+ traceprintk("%s.\n", __func__);
+ struct domain *obj = find_domain_by_id(id);
+ struct domain *subj = current->domain;
+ int i, common;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+
+ if ((obj == NULL) || (obj->ssid == NULL) || (subj->ssid == NULL)) {
+ printk("%s: NULL POINTER ERROR!\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (grant_map %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ /* chinese wall does not apply */
+ put_domain(obj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_simple_type_enforcement_ops = {
+ .init_domain_ssid = ste_init_domain_ssid,
+ .free_domain_ssid = ste_free_domain_ssid,
+ .dump_binary_policy = ste_dump_policy,
+ .set_binary_policy = ste_set_policy,
+ /* domain management control hooks */
+ .pre_domain_create = ste_pre_domain_create,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = NULL,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = acm_pre_grant_map_ref,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/Makefile xeno-unstable.bk/xen/acm/Makefile
--- xeno-unstable.bk_orig/xen/acm/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/Makefile 2005-03-29 19:12:38.000000000 -0500
@@ -0,0 +1,15 @@
+
+include $(BASEDIR)/Rules.mk
+OBJS = acm_core.o
+OBJS += acm_policy.o
+OBJS += acm_simple_type_enforcement_hooks.o
+OBJS += acm_chinesewall_hooks.o
+OBJS += acm_null_hooks.o
+
+default: acm.o
+
+acm.o: $(OBJS)
+ $(LD) $(LDFLAGS) -r -o acm.o $(OBJS)
+
+clean:
+ rm -f *.o *~ core
diff -Naur xeno-unstable.bk_orig/xen/arch/x86/setup.c xeno-unstable.bk/xen/arch/x86/setup.c
--- xeno-unstable.bk_orig/xen/arch/x86/setup.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/arch/x86/setup.c 2005-03-29 19:12:38.000000000 -0500
@@ -20,6 +20,7 @@
#include <asm/domain_page.h>
#include <asm/shadow.h>
#include <asm/e820.h>
+#include <acm/acm_hooks.h>
/*
* opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
@@ -576,12 +577,19 @@
shadow_mode_init();
+ /* initialize access control security module */
+ extern int acm_init(void);
+ acm_init();
+
/* Create initial domain 0. */
+ /* no pre-create-hooks on domain 0 */
dom0 = do_createdomain(0, 0);
if ( dom0 == NULL )
panic("Error creating domain 0\n");
set_bit(DF_PRIVILEGED, &dom0->d_flags);
+ /* post-create hooks sets security label */
+ shype_post_domain_create(dom0->id, ACM_DOM0_SSIDREF /* special ssidref */ );
/* Grab the DOM0 command line. Skip past the image name. */
cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -Naur xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S xeno-unstable.bk/xen/arch/x86/x86_32/entry.S
--- xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/arch/x86/x86_32/entry.S 2005-03-29 19:12:38.000000000 -0500
@@ -742,6 +742,7 @@
.long SYMBOL_NAME(do_update_va_mapping_otherdomain)
.long SYMBOL_NAME(do_switch_vm86)
.long SYMBOL_NAME(do_boot_vcpu)
+ .long SYMBOL_NAME(do_policy_op) /* 25 */
.rept NR_hypercalls-((.-hypercall_table)/4)
.long SYMBOL_NAME(do_ni_hypercall)
.endr
diff -Naur xeno-unstable.bk_orig/xen/common/dom0_ops.c xeno-unstable.bk/xen/common/dom0_ops.c
--- xeno-unstable.bk_orig/xen/common/dom0_ops.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/dom0_ops.c 2005-03-29 19:12:38.000000000 -0500
@@ -19,6 +19,7 @@
#include <xen/physdev.h>
#include <asm/shadow.h>
#include <public/sched_ctl.h>
+#include <acm/acm_hooks.h>
#define TRC_DOM0OP_ENTER_BASE 0x00020000
#define TRC_DOM0OP_LEAVE_BASE 0x00030000
@@ -133,10 +134,16 @@
ret = -EINVAL;
if ( d != current->domain )
{
+ if (shype_pre_domain_pause(current->domain->ssid, d->ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_pause_by_systemcontroller(d);
+ shype_post_domain_pause(d->ssid);
ret = 0;
}
put_domain(d);
+
}
}
break;
@@ -151,7 +158,12 @@
if ( (d != current->domain) &&
test_bit(DF_CONSTRUCTED, &d->d_flags) )
{
+ if (shype_pre_domain_unpause(current->domain->ssid, d->ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_unpause_by_systemcontroller(d);
+ shype_post_domain_unpause(d->ssid);
ret = 0;
}
put_domain(d);
@@ -165,15 +177,26 @@
unsigned int pro = 0;
domid_t dom;
+ if (shype_pre_domain_create(current->domain->ssid, op->u.createdomain.ssidref)) {
+ ret = -EINVAL;
+ break;
+ }
+
dom = op->u.createdomain.domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
{
ret = -EINVAL;
- if ( !is_free_domid(dom) )
+ if ( !is_free_domid(dom) ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
+ }
}
- else if ( (ret = allocate_domid(&dom)) != 0 )
+ else if ( (ret = allocate_domid(&dom)) != 0 ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
+ }
if ( op->u.createdomain.cpu == -1 )
{
@@ -197,18 +220,24 @@
pro = op->u.createdomain.cpu % smp_num_cpus;
ret = -ENOMEM;
- if ( (d = do_createdomain(dom, pro)) == NULL )
+ if ( (d = do_createdomain(dom, pro)) == NULL ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
-
+ }
ret = alloc_new_dom_mem(d, op->u.createdomain.memory_kb);
if ( ret != 0 )
{
domain_kill(d);
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
}
ret = 0;
-
+ /* sHype: post create hook */
+ shype_post_domain_create(d->id, op->u.createdomain.ssidref);
+
op->u.createdomain.domain = d->id;
copy_to_user(u_dom0_op, op, sizeof(*op));
}
@@ -218,13 +247,21 @@
{
struct domain *d = find_domain_by_id(op->u.destroydomain.domain);
ret = -ESRCH;
+
if ( d != NULL )
{
ret = -EINVAL;
if ( d != current->domain )
{
+ void *ssid=d->ssid; /* save ssid while domain might be destroyed */
+ if (shype_pre_domain_destroy(current->domain->ssid, ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_kill(d);
+ shype_post_domain_destroy(ssid);
ret = 0;
+
}
put_domain(d);
}
@@ -342,7 +379,11 @@
op->u.getdomaininfo.cpu_time = ed->cpu_time;
op->u.getdomaininfo.shared_info_frame =
__pa(d->shared_info) >> PAGE_SHIFT;
-
+ if (d->ssid != NULL)
+ op->u.getdomaininfo.ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref;
+ else
+ op->u.getdomaininfo.ssidref = 0xffffffff;
+
if ( op->u.getdomaininfo.ctxt != NULL )
{
if ( (c = xmalloc(full_execution_context_t)) == NULL )
diff -Naur xeno-unstable.bk_orig/xen/common/event_channel.c xeno-unstable.bk/xen/common/event_channel.c
--- xeno-unstable.bk_orig/xen/common/event_channel.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/event_channel.c 2005-03-29 19:12:38.000000000 -0500
@@ -25,6 +25,7 @@
#include <public/xen.h>
#include <public/event_channel.h>
+#include <acm/acm_hooks.h>
#define INIT_EVENT_CHANNELS 16
#define MAX_EVENT_CHANNELS 1024
@@ -586,15 +587,30 @@
if ( copy_from_user(&op, uop, sizeof(op)) != 0 )
return -EFAULT;
+ /* sHype maintenance: whenever a new option is included that
+ * can setup an event channel, it must be accompanied by an
+ * authorization check as done below for existing commands */
switch ( op.cmd )
{
case EVTCHNOP_alloc_unbound:
+ if (shype_pre_eventchannel_unbound(op.u.alloc_unbound.dom)) {
+ printkd("%s: unbound ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ break;
+ }
+ /* fall through if access permitted */
rc = evtchn_alloc_unbound(&op.u.alloc_unbound);
if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
case EVTCHNOP_bind_interdomain:
+ if (shype_pre_eventchannel_interdomain(op.u.bind_interdomain.dom1, op.u.bind_interdomain.dom2)) {
+ printkd("%s: interdomain ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ break;
+ }
+ /* fall through if access permitted */
rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
diff -Naur xeno-unstable.bk_orig/xen/common/grant_table.c xeno-unstable.bk/xen/common/grant_table.c
--- xeno-unstable.bk_orig/xen/common/grant_table.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/grant_table.c 2005-03-29 19:12:38.000000000 -0500
@@ -28,6 +28,7 @@
#include <xen/sched.h>
#include <asm-x86/mm.h>
#include <asm-x86/shadow.h>
+#include <acm/acm_hooks.h>
#define PIN_FAIL(_rc, _f, _a...) \
do { \
@@ -98,7 +99,10 @@
DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
return -EFAULT; /* don't set status */
}
-
+ if (shype_pre_grant_map_ref(dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ }
if ( ((host_virt_addr != 0) || (flags & GNTMAP_host_map) ) &&
unlikely(!__addr_ok(host_virt_addr)))
{
@@ -401,7 +405,6 @@
DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
return -EFAULT; /* don't set status */
}
-
map = &ld->grant_table->maptrack[handle];
if ( unlikely(handle >= NR_MAPTRACK_ENTRIES) ||
@@ -424,6 +427,10 @@
(void)__put_user(GNTST_bad_domain, &uop->status);
return GNTST_bad_domain;
}
+ if (shype_pre_grant_unmap_ref(dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ return -EFAULT;
+ }
DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
ref, dom, handle);
@@ -457,7 +464,7 @@
unsigned long _ol1e;
pl1e = &linear_pg_table[l1_linear_offset(virt)];
-
+
if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
{
DPRINTK("Could not find PTE entry for address %x\n", virt);
@@ -577,6 +584,11 @@
(void)put_user(GNTST_bad_domain, &uop->status);
return 0;
}
+ if (shype_pre_grant_setup(op.dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ (void)put_user(GNTST_bad_domain, &uop->status);
+ return 0;
+ }
if ( op.nr_frames == 1 )
{
diff -Naur xeno-unstable.bk_orig/xen/common/policy_ops.c xeno-unstable.bk/xen/common/policy_ops.c
--- xeno-unstable.bk_orig/xen/common/policy_ops.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/common/policy_ops.c 2005-03-29 23:17:58.105259808 -0500
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *policy_ops.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Process policy command requests from guest OS.
+ *
+ */
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <public/policy_ops.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <asm/domain_page.h>
+#include <xen/trace.h>
+#include <xen/console.h>
+#include <asm/shadow.h>
+#include <public/sched_ctl.h>
+
+#include <public/acm.h>
+#include <acm/acm_hooks.h>
+
+/* function prototypes defined in acm/acm_policy.c */
+int acm_set_policy(void *buf, u16 buf_size, u16 policy);
+int acm_get_policy(void *buf, u16 buf_size);
+
+typedef enum policyoperation {
+ POLICY, /* access to policy interface (early drop) */
+ GETPOLICY, /* dump policy cache */
+ SETPOLICY, /* set policy cache (controls security) */
+} policyoperation_t;
+
+int
+shype_authorize_policyops(void *subject_ssid, policyoperation_t pops)
+{
+ traceprintk("%s.\n", __func__);
+ /* currently, all policy management functiosn are restricted to privileged domains */
+ if ( !IS_PRIV(((struct acm_ssid_domain *)subject_ssid)->subject) ) {
+ printk("%s: Domain management authorization denied ERROR!\n", __func__);
+ return ACM_ACCESS_DENIED;
+ }
+ return ACM_ACCESS_PERMITTED;
+}
+
+long do_policy_op(policy_op_t *u_policy_op)
+{
+ long ret = 0;
+ policy_op_t curop, *op = &curop;
+
+ /* check here policy decision for policy commands */
+ /* for now allow DOM0 only, later indepedently */
+ if (shype_authorize_policyops(current->domain->ssid, POLICY))
+ return -EACCES;
+
+ if ( copy_from_user(op, u_policy_op, sizeof(*op)) )
+ return -EFAULT;
+
+ if ( op->interface_version != POLICY_INTERFACE_VERSION )
+ return -EACCES;
+
+ switch ( op->cmd )
+ {
+ case POLICY_SETPOLICY:
+ {
+ if (shype_authorize_policyops(current->domain->ssid, SETPOLICY))
+ return -EACCES;
+ printkd("%s: setting policy.\n", __func__);
+ ret = acm_set_policy(op->u.setpolicy.pushcache, op->u.setpolicy.pushcache_size, op->u.setpolicy.policy_type);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ case POLICY_GETPOLICY:
+ {
+ if (shype_authorize_policyops(current->domain->ssid, GETPOLICY))
+ return -EACCES;
+ printkd("%s: getting policy.\n", __func__);
+ ret = acm_get_policy(op->u.getpolicy.pullcache, op->u.getpolicy.pullcache_size);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ default:
+ ret = -ESRCH;
+
+ }
+ return ret;
+}
diff -Naur xeno-unstable.bk_orig/xen/include/acm/acm_core.h xeno-unstable.bk/xen/include/acm/acm_core.h
--- xeno-unstable.bk_orig/xen/include/acm/acm_core.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/acm/acm_core.h 2005-03-29 23:16:47.870937048 -0500
@@ -0,0 +1,98 @@
+/****************************************************************
+ * acm_core.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype header file describing core data types and constants
+ * for the access control module and relevant policies
+ *
+ */
+#ifndef _ACM_CORE_H
+#define _ACM_CORE_H
+
+#include <xen/spinlock.h>
+#include <public/acm.h>
+#include <public/policy_ops.h>
+
+/* Xen-internal representation of the binary policy */
+typedef struct {
+ u16 primary_policy_code;
+ u16 secondary_policy_code;
+ void *primary_binary_policy;
+ void *secondary_binary_policy;
+
+} acm_binary_policy_t;
+
+typedef struct {
+ u16 max_types;
+ u16 max_ssidrefs;
+ u16 max_conflictsets;
+ domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */
+ domaintype_t *conflict_aggregate_set; /* [max_types] */
+ domaintype_t *running_types; /* [max_types] */
+ domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/
+} chwall_binary_policy_t;
+
+typedef struct {
+ u16 max_types;
+ u16 max_ssidrefs;
+ domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */
+} ste_binary_policy_t;
+
+/* global acm policy */
+extern acm_binary_policy_t acm_bin_pol;
+extern chwall_binary_policy_t chwall_bin_pol;
+extern ste_binary_policy_t ste_bin_pol;
+/* use the lock when reading / changing binary policy ! */
+extern rwlock_t acm_bin_pol_rwlock;
+
+/* subject and object type definitions */
+enum acm_datatype { DOMAIN };
+
+/* general definition of a subject security id */
+struct acm_ssid_domain {
+ enum acm_datatype datatype; /* type of subject (e.g., partition) */
+ ssidref_t ssidref; /* combined security reference */
+ void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */
+ void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */
+ struct domain *subject; /* backpointer to subject structure */
+ domid_t domainid; /* replicate id */
+};
+
+/* chinese wall ssid type */
+typedef struct chwall_ssid {
+ ssidref_t chwall_ssidref;
+} chwall_ssid_t;
+
+/* simple type enforcement ssid type */
+typedef struct ste_ssid {
+ ssidref_t ste_ssidref;
+} ste_ssid_t;
+
+/* macros to access ssidref for primary / secondary policy
+ * primary ssidref = lower 16 bit
+ * secondary ssidref = higher 16 bit
+ */
+#define GET_SSIDREF(POLICY, ssidref) \
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ((ssidref) & 0xffff) : ((ssidref) >> 16)
+
+/* macros to access ssid pointer for primary / secondary policy */
+#define GET_SSIDP(POLICY, ssid) \
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ((ssid)->primary_ssid) : ((ssid)->secondary_ssid)
+
+/* protos */
+int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
+int acm_free_domain_ssid(struct acm_ssid_domain *ssid);
+
+#endif
+
diff -Naur xeno-unstable.bk_orig/xen/include/acm/acm_hooks.h xeno-unstable.bk/xen/include/acm/acm_hooks.h
--- xeno-unstable.bk_orig/xen/include/acm/acm_hooks.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/acm/acm_hooks.h 2005-03-29 23:15:53.412216032 -0500
@@ -0,0 +1,488 @@
+/****************************************************************
+ * acm_hooks.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype header file implementing the global (policy-independent)
+ * sHype hooks that are called throughout Xen.
+ *
+ */
+#ifndef _ACM_HOOKS_H
+#define _ACM_HOOKS_H
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/acm.h>
+#include <acm/acm_core.h>
+
+/* if ACM_TRACE_MODE defined, all hooks should
+ * print a short trace message (comment #define
+ * out when not in testing mode )
+ */
+#define ACM_TRACE_MODE
+
+#ifdef ACM_TRACE_MODE
+# define traceprintk(fmt, args...) printk(fmt,## args)
+#else
+# define traceprintk(fmt, args...)
+#endif
+
+/* global variables */
+extern struct acm_operations *acm_primary_ops;
+extern struct acm_operations *acm_secondary_ops;
+
+/* currently, a privileged domain can manage any other domain,
+ * later, we will restrict privileged domains to manage domains
+ * that they are "authorized" to manage (by comparing types or
+ * introducing capabilities */
+static int
+shype_authorize_domops(void *subject_ssid, ssidref_t object_ssidref)
+{
+ traceprintk("%s.\n", __func__);
+ if ( !IS_PRIV(((struct acm_ssid_domain *)subject_ssid)->subject) ) {
+ printk("%s: Domain management authorization denied ERROR!\n", __func__);
+ return ACM_ACCESS_DENIED;
+ }
+ return ACM_ACCESS_PERMITTED;
+}
+
+/**********************************************************************************************
+ * HOOK structure and meaning (justifies a few words about our model):
+ *
+ * General idea: every policy-controlled system operation is reflected in a
+ * transaction in the system's security state
+ *
+ * Keeping the security state consistent requires "atomic" transactions.
+ * The name of the hooks to place around policy-controlled transactions
+ * reflects this. If authorizations do not involve security state changes,
+ * then and only then POST and FAIL hooks remain empty since we don't care
+ * about the eventual outcome of the operation from a security viewpoint.
+ *
+ * PURPOSE of hook types:
+ * ======================
+ * PRE-Hooks
+ * a) general authorization to guard a controlled system operation
+ * b) prepare security state change (means: fail hook must be able to "undo" this)
+ *
+ * POST-Hooks
+ * a) commit prepared state change
+ *
+ * FAIL-Hooks
+ * a) roll-back prepared security state change from PRE-Hook
+ *
+ *
+ * PLACEMENT of hook types:
+ * ========================
+ * PRE-Hooks must be called:
+ * a) before a guarded/controlled system operation is started
+ * (return is ACM_ACCESS_PERMITTED or ACM_ACCESS_DENIED or error)
+ * --> operation must be aborted if return is != ACM_ACCESS_PERMITTED
+ *
+ * POST-Hooks must be called:
+ * a) after successful transaction (no return value; commit shall never fail)
+ *
+ * FAIL-Hooks must be called:
+ * a) if system transaction (operation) fails somewhen after calling the PRE-hook
+ * (obviously the POST-Hook is not called in this case)
+ * b) if another (secondary) policy denies access in its PRE-Hook
+ * (policy layering is useful but requires additional handling)
+ *
+ *
+ *
+ * Hook model from a security transaction viewpoint:
+ *
+ * start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success
+ * (pre-hook) \ (post-hook)
+ * \
+ * fail
+ * \
+ * \
+ * roll-back
+ * (fail-hook)
+ * \
+ * sys-ops error
+ *
+ *************************************************************************************************/
+
+struct acm_operations {
+ /* policy management functions */
+ int (*init_domain_ssid) (void **ssid, ssidref_t ssidref);
+ void (*free_domain_ssid) (void *ssid);
+ int (*dump_binary_policy) (u8 *buffer, u16 buf_size);
+ int (*set_binary_policy) (u8 *buffer, u16 buf_size);
+ /* domain management control hooks */
+ int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
+ void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
+ void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
+ int (*pre_domain_destroy) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_destroy) (void *object_ssid);
+ void (*fail_domain_destroy) (void *subject_ssid, void *object_ssid);
+ int (*pre_domain_pause) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_pause) (void *object_ssid);
+ void (*fail_domain_pause) (void *subject_ssid, void *object_ssid);
+ int (*pre_domain_unpause) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_unpause) (void *object_ssid);
+ void (*fail_domain_unpause) (void *subject_ssid, void *object_ssid);
+ /* event channel control hooks */
+ int (*pre_eventchannel_unbound) (domid_t id);
+ void (*post_eventchannel_unbound) (domid_t id);
+ void (*fail_eventchannel_unbound) (domid_t id);
+ int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ void (*post_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ void (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ /* int (*pre_close_eventchannel) (domid_t id); once we find use for it
+ * void (*post_close_eventchannel) (domid_t id); */
+ /* grant table control hooks (not yet complete) */
+ int (*pre_grant_map_ref) (domid_t id);
+ void (*post_grant_map_ref) (domid_t id);
+ void (*fail_grant_map_ref) (domid_t id);
+ int (*pre_grant_unmap_ref) (domid_t id);
+ void (*post_grant_unmap_ref) (domid_t id);
+ void (*fail_grant_unmap_ref) (domid_t id);
+ int (*pre_grant_setup) (domid_t id);
+ void (*post_grant_setup) (domid_t id);
+ void (*fail_grant_setup) (domid_t id);
+};
+
+static inline int shype_pre_domain_create (void *subject_ssid, ssidref_t ssidref)
+{
+ if (shype_authorize_domops(subject_ssid, ssidref))
+ return ACM_ACCESS_DENIED;
+
+ else if ((acm_primary_ops->pre_domain_create != NULL) &&
+ acm_primary_ops->pre_domain_create (subject_ssid, ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_create != NULL) &&
+ acm_secondary_ops->pre_domain_create (subject_ssid, ssidref)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_create != NULL)
+ acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_create (domid_t domid, ssidref_t ssidref)
+{
+ /* always initialize ssid (even for null policy) so we can use it for general
+ * authorization of domain and policy commands */
+ acm_init_domain_ssid(domid, ssidref);
+ /* initialialize shared sHype security labels for new domain */
+ if (acm_primary_ops->post_domain_create != NULL)
+ acm_primary_ops->post_domain_create (domid, ssidref);
+ if (acm_secondary_ops->post_domain_create != NULL)
+ acm_secondary_ops->post_domain_create (domid, ssidref);
+ return;
+}
+
+static inline void shype_fail_domain_create (void *subject_ssid, ssidref_t ssidref)
+{
+ if (acm_primary_ops->fail_domain_create != NULL) {
+ acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
+ if (acm_secondary_ops->fail_domain_create != NULL)
+ acm_secondary_ops->fail_domain_create (subject_ssid, ssidref);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_destroy (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_primary_ops->pre_domain_destroy != NULL) &&
+ acm_primary_ops->pre_domain_destroy (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_destroy != NULL) &&
+ acm_secondary_ops->pre_domain_destroy (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_destroy != NULL)
+ acm_primary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_destroy (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_destroy != NULL) {
+ acm_primary_ops->post_domain_destroy (object_ssid);
+ if (acm_secondary_ops->post_domain_destroy != NULL)
+ acm_secondary_ops->post_domain_destroy (object_ssid);
+ }
+ /* free security ssid for the destroyed domain (also if running null policy */
+ acm_free_domain_ssid((struct acm_ssid_domain *)object_ssid);
+ return;
+}
+
+static inline void shype_fail_domain_destroy (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_destroy != NULL) {
+ acm_primary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_destroy != NULL)
+ acm_secondary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_pause (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_primary_ops->pre_domain_pause != NULL) && acm_primary_ops->pre_domain_pause (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_pause != NULL) && acm_secondary_ops->pre_domain_pause (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_pause != NULL)
+ acm_primary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_pause (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_pause != NULL) {
+ acm_primary_ops->post_domain_pause (object_ssid);
+ if (acm_secondary_ops->post_domain_pause != NULL)
+ acm_secondary_ops->post_domain_pause (object_ssid);
+ }
+ return;
+}
+
+static inline void shype_fail_domain_pause (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_pause != NULL) {
+ acm_primary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_pause != NULL)
+ acm_secondary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_unpause (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+
+ else if ((acm_primary_ops->pre_domain_unpause != NULL) && acm_primary_ops->pre_domain_unpause (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_unpause != NULL) && acm_secondary_ops->pre_domain_unpause (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_unpause != NULL)
+ acm_primary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_unpause (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_unpause != NULL) {
+ acm_primary_ops->post_domain_unpause (object_ssid);
+ if (acm_secondary_ops->post_domain_unpause != NULL)
+ acm_secondary_ops->post_domain_unpause (object_ssid);
+ }
+ return;
+}
+
+static inline void shype_fail_domain_unpause (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_unpause != NULL) {
+ acm_primary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_unpause != NULL)
+ acm_secondary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_eventchannel_unbound (domid_t id)
+{
+ if ((acm_primary_ops->pre_eventchannel_unbound != NULL) &&
+ acm_primary_ops->pre_eventchannel_unbound (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) &&
+ acm_secondary_ops->pre_eventchannel_unbound (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_eventchannel_unbound != NULL)
+ acm_primary_ops->fail_eventchannel_unbound (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_eventchannel_unbound (domid_t id)
+{
+ if (acm_primary_ops->post_eventchannel_unbound != NULL) {
+ acm_primary_ops->post_eventchannel_unbound (id);
+ if (acm_secondary_ops->post_eventchannel_unbound != NULL)
+ acm_secondary_ops->post_eventchannel_unbound (id);
+ }
+ return;
+}
+
+static inline void shype_fail_eventchannel_unbound (domid_t id)
+{
+ if (acm_primary_ops->fail_eventchannel_unbound != NULL) {
+ acm_primary_ops->fail_eventchannel_unbound (id);
+ if (acm_secondary_ops->fail_eventchannel_unbound != NULL)
+ acm_secondary_ops->fail_eventchannel_unbound (id);
+ }
+ return;
+}
+
+static inline int shype_pre_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
+ acm_primary_ops->pre_eventchannel_interdomain (id1, id2))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
+ acm_secondary_ops->pre_eventchannel_interdomain (id1, id2)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
+ acm_primary_ops->fail_eventchannel_interdomain (id1, id2);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if (acm_primary_ops->post_eventchannel_interdomain != NULL) {
+ acm_primary_ops->post_eventchannel_interdomain (id1, id2);
+ if (acm_secondary_ops->post_eventchannel_interdomain != NULL)
+ acm_secondary_ops->post_eventchannel_interdomain (id1, id2);
+ }
+ return;
+}
+
+static inline void shype_fail_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if (acm_primary_ops->fail_eventchannel_interdomain != NULL) {
+ acm_primary_ops->fail_eventchannel_interdomain (id1, id2);
+ if (acm_secondary_ops->fail_eventchannel_interdomain != NULL)
+ acm_secondary_ops->fail_eventchannel_interdomain (id1, id2);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_map_ref (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_map_ref != NULL) &&
+ acm_primary_ops->pre_grant_map_ref (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_map_ref != NULL) &&
+ acm_secondary_ops->pre_grant_map_ref (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_map_ref != NULL)
+ acm_primary_ops->fail_grant_map_ref (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_map_ref(domid_t id)
+{
+ if (acm_primary_ops->post_grant_map_ref != NULL) {
+ acm_primary_ops->post_grant_map_ref (id);
+ if (acm_secondary_ops->post_grant_map_ref != NULL)
+ acm_secondary_ops->post_grant_map_ref (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_map_ref (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_map_ref != NULL) {
+ acm_primary_ops->fail_grant_map_ref (id);
+ if (acm_secondary_ops->fail_grant_map_ref != NULL)
+ acm_secondary_ops->fail_grant_map_ref (id);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_unmap_ref (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_unmap_ref != NULL) &&
+ acm_primary_ops->pre_grant_unmap_ref (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_unmap_ref != NULL) &&
+ acm_secondary_ops->pre_grant_unmap_ref (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_unmap_ref != NULL)
+ acm_primary_ops->fail_grant_unmap_ref (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_unmap_ref(domid_t id)
+{
+ if (acm_primary_ops->post_grant_unmap_ref != NULL) {
+ acm_primary_ops->post_grant_unmap_ref (id);
+ if (acm_secondary_ops->post_grant_unmap_ref != NULL)
+ acm_secondary_ops->post_grant_unmap_ref (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_unmap_ref (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_unmap_ref != NULL) {
+ acm_primary_ops->fail_grant_unmap_ref (id);
+ if (acm_secondary_ops->fail_grant_unmap_ref != NULL)
+ acm_secondary_ops->fail_grant_unmap_ref (id);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_setup (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_setup != NULL) &&
+ acm_primary_ops->pre_grant_setup (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_setup != NULL) &&
+ acm_secondary_ops->pre_grant_setup (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_setup != NULL)
+ acm_primary_ops->fail_grant_setup (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_setup (domid_t id)
+{
+ if (acm_primary_ops->post_grant_setup != NULL) {
+ acm_primary_ops->post_grant_setup (id);
+ if (acm_secondary_ops->post_grant_setup != NULL)
+ acm_secondary_ops->post_grant_setup (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_setup (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_setup != NULL) {
+ acm_primary_ops->fail_grant_setup (id);
+ if (acm_secondary_ops->fail_grant_setup != NULL)
+ acm_secondary_ops->fail_grant_setup (id);
+ }
+ return;
+}
+
+#endif
diff -Naur xeno-unstable.bk_orig/xen/include/public/acm.h xeno-unstable.bk/xen/include/public/acm.h
--- xeno-unstable.bk_orig/xen/include/public/acm.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/acm.h 2005-03-29 23:07:05.745433576 -0500
@@ -0,0 +1,139 @@
+/****************************************************************
+ * acm.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype general access control module header file.
+ * here are all definitions that are shared between
+ * xen-core, guest-kernels, and applications.
+ *
+ * todo: move from static policy choice to compile option.
+ */
+
+#ifndef _XEN_PUBLIC_ACM_H
+#define _XEN_PUBLIC_ACM_H
+
+#include "xen.h"
+#include "sched_ctl.h"
+
+/* if ACM_DEBUG defined, all hooks should
+ * print a short trace message (comment it out
+ * when not in testing mode )
+ */
+#define ACM_DEBUG
+
+#ifdef ACM_DEBUG
+# define printkd(fmt, args...) printk(fmt,## args)
+#else
+# define printkd(fmt, args...)
+#endif
+
+/* Internal ACM ERROR types */
+#define ACM_OK 0
+#define ACM_UNDEF -1
+#define ACM_INIT_SSID_ERROR -2
+#define ACM_INIT_SOID_ERROR -3
+#define ACM_ERROR -4
+
+/* External ACCESS DECISIONS */
+#define ACM_ACCESS_PERMITTED 0
+#define ACM_ACCESS_DENIED -111
+#define ACM_NULL_POINTER_ERROR -200
+
+#define ACM_MAX_POLICY 3
+
+#define ACM_NULL_POLICY 0
+#define ACM_CHINESE_WALL_POLICY 1
+#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
+#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3
+
+/* policy:
+ * include/public/acm.h defines the current policy.
+ */
+#define ACM_POLICY_NAME(X) \
+ (X == ACM_NULL_POLICY) ? "NULL policy" : \
+ (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \
+ (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT policy" : \
+ (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
+ "UNDEFINED policy"
+
+#ifndef ACM_USE_SECURITY_POLICY
+#define ACM_USE_SECURITY_POLICY ACM_NULL_POLICY
+#endif
+
+/* defines a ssid reference used by xen */
+typedef u32 ssidref_t;
+
+/* predefined ssidref for DOM0 used by xen when creating DOM0 */
+#define ACM_DOM0_SSIDREF 0
+
+
+/* -------security policy relevant type definitions-------- */
+
+/* type identifier; compares to "equal" or "not equal" */
+typedef u16 domaintype_t;
+
+/* CHINESE WALL POLICY DATA STRUCTURES
+ *
+ * current accumulated conflict type set:
+ * When a domain is started and has a type that is in
+ * a conflict set, the conflicting types are incremented in
+ * the aggregate set. When a domain is destroyed, the
+ * conflicting types to its type are decremented.
+ * If a domain has multiple types, this procedure works over
+ * all those types.
+ *
+ * conflict_aggregate_set[i] holds the number of
+ * running domains that have a conflict with type i.
+ *
+ * running_types[i] holds the number of running domains
+ * that include type i in their ssidref-referenced type set
+ *
+ * conflict_sets[i][j] is "0" if type j has no conflict
+ * with type i and is "1" otherwise.
+ */
+/* high-16 = version, low-16 = check magic */
+#define ACM_MAGIC 0x0001debc
+
+/* each offset in bytes from start of the struct they
+ * the are part of */
+/* each buffer consists of all policy information for
+ * the respective policy given in the policy code
+ */
+typedef struct {
+ u32 magic;
+ u32 policyversion;
+ u32 len;
+ u16 primary_policy_code;
+ u16 primary_buffer_offset;
+ u16 secondary_policy_code;
+ u16 secondary_buffer_offset;
+} PACKED acm_policy_buffer_t;
+
+typedef struct {
+ u16 policy_code;
+ u16 chwall_max_types;
+ u16 chwall_max_ssidrefs;
+ u16 chwall_max_conflictsets;
+ u16 chwall_ssid_offset;
+ u16 chwall_conflict_sets_offset;
+ u16 chwall_running_types_offset;
+ u16 chwall_conflict_aggregate_offset;
+} PACKED acm_chwall_policy_buffer_t;
+
+typedef struct {
+ u16 policy_code;
+ u16 ste_max_types;
+ u16 ste_max_ssidrefs;
+ u16 ste_ssid_offset;
+} PACKED acm_ste_policy_buffer_t;
+
+#endif
diff -Naur xeno-unstable.bk_orig/xen/include/public/dom0_ops.h xeno-unstable.bk/xen/include/public/dom0_ops.h
--- xeno-unstable.bk_orig/xen/include/public/dom0_ops.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/dom0_ops.h 2005-03-29 19:12:38.000000000 -0500
@@ -57,8 +57,9 @@
/* If 0, domain is allocated. If non-zero use it unless in use. */
domid_t domain; /* 16 */
u16 __pad1;
+ u32 ssidref;
/* OUT parameters. */
-} PACKED dom0_createdomain_t; /* 20 bytes */
+} PACKED dom0_createdomain_t; /* 24 bytes */
#define DOM0_DESTROYDOMAIN 9
typedef struct {
@@ -107,7 +108,8 @@
memory_t shared_info_frame; /* 32: MFN of shared_info struct */
MEMORY_PADDING;
u64 cpu_time; /* 40 */
-} PACKED dom0_getdomaininfo_t; /* 48 bytes */
+ u32 ssidref;
+} PACKED dom0_getdomaininfo_t; /* 52 bytes */
#define DOM0_SETDOMAININFO 13
typedef struct {
diff -Naur xeno-unstable.bk_orig/xen/include/public/policy_ops.h xeno-unstable.bk/xen/include/public/policy_ops.h
--- xeno-unstable.bk_orig/xen/include/public/policy_ops.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/policy_ops.h 2005-03-29 23:14:34.008287264 -0500
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * policy_ops.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Process policy command requests from guest OS.
+ * access checked by policy; not restricted to DOM0
+ *
+ */
+
+
+#ifndef __XEN_PUBLIC_POLICY_OPS_H__
+#define __XEN_PUBLIC_POLICY_OPS_H__
+
+#include "xen.h"
+#include "sched_ctl.h"
+
+/*
+ * Make sure you increment the interface version whenever you modify this file!
+ * This makes sure that old versions of policy tools will stop working in a
+ * well-defined way (rather than crashing the machine, for instance).
+ */
+#define POLICY_INTERFACE_VERSION 0xAAAA0000
+
+/************************************************************************/
+
+#define POLICY_SETPOLICY 4
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pushcache;
+ u16 pushcache_size;
+} PACKED policy_setpolicy_t; /* 8 bytes */
+
+
+#define POLICY_GETPOLICY 5
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pullcache;
+ u16 pullcache_size;
+} PACKED policy_getpolicy_t; /* 8 bytes */
+
+typedef struct {
+ u32 cmd; /* 0 */
+ u32 interface_version; /* 4 */ /* POLICY_INTERFACE_VERSION */
+ union { /* 8 */
+ u32 dummy[18]; /* 72bytes */
+ policy_setpolicy_t setpolicy;
+ policy_getpolicy_t getpolicy;
+ } PACKED u;
+} PACKED policy_op_t; /* 80 bytes */
+
+#endif /* __XEN_PUBLIC_POLICY_OPS_H__ */
diff -Naur xeno-unstable.bk_orig/xen/include/public/xen.h xeno-unstable.bk/xen/include/public/xen.h
--- xeno-unstable.bk_orig/xen/include/public/xen.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/xen.h 2005-03-29 19:12:38.000000000 -0500
@@ -58,6 +58,7 @@
#define __HYPERVISOR_switch_to_user 23 /* x86/64 only */
#define __HYPERVISOR_boot_vcpu 24
#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
+#define __HYPERVISOR_policy_op 25 /* x86/32 for now only because sb messed up above */
/*
* MULTICALLS
diff -Naur xeno-unstable.bk_orig/xen/include/xen/sched.h xeno-unstable.bk/xen/include/xen/sched.h
--- xeno-unstable.bk_orig/xen/include/xen/sched.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/xen/sched.h 2005-03-29 19:12:38.000000000 -0500
@@ -147,6 +147,8 @@
unsigned long cpuset;
struct arch_domain arch;
+
+ void *ssid; /* sHype security subject identifier */
};
struct domain_setup_info
diff -Naur xeno-unstable.bk_orig/xen/Makefile xeno-unstable.bk/xen/Makefile
--- xeno-unstable.bk_orig/xen/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/Makefile 2005-03-29 19:12:38.000000000 -0500
@@ -42,6 +42,7 @@
$(MAKE) -C tools clean
$(MAKE) -C common clean
$(MAKE) -C drivers clean
+ $(MAKE) -C acm clean
$(MAKE) -C arch/$(TARGET_ARCH) clean
rm -f include/asm *.o $(TARGET)* *~ core
rm -f include/asm-*/asm-offsets.h
@@ -54,6 +55,7 @@
$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
$(MAKE) -C common
$(MAKE) -C drivers
+ $(MAKE) -C acm
$(MAKE) -C arch/$(TARGET_ARCH)
# drivers/char/console.o may contain static banner/compile info. Blow it away.
@@ -105,7 +107,7 @@
.PHONY: default debug install dist clean delete-unfresh-files TAGS tags
-SUBDIRS = arch/$(TARGET_ARCH) common drivers
+SUBDIRS = acm arch/$(TARGET_ARCH) common drivers
TAGS:
( find include/asm-$(TARGET_ARCH) -name '*.h'; \
find include -type d \( -name "asm-*" -o -name config \) -prune -o \
diff -Naur xeno-unstable.bk_orig/xen/Rules.mk xeno-unstable.bk/xen/Rules.mk
--- xeno-unstable.bk_orig/xen/Rules.mk 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/Rules.mk 2005-03-29 19:12:38.000000000 -0500
@@ -35,6 +35,7 @@
ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
ALL_OBJS += $(BASEDIR)/drivers/pci/driver.o
+ALL_OBJS += $(BASEDIR)/acm/acm.o
ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
[-- Attachment #3: shype_4_xeno-unstable.bk_v0.2_tools.diff --]
[-- Type: application/octet-stream, Size: 28809 bytes --]
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc_domain.c xeno-unstable.bk/tools/libxc/xc_domain.c
--- xeno-unstable.bk_orig/tools/libxc/xc_domain.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc_domain.c 2005-03-29 19:12:44.000000000 -0500
@@ -9,6 +9,7 @@
#include "xc_private.h"
int xc_domain_create(int xc_handle,
+ u32 ssidref,
unsigned int mem_kb,
int cpu,
float cpu_weight,
@@ -21,6 +22,8 @@
op.u.createdomain.domain = (domid_t)*pdomid;
op.u.createdomain.memory_kb = mem_kb;
op.u.createdomain.cpu = cpu;
+ op.u.createdomain.ssidref = ssidref;
+
if ( (err = do_dom0_op(xc_handle, &op)) == 0 )
{
@@ -108,6 +111,7 @@
(op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
DOMFLAGS_SHUTDOWNMASK;
+ info->ssidref = op.u.getdomaininfo.ssidref;
info->nr_pages = op.u.getdomaininfo.tot_pages;
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc.h xeno-unstable.bk/tools/libxc/xc.h
--- xeno-unstable.bk_orig/tools/libxc/xc.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc.h 2005-03-29 19:12:44.000000000 -0500
@@ -77,6 +77,7 @@
typedef struct {
u32 domid;
+ u32 ssidref;
unsigned int cpu;
unsigned int dying:1, crashed:1, shutdown:1,
paused:1, blocked:1, running:1;
@@ -89,6 +90,7 @@
typedef dom0_getdomaininfo_t xc_domaininfo_t;
int xc_domain_create(int xc_handle,
+ u32 ssidref,
unsigned int mem_kb,
int cpu,
float cpu_weight,
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc_linux_restore.c xeno-unstable.bk/tools/libxc/xc_linux_restore.c
--- xeno-unstable.bk_orig/tools/libxc/xc_linux_restore.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc_linux_restore.c 2005-03-29 19:12:44.000000000 -0500
@@ -163,7 +163,8 @@
}
/* Create domain on CPU -1 so that it may auto load-balance in future. */
- if ( xc_domain_create(xc_handle, nr_pfns * (PAGE_SIZE / 1024),
+ /* ssidref to be tested... R Sailer */
+ if ( xc_domain_create(xc_handle, 0xffffffff, nr_pfns * (PAGE_SIZE / 1024),
-1, 1, &dom) )
{
xcio_error(ioctxt, "Could not create domain. pfns=%d, %dKB",
diff -Naur xeno-unstable.bk_orig/tools/Makefile xeno-unstable.bk/tools/Makefile
--- xeno-unstable.bk_orig/tools/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/Makefile 2005-03-29 19:12:44.000000000 -0500
@@ -11,6 +11,7 @@
SUBDIRS += xfrd
SUBDIRS += xcs
SUBDIRS += ioemu
+SUBDIRS += policy
.PHONY: all install clean check check_clean
diff -Naur xeno-unstable.bk_orig/tools/policy/Makefile xeno-unstable.bk/tools/policy/Makefile
--- xeno-unstable.bk_orig/tools/policy/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/tools/policy/Makefile 2005-03-29 19:12:44.000000000 -0500
@@ -0,0 +1,36 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+SRCS = policy_tool.c
+CFLAGS += -static
+CFLAGS += -Wall
+CFLAGS += -Werror
+CFLAGS += -O3
+CFLAGS += -fno-strict-aliasing
+CFLAGS += -I.
+
+all: build
+build: mk-symlinks
+ $(MAKE) policy_tool
+
+default: all
+
+install: all
+
+policy_tool : policy_tool.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+clean:
+ rm -rf policy_tool xen
+
+
+LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
+mk-symlinks:
+ [ -e xen/linux ] || mkdir -p xen/linux
+ [ -e xen/io ] || mkdir -p xen/io
+ ( cd xen >/dev/null ; \
+ ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
+ ( cd xen/io >/dev/null ; \
+ ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+ ( cd xen/linux >/dev/null ; \
+ ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -Naur xeno-unstable.bk_orig/tools/policy/policy_tool.c xeno-unstable.bk/tools/policy/policy_tool.c
--- xeno-unstable.bk_orig/tools/policy/policy_tool.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/tools/policy/policy_tool.c 2005-03-29 23:00:13.758065176 -0500
@@ -0,0 +1,423 @@
+/****************************************************************
+ * policy_tool.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype policy management tool. This code runs in a domain and
+ * manages the Xen security policy by interacting with the
+ * Xen access control module via a /proc/xen/policycmd proc-ioctl,
+ * which is translated into a policy_op hypercall into Xen.
+ *
+ * todo: implement setpolicy to dynamically set a policy cache.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdint.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+#include <xen/acm.h>
+
+#include <xen/policy_ops.h>
+
+#include <xen/linux/policycmd.h>
+
+#define ERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m "\n" , ## _a )
+
+#define PERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
+ errno, strerror(errno))
+
+static inline int do_policycmd(int xc_handle,
+ unsigned int cmd,
+ unsigned long data)
+{
+ return ioctl(xc_handle, cmd, data);
+}
+
+static inline int do_xen_hypercall(int xc_handle,
+ policycmd_hypercall_t *hypercall)
+{
+ return do_policycmd(xc_handle,
+ IOCTL_POLICYCMD_HYPERCALL,
+ (unsigned long)hypercall);
+}
+
+static inline int do_policy_op(int xc_handle, policy_op_t *op)
+{
+ int ret = -1;
+ policycmd_hypercall_t hypercall;
+
+ op->interface_version = POLICY_INTERFACE_VERSION;
+
+ hypercall.op = __HYPERVISOR_policy_op;
+ hypercall.arg[0] = (unsigned long)op;
+
+ if ( mlock(op, sizeof(*op)) != 0 )
+ {
+ PERROR("Could not lock memory for Xen policy hypercall");
+ goto out1;
+ }
+
+ if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+ {
+ if ( errno == EACCES )
+ fprintf(stderr, "POLICY operation failed -- need to"
+ " rebuild the user-space tool set?\n");
+ goto out2;
+ }
+
+ out2: (void)munlock(op, sizeof(*op));
+ out1: return ret;
+}
+
+/*************************** DUMPS *******************************/
+
+void acm_dump_chinesewall_buffer(void *buf, int buflen) {
+
+ acm_chwall_policy_buffer_t *cwbuf = (acm_chwall_policy_buffer_t *)buf;
+ domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
+ int i,j;
+
+
+ if (cwbuf->policy_code != ACM_CHINESE_WALL_POLICY) {
+ printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\n\nChinese Wall policy:\n");
+ printf("====================\n");
+ printf("Max Types = %x.\n", cwbuf->chwall_max_types);
+ printf("Max Ssidrefs = %x.\n", cwbuf->chwall_max_ssidrefs);
+ printf("Max ConfSets = %x.\n", cwbuf->chwall_max_conflictsets);
+ printf("Ssidrefs Off = %x.\n", cwbuf->chwall_ssid_offset);
+ printf("Conflicts Off = %x.\n", cwbuf->chwall_conflict_sets_offset);
+ printf("Runing T. Off = %x.\n", cwbuf->chwall_running_types_offset);
+ printf("C. Agg. Off = %x.\n", cwbuf->chwall_conflict_aggregate_offset);
+ printf("\nSSID To CHWALL-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + cwbuf->chwall_ssid_offset);
+ for(i=0; i< cwbuf->chwall_max_ssidrefs; i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< cwbuf->chwall_max_types; j++)
+ printf("%02x ", ssids[i*cwbuf->chwall_max_types +j]);
+ }
+ printf("\n\nConfict Sets:\n");
+ conflicts = (domaintype_t *)(buf + cwbuf->chwall_conflict_sets_offset);
+ for(i=0; i< cwbuf->chwall_max_conflictsets; i++) {
+ printf("\n c-set%2x: ", i);
+ for(j=0; j< cwbuf->chwall_max_types; j++)
+ printf("%02x ", conflicts[i*cwbuf->chwall_max_types +j]);
+ }
+ printf("\n");
+
+ printf("\nRunning\nTypes: ");
+ if (cwbuf->chwall_running_types_offset) {
+ running_types = (domaintype_t *)(buf + cwbuf->chwall_running_types_offset);
+ for(i=0; i< cwbuf->chwall_max_types; i++) {
+ printf("%02x ", running_types[i]);
+ }
+ printf("\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+ printf("\nConflict\nAggregate Set: ");
+ if (cwbuf->chwall_conflict_aggregate_offset) {
+ conflict_aggregate = (domaintype_t *)(buf + cwbuf->chwall_conflict_aggregate_offset);
+ for(i=0; i< cwbuf->chwall_max_types; i++) {
+ printf("%02x ", conflict_aggregate[i]);
+ }
+ printf("\n\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+}
+
+void acm_dump_ste_buffer(void *buf, int buflen) {
+
+ acm_ste_policy_buffer_t *stebuf = (acm_ste_policy_buffer_t *)buf;
+ domaintype_t *ssids;
+ int i,j;
+
+
+ if (stebuf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\nSimple Type Enforcement policy:\n");
+ printf("===============================\n");
+ printf("Max Types = %x.\n", stebuf->ste_max_types);
+ printf("Max Ssidrefs = %x.\n", stebuf->ste_max_ssidrefs);
+ printf("Ssidrefs Off = %x.\n", stebuf->ste_ssid_offset);
+ printf("\nSSID To STE-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + stebuf->ste_ssid_offset);
+ for(i=0; i< stebuf->ste_max_ssidrefs; i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< stebuf->ste_max_types; j++)
+ printf("%02x ", ssids[i*stebuf->ste_max_types +j]);
+ }
+ printf("\n\n");
+}
+
+void acm_dump_policy_buffer(void *buf, int buflen) {
+ acm_policy_buffer_t *pol = (acm_policy_buffer_t *)buf;
+
+ /* int i;
+ * for (i=0; i< buflen; i++)
+ * printf(" %02x", ((u8 *)buf)[i]);
+ */
+ printf("\nPolicy dump:\n");
+ printf("============\n");
+ printf("Magic = %x.\n", pol->magic);
+ printf("PolVer = %x.\n", pol->policyversion);
+ printf("Len = %x.\n", pol->len);
+ printf("Primary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME((pol->primary_policy_code)),
+ pol->primary_policy_code, pol->primary_buffer_offset);
+ printf("Secondary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME((pol->secondary_policy_code)),
+ pol->secondary_policy_code, pol->secondary_buffer_offset);
+ switch (pol->primary_policy_code) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+pol->primary_buffer_offset,
+ pol->len - pol->primary_buffer_offset);
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+pol->primary_buffer_offset,
+ pol->len - pol->primary_buffer_offset);
+ break;
+ case ACM_NULL_POLICY:
+ printf("No primary policy (NULL).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ switch (pol->secondary_policy_code) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+pol->secondary_buffer_offset,
+ pol->len - pol->secondary_buffer_offset);
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+pol->secondary_buffer_offset,
+ pol->len - pol->secondary_buffer_offset);
+ break;
+ case ACM_NULL_POLICY:
+ printf("No secondary policy (NULL).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ printf("\nPolicy dump End.\n\n");
+}
+
+/*************************** set policy ****************************/
+
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
+#define CWALL_MAX_SSIDREFS 5
+#define CWALL_MAX_TYPES 10
+#define CWALL_MAX_CONFLICTSETS 2
+
+ acm_chwall_policy_buffer_t *chwall_bin_pol = (acm_chwall_policy_buffer_t *)bufstart;
+ domaintype_t *ssidrefs, *conflicts;
+ int ret = 0;
+ int i,j;
+
+ chwall_bin_pol->chwall_max_types = CWALL_MAX_TYPES;
+ chwall_bin_pol->chwall_max_ssidrefs = CWALL_MAX_SSIDREFS;
+ chwall_bin_pol->policy_code = ACM_CHINESE_WALL_POLICY;
+ chwall_bin_pol->chwall_ssid_offset = sizeof(acm_chwall_policy_buffer_t);
+ chwall_bin_pol->chwall_max_conflictsets = CWALL_MAX_CONFLICTSETS;
+ chwall_bin_pol->chwall_conflict_sets_offset =
+ chwall_bin_pol->chwall_ssid_offset +
+ sizeof(domaintype_t)*CWALL_MAX_SSIDREFS*CWALL_MAX_TYPES;
+ chwall_bin_pol->chwall_running_types_offset = 0; /* not set */
+ chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */
+ ret += sizeof(acm_chwall_policy_buffer_t);
+ /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
+ /* check buffer size */
+ if ((buflen - ret) < (CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+chwall_bin_pol->chwall_ssid_offset);
+ for(i=0; i< CWALL_MAX_SSIDREFS; i++) {
+ for (j=0; j< CWALL_MAX_TYPES; j++)
+ ssidrefs[i*CWALL_MAX_TYPES + j] = 0;
+ /* here, set type i for ssidref i; generally, a ssidref can have multiple chwall types */
+ if (i < CWALL_MAX_SSIDREFS)
+ ssidrefs[i*CWALL_MAX_TYPES + i] = 1;
+ }
+ ret += CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t);
+ if ((buflen - ret) < (CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ /* now the chinese wall policy conflict sets*/
+ conflicts = (domaintype_t *)(bufstart +
+ chwall_bin_pol->chwall_conflict_sets_offset);
+ memset((void *)conflicts, 0, CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t));
+ /* just 1 conflict set [0]={2,3}, [1]={0,5,6} */
+ if (CWALL_MAX_TYPES > 3) {
+ conflicts[2] = 1; conflicts[3] = 1; /* {2,3} */
+ conflicts[CWALL_MAX_TYPES] = 1; conflicts[CWALL_MAX_TYPES+5] = 1;
+ conflicts[CWALL_MAX_TYPES+6] = 1;/* {0,5,6} */
+ }
+ ret += sizeof(domaintype_t)*CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES;
+ return ret;
+}
+
+int acm_domain_set_stepolicy(void *bufstart, int buflen) {
+#define STE_MAX_SSIDREFS 5
+#define STE_MAX_TYPES 5
+
+ acm_ste_policy_buffer_t *ste_bin_pol = (acm_ste_policy_buffer_t *)bufstart;
+ domaintype_t *ssidrefs;
+ int i,j, ret = 0;
+
+ ste_bin_pol->ste_max_types = STE_MAX_TYPES;
+ ste_bin_pol->ste_max_ssidrefs = STE_MAX_SSIDREFS;
+ ste_bin_pol->policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ste_bin_pol->ste_ssid_offset = sizeof(acm_ste_policy_buffer_t);
+ ret += sizeof(acm_ste_policy_buffer_t);
+ /* check buffer size */
+ if ((buflen - ret) < (STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+ste_bin_pol->ste_ssid_offset);
+ for(i=0; i< STE_MAX_SSIDREFS; i++) {
+ for (j=0; j< STE_MAX_TYPES; j++)
+ ssidrefs[i*STE_MAX_TYPES + j] = 0;
+ /* set type i in ssidref 0 and ssidref i */
+ ssidrefs[i] = 1; /* ssidref 0 has all types set */
+ if (i < STE_MAX_SSIDREFS)
+ ssidrefs[i*STE_MAX_TYPES + i] = 1;
+ }
+ ret += STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t);
+ return ret;
+}
+
+#define MAX_PUSH_BUFFER 16384
+u8 push_buffer[MAX_PUSH_BUFFER];
+
+int acm_domain_setpolicy(int xc_handle)
+{
+ int ret;
+ acm_policy_buffer_t *bin_pol;
+ policy_op_t op;
+
+ /* future: read policy from file and set it */
+ bin_pol = (acm_policy_buffer_t *)push_buffer;
+ bin_pol->magic = ACM_MAGIC;
+ bin_pol->policyversion = POLICY_INTERFACE_VERSION;
+ bin_pol->primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ bin_pol->secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+
+ bin_pol->len = sizeof(acm_policy_buffer_t);
+ bin_pol->primary_buffer_offset = bin_pol->len;
+ ret = acm_domain_set_chwallpolicy(push_buffer + bin_pol->primary_buffer_offset,
+ MAX_PUSH_BUFFER - bin_pol->primary_buffer_offset);
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len += ret;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ ret = acm_domain_set_stepolicy(push_buffer + bin_pol->secondary_buffer_offset,
+ MAX_PUSH_BUFFER - bin_pol->secondary_buffer_offset);
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len += ret;
+
+ /* dump it and then push it down into xen/acm */
+ acm_dump_policy_buffer(push_buffer, bin_pol->len);
+ op.cmd = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)push_buffer;
+ op.u.setpolicy.pushcache_size = bin_pol->len;
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_op(xc_handle, &op);
+
+ if (ret)
+ printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+ else
+ printf("Successfully changed policy.\n");
+ return ret;
+}
+
+/******************************* get policy ******************************/
+
+#define PULL_CACHE_SIZE 8192
+u8 pull_buffer[PULL_CACHE_SIZE];
+int acm_domain_getpolicy(int xc_handle)
+{
+ policy_op_t op;
+ int ret;
+
+ memset(pull_buffer, 0x00, sizeof(pull_buffer));
+ op.cmd = POLICY_GETPOLICY;
+ op.u.getpolicy.pullcache = (void *)pull_buffer;
+ op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = do_policy_op(xc_handle, &op);
+ /* dump policy */
+ acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+ return ret;
+}
+
+/***************************** main **************************************/
+
+void
+usage(char *progname){
+ printf("Use: %s \n\t setpolicy\n\t getpolicy\n", progname);
+ exit(-1);
+}
+
+int
+main(int argc, char **argv) {
+
+ int policycmd_fd;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ if ((policycmd_fd = open("/proc/xen/policycmd", O_RDONLY)) == 0) {
+ printf("ERROR: Could not open xen policycmd device!\n");
+ exit(-1);
+ }
+
+ if (!strcmp(argv[1], "setpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_setpolicy(policycmd_fd);
+ } else if (!strcmp(argv[1], "getpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_getpolicy(policycmd_fd);
+ } else
+ usage(argv[0]);
+
+ close(policycmd_fd);
+ return 0;
+}
diff -Naur xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c xeno-unstable.bk/tools/python/xen/lowlevel/xc/xc.c
--- xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/lowlevel/xc/xc.c 2005-03-29 19:12:44.000000000 -0500
@@ -47,15 +47,16 @@
float cpu_weight = 1;
u32 dom = 0;
int ret;
+ u32 ssidref=5;
- static char *kwd_list[] = { "dom", "mem_kb", "cpu", "cpu_weight", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiif", kwd_list,
- &dom, &mem_kb, &cpu, &cpu_weight))
+ static char *kwd_list[] = { "dom", "ssidref", "mem_kb", "cpu", "cpu_weight", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiiif", kwd_list,
+ &dom, &ssidref, &mem_kb, &cpu, &cpu_weight))
return NULL;
if ( (ret = xc_domain_create(
- xc->xc_handle, mem_kb, cpu, cpu_weight, &dom)) < 0 )
+ xc->xc_handle, ssidref, mem_kb, cpu, cpu_weight, &dom)) < 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
@@ -171,7 +172,7 @@
PyList_SetItem(
list, i,
Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
- ",s:l,s:L,s:l,s:i}",
+ ",s:l,s:L,s:l,s:i,s:i}",
"dom", info[i].domid,
"cpu", info[i].cpu,
"dying", info[i].dying,
@@ -183,6 +184,7 @@
"mem_kb", info[i].nr_pages*4,
"cpu_time", info[i].cpu_time,
"maxmem_kb", info[i].max_memkb,
+ "ssidref", info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason
));
}
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py xeno-unstable.bk/tools/python/xen/xend/server/SrvDomainDir.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xend/server/SrvDomainDir.py 2005-03-29 19:12:44.000000000 -0500
@@ -151,6 +151,7 @@
% (url, d.name, d.name))
req.write('id=%s' % d.id)
req.write('memory=%d'% d.memory)
+ req.write('ssidref=%d'% d.ssidref)
req.write('</li>')
req.write('</ul>')
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py xeno-unstable.bk/tools/python/xen/xend/XendDomainInfo.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xend/XendDomainInfo.py 2005-03-29 19:12:44.000000000 -0500
@@ -148,7 +148,7 @@
def add_image_handler(name, h):
"""Add a handler for an image type
@param name: image type
- @param h: handler: fn(config, name, memory, image)
+ @param h: handler: fn(config, name, memory, ssidref, image)
"""
image_handlers[name] = h
@@ -300,6 +300,7 @@
self.start_time = None
self.name = None
self.memory = None
+ self.ssidref = None
self.image = None
self.ramdisk = None
self.cmdline = None
@@ -337,12 +338,14 @@
"""
self.info = info
self.memory = self.info['mem_kb'] / 1024
+ self.ssidref = self.info['ssidref']
def __str__(self):
s = "domain"
s += " id=" + self.id
s += " name=" + self.name
s += " memory=" + str(self.memory)
+ s += " ssidref=" + str(self.ssidref)
if self.console:
s += " console=" + str(self.console.console_port)
if self.image:
@@ -356,7 +359,8 @@
sxpr = ['domain',
['id', self.id],
['name', self.name],
- ['memory', self.memory] ]
+ ['memory', self.memory],
+ ['ssidref', self.ssidref]]
if self.info:
sxpr.append(['maxmem', self.info['maxmem_kb']/1024 ])
@@ -447,6 +451,7 @@
self.memory = int(sxp.child_value(config, 'memory'))
if self.memory is None:
raise VmError('missing memory size')
+ self.ssidref = int(sxp.child_value(config, 'ssidref'))
cpu = sxp.child_value(config, 'cpu')
if self.recreate and self.dom and cpu is not None:
xc.domain_pincpu(self.dom, int(cpu))
@@ -455,7 +460,6 @@
self.vcpus = int(sxp.child_value(image, 'vcpus'))
except:
raise VmError('invalid vcpus value')
-
self.find_image_handler()
self.init_domain()
self.configure_console()
@@ -716,7 +720,7 @@
def show(self):
"""Print virtual machine info.
"""
- print "[VM dom=%d name=%s memory=%d" % (self.dom, self.name, self.memory)
+ print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.dom, self.name, self.memory, self.ssidref)
print "image:"
sxp.show(self.image)
print
@@ -742,6 +746,7 @@
return
dom = self.dom or 0
memory = self.memory
+ ssidref = self.ssidref
name = self.name
# If the name is over the xen limit, use the end of it.
if len(name) > MAX_DOMAIN_NAME:
@@ -752,12 +757,14 @@
raise VmError('invalid cpu')
cpu_weight = self.cpu_weight
memory = memory * 1024 + self.pgtable_size(memory)
- dom = xc.domain_create(dom= dom, mem_kb= memory,
+ dom = xc.domain_create(dom= dom, ssidref= ssidref, mem_kb= memory,
cpu= cpu, cpu_weight= cpu_weight)
+ #dom = xc.domain_create(dom= dom, mem_kb= memory,
+ # cpu= cpu, cpu_weight= cpu_weight)
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d'
% (name, memory))
- log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
+ log.debug('init_domain> Created domain=%d name=%s memory=%d ssidref=%d', dom, name, memory, ssidref)
self.setdom(dom)
def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap):
@@ -805,7 +812,6 @@
@param ramdisk: kernel ramdisk
@param cmdline: kernel commandline
"""
-
self.create_channel()
if self.console:
self.console.registerChannel()
@@ -860,6 +866,7 @@
device_model = sxp.child_value(self.config, 'device_model')
device_config = sxp.child_value(self.config, 'device_config')
memory = sxp.child_value(self.config, "memory")
+ ssidref = sxp.child_value(self.config, "ssidref")
# Create an event channel
device_channel = channel.eventChannel(0, self.dom)
# Fork and exec device_model -f device_config <port>
@@ -1082,6 +1089,7 @@
self.setdom(dom)
#self.name = d['name']
self.memory = d['mem_kb']/1024
+ self.ssidref = d['ssidref']
deferred = self.construct(config)
finally:
self.restore = 0
@@ -1346,6 +1354,7 @@
# Ignore the fields we already handle.
add_config_handler('name', vm_field_ignore)
add_config_handler('memory', vm_field_ignore)
+add_config_handler('ssidref', vm_field_ignore)
add_config_handler('cpu', vm_field_ignore)
add_config_handler('cpu_weight', vm_field_ignore)
add_config_handler('console', vm_field_ignore)
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xm/create.py xeno-unstable.bk/tools/python/xen/xm/create.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/create.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xm/create.py 2005-03-29 19:12:44.000000000 -0500
@@ -110,6 +110,10 @@
fn=set_int, default=128,
use="Domain memory in MB.")
+gopts.var('ssidref', val='SSIDREF',
+ fn=set_int, default=05,
+ use="Security Identifier.")
+
gopts.var('maxmem', val='MEMORY',
fn=set_int, default=None,
use="Maximum domain memory in MB.")
@@ -379,9 +383,10 @@
"""Create the domain configuration.
"""
- config = ['vm',
+ config = ['vm',
['name', vals.name ],
- ['memory', vals.memory ]]
+ ['memory', vals.memory ],
+ ['ssidref', vals.ssidref ]]
if vals.maxmem:
config.append(['maxmem', vals.maxmem])
if vals.cpu is not None:
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xm/main.py xeno-unstable.bk/tools/python/xen/xm/main.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/main.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xm/main.py 2005-03-29 19:12:44.000000000 -0500
@@ -350,7 +350,7 @@
self.brief_list(doms)
def brief_list(self, doms):
- print 'Name Id Mem(MB) CPU State Time(s) Console'
+ print 'Name Id Mem(MB) CPU State Time(s) Console SSID-REF'
for dom in doms:
info = server.xend_domain(dom)
d = {}
@@ -365,7 +365,9 @@
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
- print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f %(port)4s"
+ d['ssidref1'] = int(sxp.child_value(info, 'ssidref', '-1')) & 0xffff
+ d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '-1')) >> 16) & 0xffff
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f %(port)4s s:%(ssidref2)02x/p:%(ssidref1)02x"
% d)
def long_list(self, doms):
[-- Attachment #4: shype_4_xeno-unstable.bk_v0.2_sparse.diff --]
[-- Type: application/octet-stream, Size: 5432 bytes --]
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/Makefile xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/Makefile
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/Makefile 2005-03-29 19:12:49.000000000 -0500
@@ -3,6 +3,7 @@
obj-y += console/
obj-y += evtchn/
obj-y += balloon/
+obj-y += policycmd/
obj-$(CONFIG_XEN_PRIVILEGED_GUEST) += privcmd/
obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile 2005-03-29 19:12:49.000000000 -0500
@@ -0,0 +1,2 @@
+
+obj-y := policycmd.o
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c 2005-03-29 23:02:08.979548848 -0500
@@ -0,0 +1,93 @@
+/******************************************************************************
+ * policycmd.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Interface to policy and security management commands.
+ * This interface registers a /proc/xen/policycmd entry
+ * which is accessed by the policy application through
+ * ioctl commands. Requests are translated here into
+ * a new policy_op hypercall and communicated into xen.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm-xen/linux-public/policycmd.h>
+#include <asm-xen/xen-public/policy_ops.h>
+#include <asm-xen/xen_proc.h>
+
+static struct proc_dir_entry *policycmd_intf;
+
+static int policycmd_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data)
+{
+ int ret = -ENOSYS;
+
+ switch ( cmd )
+ {
+ case IOCTL_POLICYCMD_HYPERCALL:
+ {
+ policycmd_hypercall_t hypercall;
+
+ if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+ return -EFAULT;
+
+ __asm__ __volatile__ (
+ "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
+ "movl 4(%%eax),%%ebx ;"
+ "movl 8(%%eax),%%ecx ;"
+ "movl 12(%%eax),%%edx ;"
+ "movl 16(%%eax),%%esi ;"
+ "movl 20(%%eax),%%edi ;"
+ "movl (%%eax),%%eax ;"
+ TRAP_INSTR "; "
+ "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+ : "=a" (ret) : "0" (&hypercall) : "memory" );
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static struct file_operations policycmd_file_ops = {
+ ioctl : policycmd_ioctl,
+};
+
+static int __init policycmd_init(void)
+{
+ policycmd_intf = create_xen_proc_entry("policycmd", 0400);
+ if ( policycmd_intf != NULL )
+ policycmd_intf->proc_fops = &policycmd_file_ops;
+ return 0;
+}
+
+__initcall(policycmd_init);
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h xeno-unstable.bk/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h 2005-03-29 23:04:54.555377496 -0500
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * policycmd.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Interface to /proc/xen/policycmd.
+ *
+ */
+
+#ifndef __POLICYCMD_H__
+#define __POLICYCMD_H__
+
+typedef struct policycmd_hypercall
+{
+ unsigned long op;
+ unsigned long arg[5]; /* 20 bytes */
+} policycmd_hypercall_t;
+
+/*
+ * @cmd: IOCTL_POLICYCMD_HYPERCALL
+ * @arg: &policycmd_hypercall_t
+ * Return: Value returned from execution of the specified hypercall.
+ */
+#define IOCTL_POLICYCMD_HYPERCALL \
+ _IOC(_IOC_NONE, 'S', 0, sizeof(policycmd_hypercall_t))
+
+#endif
+/* __POLICYCMD_H__ */
^ permalink raw reply [flat|nested] 3+ messages in thread
* [patches] shype for xen / patches
@ 2005-03-30 5:23 Reiner Sailer
2005-03-31 17:36 ` David Hopwood
0 siblings, 1 reply; 3+ messages in thread
From: Reiner Sailer @ 2005-03-30 5:23 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1.1: Type: text/plain, Size: 3268 bytes --]
Hi all,
For the past two months our team has worked to integrate the sHype
security architecture into Xen. sHype was initially discussed on the Xen
development emailing list in
http://lists.xensource.com/archives/html/xen-devel/2005-01/msg00519.html
and the implementation described here is based on the design published in
http://www.research.ibm.com/secure_systems_department/projects/hypervisor.
We have attached the stable patches of our port for the group to evaluate.
The code successfully enforces "sample" security policies and demonstrates
the minimal impact sHype has on both the main Xen code base and on Xen's
run-time performance. (I post the patches here tonight, and will follow
up by Thursday with a README and some examples.) The security enforcement
hooks cover domain operations, event channels, and also --as far as
available-- grant tables. These hooks will also cover save/restore/migrate
once these operations are working and stable.
Please note that the default policy under these patches is a "NULL"
policy. This means that, even after the patches are applied, there will
be *no* change to the user or administrator experience until a security
policy is explicitly enabled.
The sHype port consists of three patches (tested on the xeno-unstable.bk
version from March 29 th):
1. shype_4_xeno-unstable.bk_v0.2_xen.diff .. patch that includes the
security enforcement code and access control module, the heart of shype;
2. shype_4_xeno-unstable.bk_v0.2_sparse.diff .. kernel patch that includes
an additional /proc/xen/policycmd interface using a new policy hypercall
to communicate policies between xen and the policy management tool;
3. shype_4_xeno-unstable.bk_v0.2_tools.diff .. tools patch that includes
support for a new parameter security subject identifier reference
(ssidref) in the domain configuration, as well as a v-e-r-y simple policy
tool to set binary policies in xen and to retrieve and dump enforced
policies from xen (tools/policytool); in a future version, this tool will
read user-defined policies and compile them into the binary policies to be
downloaded into xen.
If you install the patches, please start with a clean xeno-unstable.bk
tree: make mrproper; make uninstall; >patch the code here<; make;
./install.sh. More instructions to follow.
Comments/feedback related to these patches are very welcome. Note that I
will not be able to read my email from April 1st to 11th. If anyone has
any quick questions I will try to answer them before I leave; otherwise,
please look through the code at your convenience and let us discuss
details once I am back. (Note that the code is still "under development"
-- for example, work continues on save/restore support & on revoking
resources to enable policy changes at run-time, as well as moving the
enforced policy from a hard-coded parameter to a compile-time option).
Kindest Regards
Reiner
Signed-off-by: Reiner Sailer
__________________________________________________________
Reiner Sailer, Research Staff Member, Secure Systems Department
IBM T J Watson Research Ctr, 19 Skyline Drive, Hawthorne NY 10532
Phone: 914 784 6280 (t/l 863) Fax: 914 784 6205, sailer@us.ibm.com
http://www.research.ibm.com/people/s/sailer/
[-- Attachment #1.2: Type: text/html, Size: 3995 bytes --]
[-- Attachment #2: shype_4_xeno-unstable.bk_v0.2_sparse.diff --]
[-- Type: application/octet-stream, Size: 5432 bytes --]
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/Makefile xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/Makefile
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/Makefile 2005-03-29 19:12:49.000000000 -0500
@@ -3,6 +3,7 @@
obj-y += console/
obj-y += evtchn/
obj-y += balloon/
+obj-y += policycmd/
obj-$(CONFIG_XEN_PRIVILEGED_GUEST) += privcmd/
obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/Makefile 2005-03-29 19:12:49.000000000 -0500
@@ -0,0 +1,2 @@
+
+obj-y := policycmd.o
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/drivers/xen/policycmd/policycmd.c 2005-03-29 23:02:08.979548848 -0500
@@ -0,0 +1,93 @@
+/******************************************************************************
+ * policycmd.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Interface to policy and security management commands.
+ * This interface registers a /proc/xen/policycmd entry
+ * which is accessed by the policy application through
+ * ioctl commands. Requests are translated here into
+ * a new policy_op hypercall and communicated into xen.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/seq_file.h>
+
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm-xen/linux-public/policycmd.h>
+#include <asm-xen/xen-public/policy_ops.h>
+#include <asm-xen/xen_proc.h>
+
+static struct proc_dir_entry *policycmd_intf;
+
+static int policycmd_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data)
+{
+ int ret = -ENOSYS;
+
+ switch ( cmd )
+ {
+ case IOCTL_POLICYCMD_HYPERCALL:
+ {
+ policycmd_hypercall_t hypercall;
+
+ if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+ return -EFAULT;
+
+ __asm__ __volatile__ (
+ "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
+ "movl 4(%%eax),%%ebx ;"
+ "movl 8(%%eax),%%ecx ;"
+ "movl 12(%%eax),%%edx ;"
+ "movl 16(%%eax),%%esi ;"
+ "movl 20(%%eax),%%edi ;"
+ "movl (%%eax),%%eax ;"
+ TRAP_INSTR "; "
+ "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+ : "=a" (ret) : "0" (&hypercall) : "memory" );
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static struct file_operations policycmd_file_ops = {
+ ioctl : policycmd_ioctl,
+};
+
+static int __init policycmd_init(void)
+{
+ policycmd_intf = create_xen_proc_entry("policycmd", 0400);
+ if ( policycmd_intf != NULL )
+ policycmd_intf->proc_fops = &policycmd_file_ops;
+ return 0;
+}
+
+__initcall(policycmd_init);
diff -Naur xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h xeno-unstable.bk/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h
--- xeno-unstable.bk_orig/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/policycmd.h 2005-03-29 23:04:54.555377496 -0500
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * policycmd.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Interface to /proc/xen/policycmd.
+ *
+ */
+
+#ifndef __POLICYCMD_H__
+#define __POLICYCMD_H__
+
+typedef struct policycmd_hypercall
+{
+ unsigned long op;
+ unsigned long arg[5]; /* 20 bytes */
+} policycmd_hypercall_t;
+
+/*
+ * @cmd: IOCTL_POLICYCMD_HYPERCALL
+ * @arg: &policycmd_hypercall_t
+ * Return: Value returned from execution of the specified hypercall.
+ */
+#define IOCTL_POLICYCMD_HYPERCALL \
+ _IOC(_IOC_NONE, 'S', 0, sizeof(policycmd_hypercall_t))
+
+#endif
+/* __POLICYCMD_H__ */
[-- Attachment #3: shype_4_xeno-unstable.bk_v0.2_xen.diff --]
[-- Type: application/octet-stream, Size: 94654 bytes --]
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_chinesewall_hooks.c xeno-unstable.bk/xen/acm/acm_chinesewall_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_chinesewall_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_chinesewall_hooks.c 2005-03-29 23:18:49.462452328 -0500
@@ -0,0 +1,473 @@
+/****************************************************************
+ * acm_chinesewall_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype Chinese Wall Policy for Xen
+ * This code implements the hooks that are called
+ * throughout Xen operations and decides authorization
+ * based on domain types and Chinese Wall conflict type
+ * sets. The CHWALL policy decides if a new domain can be started
+ * based on the types of running domains and the type of the
+ * new domain to be started. If the new domain's type is in
+ * conflict with types of running domains, then this new domain
+ * is not allowed to be created. A domain can have multiple types,
+ * in which case all types of a new domain must be conflict-free
+ * with all types of already running domains.
+ *
+ */
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/acm.h>
+#include <acm/acm_core.h>
+#include <acm/acm_hooks.h>
+
+/* local cache structures for chinese wall policy */
+chwall_binary_policy_t chwall_bin_pol;
+
+/*
+ * Initializing chinese wall policy (will be filled by policy partition
+ * using setpolicy command)
+ */
+int acm_init_chwall_policy(void)
+{
+ /* minimal startup policy; policy write-locked already */
+ chwall_bin_pol.max_types = 1;
+ chwall_bin_pol.max_ssidrefs = 1;
+ chwall_bin_pol.max_conflictsets = 1;
+ chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
+ chwall_bin_pol.conflict_sets = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
+ chwall_bin_pol.running_types = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
+ chwall_bin_pol.conflict_aggregate_set = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types);
+
+ if ((chwall_bin_pol.conflict_sets == NULL) || (chwall_bin_pol.running_types == NULL) ||
+ (chwall_bin_pol.ssidrefs == NULL) || (chwall_bin_pol.conflict_aggregate_set == NULL))
+ return ACM_INIT_SSID_ERROR;
+
+ /* initialize state */
+ memset((void *)chwall_bin_pol.ssidrefs, 0, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.conflict_sets, 0, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.running_types, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));
+ memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, chwall_bin_pol.max_types*sizeof(domaintype_t));
+ return ACM_OK;
+}
+
+static int
+chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+{
+ chwall_ssid_t *chwall_ssidp = xmalloc(chwall_ssid_t);
+ traceprintk("%s.\n", __func__);
+ if (chwall_ssidp == NULL)
+ return ACM_INIT_SSID_ERROR;
+ /*
+ * depending on wheter chwall is primary or secondary, get the respective
+ * part of the global ssidref (same way we'll get the partial ssid pointer)
+ */
+ chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ if (chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
+ printkd("%s: ERROR chwall_ssidref(%x) > max(%x).\n",
+ __func__, chwall_ssidp->chwall_ssidref, chwall_bin_pol.max_ssidrefs-1);
+ xfree(chwall_ssidp);
+ return ACM_INIT_SSID_ERROR;
+ }
+ (*chwall_ssid) = chwall_ssidp;
+ printkd("%s: determined chwall_ssidref to %x.\n",
+ __func__, chwall_ssidp->chwall_ssidref);
+ return ACM_OK;
+}
+
+static void
+chwall_free_domain_ssid(void *chwall_ssid)
+{
+ traceprintk("%s.\n", __func__);
+ if (chwall_ssid != NULL)
+ xfree(chwall_ssid);
+ return;
+}
+
+
+/* dump chinese wall cache; policy read-locked already */
+static int
+chwall_dump_policy(u8 *buf, u16 buf_size) {
+ acm_chwall_policy_buffer_t *chwall_buf = (acm_chwall_policy_buffer_t *)buf;;
+ int ret = 0;
+
+ chwall_buf->chwall_max_types = chwall_bin_pol.max_types;
+ chwall_buf->chwall_max_ssidrefs = chwall_bin_pol.max_ssidrefs;
+ chwall_buf->policy_code = ACM_CHINESE_WALL_POLICY;
+ chwall_buf->chwall_ssid_offset = sizeof(acm_chwall_policy_buffer_t);
+ chwall_buf->chwall_max_conflictsets = chwall_bin_pol.max_conflictsets;
+ chwall_buf->chwall_conflict_sets_offset =
+ chwall_buf->chwall_ssid_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types;
+
+ chwall_buf->chwall_running_types_offset =
+ chwall_buf->chwall_conflict_sets_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types;
+
+ chwall_buf->chwall_conflict_aggregate_offset =
+ chwall_buf->chwall_running_types_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_types;
+
+ ret = chwall_buf->chwall_conflict_aggregate_offset +
+ sizeof(domaintype_t)*chwall_bin_pol.max_types;
+
+ /* now copy buffers over */
+ memcpy(buf + chwall_buf->chwall_ssid_offset,
+ chwall_bin_pol.ssidrefs,
+ sizeof(domaintype_t)*chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_conflict_sets_offset,
+ chwall_bin_pol.conflict_sets,
+ sizeof(domaintype_t)*chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_running_types_offset,
+ chwall_bin_pol.running_types,
+ sizeof(domaintype_t)*chwall_bin_pol.max_types);
+
+ memcpy(buf + chwall_buf->chwall_conflict_aggregate_offset,
+ chwall_bin_pol.conflict_aggregate_set,
+ sizeof(domaintype_t)*chwall_bin_pol.max_types);
+ return ret;
+}
+
+/* adapt security state (running_types and conflict_aggregate_set) to all running
+ * domains; chwall_init_state is called when a policy is changed to bring the security
+ * information into a consistent state and to detect violations (return != 0).
+ * from a security point of view, we simulate that all running domains are re-started
+ */
+static int
+chwall_init_state(acm_chwall_policy_buffer_t *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets,
+ domaintype_t *running_types, domaintype_t *conflict_aggregate_set)
+{
+ int violation = 0, i, j;
+ chwall_ssid_t *chwall_ssid;
+ ssidref_t chwall_ssidref;
+ struct domain **pd;
+
+ write_lock(&domlist_lock);
+ /* go through all domains and adjust policy as if this domain was started now */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list ) {
+ chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)(*pd)->ssid);
+ chwall_ssidref = chwall_ssid->chwall_ssidref;
+ traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n",
+ __func__, (*pd)->id, chwall_ssidref);
+ /* a) adjust types ref-count for running domains */
+ for (i=0; i< chwall_buf->chwall_max_types; i++)
+ running_types[i] +=
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i];
+
+ /* b) check for conflict */
+ for (i=0; i< chwall_buf->chwall_max_types; i++)
+ if (conflict_aggregate_set[i] &&
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) {
+ printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
+ violation = 1;
+ goto out;
+ }
+ /* set violation and break out of the loop */
+ /* c) adapt conflict aggregate set for this domain (notice conflicts) */
+ for (i=0; i<chwall_buf->chwall_max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_buf->chwall_max_types; j++)
+ if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
+ ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_buf->chwall_max_types; j++)
+ if (conflict_sets[i*chwall_buf->chwall_max_types + j] &&
+ !ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j])
+ conflict_aggregate_set[j]++;
+ }
+ }
+ out:
+ write_unlock(&domlist_lock);
+ return violation;
+ /* returning "violation != 0" means that the currently running set of domains would
+ * not be possible if the new policy had been enforced before starting them; for chinese
+ * wall, this means that the new policy includes at least one conflict set of which
+ * more than one type is currently running */
+}
+
+static int
+chwall_set_policy(u8 *buf, u16 buf_size)
+{
+ /* policy write-locked already */
+ acm_chwall_policy_buffer_t *chwall_buf = (acm_chwall_policy_buffer_t *)buf;
+ void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL;
+
+ /* 1. allocate new buffers */
+ ssids = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
+ conflict_sets = xmalloc_array(domaintype_t, chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types);
+ running_types = xmalloc_array(domaintype_t,chwall_buf->chwall_max_types);
+ conflict_aggregate_set = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types);
+
+ if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == NULL)||(conflict_aggregate_set == NULL))
+ goto error_free;
+
+ /* 2. set new policy */
+ memcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
+ sizeof(domaintype_t)*chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs);
+ memcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset,
+ sizeof(domaintype_t)*chwall_buf->chwall_max_types*chwall_buf->chwall_max_conflictsets);
+ /* we also use new state buffers since max_types can change */
+ memset(running_types, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
+ memset(conflict_aggregate_set, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types);
+
+ /* 3. now re-calculate the state for the new policy based on running domains;
+ * this can fail if new policy is conflicting with running domains */
+ if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set)) {
+ printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
+ goto error_free; /* new policy conflicts with running domains */
+ }
+ /* 4. free old policy buffers, replace with new ones */
+ chwall_bin_pol.max_types = chwall_buf->chwall_max_types;
+ chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;
+ chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;
+ if (chwall_bin_pol.ssidrefs != NULL)
+ xfree(chwall_bin_pol.ssidrefs);
+ if (chwall_bin_pol.conflict_aggregate_set != NULL)
+ xfree(chwall_bin_pol.conflict_aggregate_set);
+ if (chwall_bin_pol.running_types != NULL)
+ xfree(chwall_bin_pol.running_types);
+ if (chwall_bin_pol.conflict_sets != NULL)
+ xfree(chwall_bin_pol.conflict_sets);
+ chwall_bin_pol.ssidrefs = ssids;
+ chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;
+ chwall_bin_pol.running_types = running_types;
+ chwall_bin_pol.conflict_sets = conflict_sets;
+ return ACM_OK;
+
+error_free:
+ printk("%s: ERROR setting policy.\n", __func__);
+ if (ssids != NULL) xfree(ssids);
+ if (conflict_sets != NULL) xfree(conflict_sets);
+ if (running_types != NULL) xfree(running_types);
+ if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set);
+ return -EFAULT;
+}
+
+/***************************
+ * Authorization functions
+ ***************************/
+
+
+/* -------- DOMAIN OPERATION HOOKS -----------*/
+
+static int
+chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ ssidref_t chwall_ssidref;
+ int i,j;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) {
+ printk("%s: ERROR chwall_ssidref > max(%x).\n",
+ __func__, chwall_bin_pol.max_ssidrefs-1);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+ /* A: chinese wall check for conflicts */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ if (chwall_bin_pol.conflict_aggregate_set[i] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) {
+ printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+
+ /* B: chinese wall conflict set adjustment (so that other
+ * other domains simultaneously created are evaluated against this new set)*/
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]++;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_PERMITTED;
+}
+
+static void
+chwall_post_domain_create(domid_t domid, ssidref_t ssidref)
+{
+ int i,j;
+ ssidref_t chwall_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ /* adjust types ref-count for running domains */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ chwall_bin_pol.running_types[i] +=
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
+ if (domid) {
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+ }
+ /* Xen does not call pre-create hook for DOM0;
+ * to consider type conflicts of any domain with DOM0, we need
+ * to adjust the conflict_aggregate for DOM0 here the same way it
+ * is done for non-DOM0 domains in the pre-hook */
+ printkd("%s: adjusting security state for DOM0 (ssidref=%x, chwall_ssidref=%x).\n",
+ __func__, ssidref, chwall_ssidref);
+
+ /* chinese wall conflict set adjustment (so that other
+ * other domains simultaneously created are evaluated against this new set)*/
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]++;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+}
+
+static void
+chwall_fail_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ int i, j;
+ ssidref_t chwall_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);
+ /* roll-back: re-adjust conflicting types aggregate */
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]--;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+}
+
+
+static void
+chwall_post_domain_destroy(void *object_ssid)
+{
+ int i,j;
+ chwall_ssid_t *chwall_ssidp =
+ GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)object_ssid);
+ ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;
+
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ /* adjust running types set */
+ for (i=0; i< chwall_bin_pol.max_types; i++)
+ chwall_bin_pol.running_types[i] -=
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i];
+
+ /* roll-back: re-adjust conflicting types aggregate */
+ for (i=0; i<chwall_bin_pol.max_conflictsets; i++) {
+ int common = 0;
+ /* check if conflict_set_i and ssidref have common types */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j]) {
+ common = 1;
+ break;
+ }
+ if (common == 0)
+ continue; /* try next conflict set, this one does not include any type of chwall_ssidref */
+ /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */
+ for (j=0; j<chwall_bin_pol.max_types; j++)
+ if (chwall_bin_pol.conflict_sets[i*chwall_bin_pol.max_types + j] &&
+ !chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + j])
+ chwall_bin_pol.conflict_aggregate_set[j]--;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return;
+}
+
+struct acm_operations acm_chinesewall_ops = {
+ /* domain management control hooks */
+ .init_domain_ssid = chwall_init_domain_ssid,
+ .free_domain_ssid = chwall_free_domain_ssid,
+ .dump_binary_policy = chwall_dump_policy,
+ .set_binary_policy = chwall_set_policy,
+ .pre_domain_create = chwall_pre_domain_create,
+ .post_domain_create = chwall_post_domain_create,
+ .fail_domain_create = chwall_fail_domain_create,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = chwall_post_domain_destroy,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_core.c xeno-unstable.bk/xen/acm/acm_core.c
--- xeno-unstable.bk_orig/xen/acm/acm_core.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_core.c 2005-03-29 23:19:38.501997184 -0500
@@ -0,0 +1,182 @@
+/****************************************************************
+ * acm_core.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype access control module (ACM)
+ * This file handles initialization of the ACM
+ * as well as initializing/freeing security
+ * identifiers for domains (it calls on active
+ * policy hook functions).
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <acm/acm_hooks.h>
+
+/* debug:
+ * include/acm/acm_hooks.h defines a constant ACM_TRACE_MODE;
+ * define/undefine this constant to receive / suppress any
+ * security hook debug output of sHype
+ *
+ * include/public/acm.h defines a constant ACM_DEBUG
+ * define/undefine this constant to receive non-hook-related
+ * debug output.
+ */
+
+/* function prototypes */
+void acm_init_chwall_policy(void);
+void acm_init_ste_policy(void);
+
+extern struct acm_operations acm_chinesewall_ops,
+ acm_simple_type_enforcement_ops, acm_null_ops;
+
+/* global ops structs called by the hooks */
+struct acm_operations *acm_primary_ops = NULL;
+/* called in hook if-and-only-if primary succeeds */
+struct acm_operations *acm_secondary_ops = NULL;
+
+/* acm global binary policy (points to 'local' primary and secondary policies */
+acm_binary_policy_t acm_bin_pol;
+/* acm binary policy lock */
+rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
+
+/* initialize global security policy for Xen; policy write-locked already */
+static void
+acm_init_binary_policy(void *primary, void *secondary)
+{
+ acm_bin_pol.primary_policy_code = 0;
+ acm_bin_pol.secondary_policy_code = 0;
+ acm_bin_pol.primary_binary_policy = primary;
+ acm_bin_pol.secondary_binary_policy = secondary;
+}
+
+int
+acm_init(void)
+{
+ int ret = -EINVAL;
+
+ write_lock(&acm_bin_pol_rwlock);
+
+ if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_chwall_policy();
+ acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ acm_primary_ops = &acm_chinesewall_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_ste_policy();
+ acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ acm_primary_ops = &acm_simple_type_enforcement_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_init_chwall_policy();
+ acm_init_ste_policy();
+ acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ acm_primary_ops = &acm_chinesewall_ops;
+ acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ acm_secondary_ops = &acm_simple_type_enforcement_ops;
+ ret = ACM_OK;
+ } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
+ acm_init_binary_policy(NULL, NULL);
+ acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
+ acm_primary_ops = &acm_null_ops;
+ acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
+ acm_secondary_ops = &acm_null_ops;
+ ret = ACM_OK;
+ }
+ write_unlock(&acm_bin_pol_rwlock);
+
+ if (ret != ACM_OK)
+ return -EINVAL;
+ printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__,
+ ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
+ return ACM_OK;
+}
+
+
+int
+acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
+{
+ struct acm_ssid_domain *ssid;
+ struct domain *subj = find_domain_by_id(id);
+ int ret1, ret2;
+
+ if (subj == NULL) {
+ printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) {
+ return ACM_INIT_SSID_ERROR;
+ }
+ ssid->datatype = DOMAIN;
+ ssid->subject = subj;
+ ssid->domainid = subj->id;
+ ssid->ssidref = ssidref;
+ ssid->primary_ssid = NULL;
+ ssid->secondary_ssid = NULL;
+ subj->ssid = ssid;
+ /* now fill in primary and secondary parts; we only get here through hooks */
+ if (acm_primary_ops->init_domain_ssid != NULL)
+ ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref);
+ else
+ ret1 = ACM_OK;
+ if (acm_secondary_ops->init_domain_ssid != NULL)
+ ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref);
+ else
+ ret2 = ACM_OK;
+ if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
+ printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
+ __func__, subj->id);
+ acm_free_domain_ssid(ssid);
+ put_domain(subj);
+ return ACM_INIT_SSID_ERROR;
+ }
+ printkd("%s: Instantiated individual ssid for domain 0x%02x.\n",
+ __func__, subj->id);
+ put_domain(subj);
+ return ACM_OK;
+}
+
+
+int
+acm_free_domain_ssid(struct acm_ssid_domain *ssid)
+{
+ domid_t id;
+
+ if (ssid == NULL) {
+ printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ id = ssid->domainid;
+ ssid->subject = NULL;
+
+ if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
+ acm_primary_ops->free_domain_ssid(ssid->primary_ssid);
+ ssid->primary_ssid = NULL;
+ if (acm_secondary_ops->free_domain_ssid != NULL)
+ acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
+ ssid->secondary_ssid = NULL;
+ xfree(ssid);
+ printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__, id);
+ return ACM_OK;
+}
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_null_hooks.c xeno-unstable.bk/xen/acm/acm_null_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_null_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_null_hooks.c 2005-03-29 23:22:22.499065840 -0500
@@ -0,0 +1,54 @@
+/****************************************************************
+ * acm_null_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+#include <acm/acm_hooks.h>
+
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_null_ops = {
+ .init_domain_ssid = NULL,
+ .free_domain_ssid = NULL,
+ .dump_binary_policy = NULL,
+ .set_binary_policy = NULL,
+ /* domain management control hooks */
+ .pre_domain_create = NULL,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = NULL,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_policy.c xeno-unstable.bk/xen/acm/acm_policy.c
--- xeno-unstable.bk_orig/xen/acm/acm_policy.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_policy.c 2005-03-29 23:21:00.060598392 -0500
@@ -0,0 +1,148 @@
+/****************************************************************
+ * acm_policy.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype access control policy management for Xen.
+ * This interface allows policy tools in authorized
+ * domains to interact with the Xen access control module
+ *
+ */
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/policy_ops.h>
+#include <acm/acm_core.h>
+#include <acm/acm_hooks.h>
+
+int
+acm_set_policy(void *buf, u16 buf_size, u16 policy)
+{
+ u8 *policy_buffer = NULL;
+ acm_policy_buffer_t *pol;
+
+ if (policy != ACM_USE_SECURITY_POLICY) {
+ printk("%s: Loading incompatible policy (running: %s).\n", __func__,
+ ACM_POLICY_NAME(ACM_USE_SECURITY_POLICY));
+ return -EFAULT;
+ }
+ /* now check correct buffer sizes for policy combinations */
+ if (policy == ACM_NULL_POLICY) {
+ printkd("%s: NULL Policy, no policy needed.\n", __func__);
+ goto out;
+ }
+ if (buf_size < sizeof(acm_policy_buffer_t))
+ return -EFAULT;
+ /* 1. copy buffer from domain */
+ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ goto error_free;
+ if (copy_from_user(policy_buffer, buf, buf_size))
+ goto error_free;
+ /* 2. some sanity checking */
+ pol = (acm_policy_buffer_t *)policy_buffer;
+ if ((pol->magic != ACM_MAGIC) ||
+ (pol->primary_policy_code != acm_bin_pol.primary_policy_code) ||
+ (pol->secondary_policy_code != acm_bin_pol.secondary_policy_code)) {
+ printkd("%s: Wrong policy magics!\n", __func__);
+ goto error_free;
+ }
+ if (buf_size != pol->len) {
+ printk("%s: ERROR in buf size.\n", __func__);
+ goto error_free;
+ }
+ /* get bin_policy lock and rewrite policy (release old one) */
+ write_lock(&acm_bin_pol_rwlock);
+
+ /* 3. now get/set primary policy data */
+ if (acm_primary_ops->set_binary_policy(buf + pol->primary_buffer_offset,
+ pol->secondary_buffer_offset -
+ pol->primary_buffer_offset)) {
+ goto error_lock_free;
+ }
+ /* 4. now get/set secondary policy data */
+ if (acm_secondary_ops->set_binary_policy(buf + pol->secondary_buffer_offset,
+ pol->len -
+ pol->secondary_buffer_offset)) {
+ goto error_lock_free;
+ }
+ write_unlock(&acm_bin_pol_rwlock);
+ out:
+ printk("%s: Done .\n", __func__);
+ if (policy_buffer != NULL)
+ xfree(policy_buffer);
+ return ACM_OK;
+
+ error_lock_free:
+ write_unlock(&acm_bin_pol_rwlock);
+ error_free:
+ printk("%s: Error setting policy.\n", __func__);
+ if (policy_buffer != NULL)
+ xfree(policy_buffer);
+ return -ENOMEM;
+}
+
+int
+acm_get_policy(void *buf, u16 buf_size)
+{
+ u8 *policy_buffer;
+ int ret;
+ acm_policy_buffer_t *bin_pol;
+
+ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ return -ENOMEM;
+
+ read_lock(&acm_bin_pol_rwlock);
+ /* future: read policy from file and set it */
+ bin_pol = (acm_policy_buffer_t *)policy_buffer;
+ bin_pol->magic = ACM_MAGIC;
+ bin_pol->policyversion = POLICY_INTERFACE_VERSION;
+ bin_pol->primary_policy_code = acm_bin_pol.primary_policy_code;
+ bin_pol->secondary_policy_code = acm_bin_pol.secondary_policy_code;
+
+ bin_pol->len = sizeof(acm_policy_buffer_t);
+ bin_pol->primary_buffer_offset = bin_pol->len;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ if (acm_primary_ops->dump_binary_policy == NULL)
+ goto out_lock_free;
+
+ ret = acm_primary_ops->dump_binary_policy (policy_buffer + bin_pol->primary_buffer_offset,
+ buf_size - bin_pol->primary_buffer_offset);
+ if (ret < 0) {
+ printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return -1;
+ }
+ bin_pol->len += ret;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ if (acm_secondary_ops->dump_binary_policy == NULL)
+ goto out_lock_free;
+
+ ret = acm_secondary_ops->dump_binary_policy(policy_buffer + bin_pol->secondary_buffer_offset,
+ buf_size - bin_pol->secondary_buffer_offset);
+ if (ret < 0) {
+ printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return -1;
+ }
+ bin_pol->len += ret;
+
+ out_lock_free:
+ read_unlock(&acm_bin_pol_rwlock);
+ if (copy_to_user(buf, policy_buffer, bin_pol->len))
+ return -EFAULT;
+ xfree(policy_buffer);
+ return ACM_OK;
+}
+/*eof*/
diff -Naur xeno-unstable.bk_orig/xen/acm/acm_simple_type_enforcement_hooks.c xeno-unstable.bk/xen/acm/acm_simple_type_enforcement_hooks.c
--- xeno-unstable.bk_orig/xen/acm/acm_simple_type_enforcement_hooks.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/acm_simple_type_enforcement_hooks.c 2005-03-29 23:21:41.529294192 -0500
@@ -0,0 +1,413 @@
+/****************************************************************
+ * acm_simple_type_enforcement_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype Simple Type Enforcement for Xen
+ * STE allows to control which domains can setup sharing
+ * (eventchannels right now) with which other domains. Hooks
+ * are defined and called throughout Xen when domains bind to
+ * shared resources (setup eventchannels) and a domain is allowed
+ * to setup sharing with another domain if and only if both domains
+ * share at least on common type.
+ *
+ */
+#include <acm/acm_hooks.h>
+
+/* local cache structures for chinese wall policy */
+ste_binary_policy_t ste_bin_pol;
+
+/*
+ * Initializing chinese wall policy (will be filled by policy partition
+ * using setpolicy command)
+ */
+int acm_init_ste_policy(void)
+{
+ /* minimal startup policy; policy write-locked already */
+ ste_bin_pol.max_types = 1;
+ ste_bin_pol.max_ssidrefs = 1;
+ ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 1);
+
+ if (ste_bin_pol.ssidrefs == NULL)
+ return ACM_INIT_SSID_ERROR;
+
+ /* initialize state */
+ ste_bin_pol.ssidrefs[0] = 1;
+
+ return ACM_OK;
+}
+
+
+/* ste initialization function hooks */
+static int
+ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
+{
+ ste_ssid_t *ste_ssidp = xmalloc(ste_ssid_t);
+ traceprintk("%s.\n", __func__);
+ if (ste_ssidp == NULL)
+ return ACM_INIT_SSID_ERROR;
+ /*
+ * depending on wheter chwall is primary or secondary, get the respective
+ * part of the global ssidref (same way we'll get the partial ssid pointer)
+ */
+ ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
+ if (ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) {
+ printkd("%s: ERROR ste_ssidref (%x) > max(%x).\n",
+ __func__, ste_ssidp->ste_ssidref, ste_bin_pol.max_ssidrefs-1);
+ xfree(ste_ssidp);
+ return ACM_INIT_SSID_ERROR;
+ }
+ (*ste_ssid) = ste_ssidp;
+ printkd("%s: determined ste_ssidref to %x.\n",
+ __func__, ste_ssidp->ste_ssidref);
+ return ACM_OK;
+}
+
+static void
+ste_free_domain_ssid(void *ste_ssid)
+{
+ traceprintk("%s.\n", __func__);
+ if (ste_ssid != NULL)
+ xfree(ste_ssid);
+ return;
+}
+
+/* dump type enforcement cache; policy read-locked already */
+static int
+ste_dump_policy(u8 *buf, u16 buf_size) {
+ acm_ste_policy_buffer_t *ste_buf = (acm_ste_policy_buffer_t *)buf;
+ int ret = 0;
+
+ ste_buf->ste_max_types = ste_bin_pol.max_types;
+ ste_buf->ste_max_ssidrefs = ste_bin_pol.max_ssidrefs;
+ ste_buf->policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ste_buf->ste_ssid_offset = sizeof(acm_ste_policy_buffer_t);
+ ret = ste_buf->ste_ssid_offset +
+ sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
+
+ /* now copy buffer over */
+ memcpy(buf + ste_buf->ste_ssid_offset,
+ ste_bin_pol.ssidrefs,
+ sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types);
+
+ return ret;
+}
+
+/* ste_init_state is called when a policy is changed to detect violations (return != 0).
+ * from a security point of view, we simulate that all running domains are re-started and
+ * all sharing decisions are replayed to detect violations or current sharing behavior
+ * (right now: event_channels, future: also grant_tables)
+ */
+static int
+ste_init_state(acm_ste_policy_buffer_t *ste_buf, domaintype_t *ssidrefs)
+{
+ int violation = 0;
+ ste_ssid_t *ste_ssid, *ste_rssid;
+ ssidref_t ste_ssidref, ste_rssidref;
+ struct domain **pd, *rdom;
+ domid_t rdomid;
+ int port, i, common;
+
+ write_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
+ /* go through all domains and adjust policy as if this domain was started now */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list ) {
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(*pd)->ssid);
+ ste_ssidref = ste_ssid->ste_ssidref;
+ traceprintk("%s: validating policy for domain %x (ste-Ref=%x).\n",
+ __func__, (*pd)->id, ste_ssidref);
+ /* a) check for event channel conflicts */
+ for (port=0; port < (*pd)->max_event_channel; port++) {
+ if ((*pd)->event_channel[port].state == ECS_INTERDOMAIN) {
+ rdom = (*pd)->event_channel[port].u.interdomain.remote_dom->domain;
+ rdomid = rdom->id;
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ } else if ((*pd)->event_channel[port].state == ECS_UNBOUND) {
+ rdomid = (*pd)->event_channel[port].u.unbound.remote_domid;
+ if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+ printk("%s: Error finding domain to id %x!\n", __func__, rdomid);
+ violation = 1;
+ goto out;
+ }
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ put_domain(rdom);
+ } else
+ continue; /* port unused */
+ /* rdom now has remote domain */
+ ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(rdom->ssid));
+ ste_rssidref = ste_rssid->ste_ssidref;
+ traceprintk("%s: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n",
+ __func__, (*pd)->id, ste_ssidref, rdom->id, ste_rssidref, port);
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ssidrefs[ste_ssidref*ste_buf->ste_max_types + i] &&
+ ssidrefs[ste_rssidref*ste_buf->ste_max_types + i]) {
+ common = 1;
+ break;
+ }
+ if (!common) {
+ printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
+ __func__, (*pd)->id, rdomid);
+ violation = 1;
+ goto out;
+ }
+ }
+ /* b) check for grant table conflicts */
+ /* todo once grant tables are available */
+ }
+ out:
+ write_unlock(&domlist_lock);
+ return violation;
+ /* returning "violation != 0" means that existing sharing between domains would not
+ * have been allowed if the new policy had been enforced before the sharing; for ste,
+ * this means that there are at least 2 domains that have established sharing through
+ * event-channels or grant-tables but these two domains don't have no longer a common
+ * type in their typesets referenced by their ssidrefs */
+}
+
+/* set new policy; policy write-locked already */
+static int
+ste_set_policy(u8 *buf, u16 buf_size)
+{
+ acm_ste_policy_buffer_t *ste_buf = (acm_ste_policy_buffer_t *)buf;
+ void *ssidrefsbuf;
+
+ /* 1. create and copy-in new ssidrefs buffer */
+ ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs);
+ if (ssidrefsbuf == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(ssidrefsbuf, buf + ste_buf->ste_ssid_offset,
+ sizeof(domaintype_t)*ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types);
+ /* 2. now re-calculate sharing decisions based on running domains;
+ * this can fail if new policy is conflicting with sharing of running domains
+ * now: reject violating new policy; future: adjust sharing through revoking sharing */
+ if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) {
+ printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__);
+ goto error_free; /* new policy conflicts with sharing of running domains */
+ }
+ /* 3. replace old policy (activate new policy) */
+ ste_bin_pol.max_types = ste_buf->ste_max_types;
+ ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs;
+ if (ste_bin_pol.ssidrefs)
+ xfree(ste_bin_pol.ssidrefs);
+ ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf;
+ return ACM_OK;
+
+error_free:
+ printk("%s: ERROR setting policy.\n", __func__);
+ if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
+ return -EFAULT;
+}
+
+/***************************
+ * Authorization functions
+ **************************/
+
+static int
+ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
+{
+ /* check for ssidref in range for policy */
+ ssidref_t ste_ssidref;
+ traceprintk("%s.\n", __func__);
+
+ read_lock(&acm_bin_pol_rwlock);
+ ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);
+ if (ste_ssidref >= ste_bin_pol.max_ssidrefs) {
+ printk("%s: ERROR ste_ssidref > max(%x).\n", __func__, ste_bin_pol.max_ssidrefs-1);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_PERMITTED;
+}
+
+/* -------- EVENTCHANNEL OPERATIONS -----------*/
+static int
+ste_pre_eventchannel_unbound(domid_t id) {
+ struct domain *obj = find_domain_by_id(id);
+ struct domain *subj = current->domain;
+ int i, common;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+
+ traceprintk("%s.\n", __func__);
+ if ((obj == NULL) || (obj->ssid == NULL) || (subj->ssid == NULL)) {
+ printk("%s: NULL POINTER ERROR!\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (evtchn %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ /* chinese wall does not apply */
+ read_unlock(&acm_bin_pol_rwlock);
+ put_domain(obj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+static int
+ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
+{
+ struct domain *subj, *obj;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+ int i, common;
+ traceprintk("%s.\n", __func__);
+
+ if (id1 == DOMID_SELF)
+ id1 = current->domain->id;
+ if (id2 == DOMID_SELF)
+ id2 = current->domain->id;
+
+ if ((subj = find_domain_by_id(id1)) == NULL)
+ return ACM_NULL_POINTER_ERROR;
+
+ if ((obj = find_domain_by_id(id2)) == NULL) {
+ put_domain(subj);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (evtchn %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ put_domain(obj);
+ put_domain(subj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+/* -------- SHARED MEMORY OPERATIONS -----------*/
+static int
+acm_pre_grant_map_ref (domid_t id) {
+ /* fill in */
+ traceprintk("%s.\n", __func__);
+ struct domain *obj = find_domain_by_id(id);
+ struct domain *subj = current->domain;
+ int i, common;
+
+ ste_ssid_t *ste_ssid_s, *ste_ssid_o;
+ ssidref_t ref_s, ref_o;
+
+ if ((obj == NULL) || (obj->ssid == NULL) || (subj->ssid == NULL)) {
+ printk("%s: NULL POINTER ERROR!\n", __func__);
+ return ACM_NULL_POINTER_ERROR;
+ }
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ste_ssid_s = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)subj->ssid);
+ ste_ssid_o = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, (struct acm_ssid_domain *)obj->ssid);
+
+ ref_s = ste_ssid_s->ste_ssidref;
+ ref_o = ste_ssid_o->ste_ssidref;
+
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ common = 0;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref_s*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref_o*ste_bin_pol.max_types + i]) {
+ common = 1;
+ printkd("%s: (grant_map %x --> %x) common type #%02x.\n",
+ __func__, subj->id, obj->id, i);
+ break;
+ }
+ read_unlock(&acm_bin_pol_rwlock);
+ /* chinese wall does not apply */
+ put_domain(obj);
+ if (common)
+ return ACM_ACCESS_PERMITTED;
+ else
+ return ACM_ACCESS_DENIED;
+}
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_simple_type_enforcement_ops = {
+ .init_domain_ssid = ste_init_domain_ssid,
+ .free_domain_ssid = ste_free_domain_ssid,
+ .dump_binary_policy = ste_dump_policy,
+ .set_binary_policy = ste_set_policy,
+ /* domain management control hooks */
+ .pre_domain_create = ste_pre_domain_create,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .pre_domain_destroy = NULL,
+ .post_domain_destroy = NULL,
+ .fail_domain_destroy = NULL,
+ .pre_domain_pause = NULL,
+ .post_domain_pause = NULL,
+ .fail_domain_pause = NULL,
+ .pre_domain_unpause = NULL,
+ .post_domain_unpause = NULL,
+ .fail_domain_unpause = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
+ .post_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
+ .post_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = acm_pre_grant_map_ref,
+ .post_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_unmap_ref = NULL,
+ .post_grant_unmap_ref = NULL,
+ .fail_grant_unmap_ref = NULL,
+ .pre_grant_setup = NULL,
+ .post_grant_setup = NULL,
+ .fail_grant_setup = NULL
+
+};
diff -Naur xeno-unstable.bk_orig/xen/acm/Makefile xeno-unstable.bk/xen/acm/Makefile
--- xeno-unstable.bk_orig/xen/acm/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/acm/Makefile 2005-03-29 19:12:38.000000000 -0500
@@ -0,0 +1,15 @@
+
+include $(BASEDIR)/Rules.mk
+OBJS = acm_core.o
+OBJS += acm_policy.o
+OBJS += acm_simple_type_enforcement_hooks.o
+OBJS += acm_chinesewall_hooks.o
+OBJS += acm_null_hooks.o
+
+default: acm.o
+
+acm.o: $(OBJS)
+ $(LD) $(LDFLAGS) -r -o acm.o $(OBJS)
+
+clean:
+ rm -f *.o *~ core
diff -Naur xeno-unstable.bk_orig/xen/arch/x86/setup.c xeno-unstable.bk/xen/arch/x86/setup.c
--- xeno-unstable.bk_orig/xen/arch/x86/setup.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/arch/x86/setup.c 2005-03-29 19:12:38.000000000 -0500
@@ -20,6 +20,7 @@
#include <asm/domain_page.h>
#include <asm/shadow.h>
#include <asm/e820.h>
+#include <acm/acm_hooks.h>
/*
* opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
@@ -576,12 +577,19 @@
shadow_mode_init();
+ /* initialize access control security module */
+ extern int acm_init(void);
+ acm_init();
+
/* Create initial domain 0. */
+ /* no pre-create-hooks on domain 0 */
dom0 = do_createdomain(0, 0);
if ( dom0 == NULL )
panic("Error creating domain 0\n");
set_bit(DF_PRIVILEGED, &dom0->d_flags);
+ /* post-create hooks sets security label */
+ shype_post_domain_create(dom0->id, ACM_DOM0_SSIDREF /* special ssidref */ );
/* Grab the DOM0 command line. Skip past the image name. */
cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -Naur xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S xeno-unstable.bk/xen/arch/x86/x86_32/entry.S
--- xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/arch/x86/x86_32/entry.S 2005-03-29 19:12:38.000000000 -0500
@@ -742,6 +742,7 @@
.long SYMBOL_NAME(do_update_va_mapping_otherdomain)
.long SYMBOL_NAME(do_switch_vm86)
.long SYMBOL_NAME(do_boot_vcpu)
+ .long SYMBOL_NAME(do_policy_op) /* 25 */
.rept NR_hypercalls-((.-hypercall_table)/4)
.long SYMBOL_NAME(do_ni_hypercall)
.endr
diff -Naur xeno-unstable.bk_orig/xen/common/dom0_ops.c xeno-unstable.bk/xen/common/dom0_ops.c
--- xeno-unstable.bk_orig/xen/common/dom0_ops.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/dom0_ops.c 2005-03-29 19:12:38.000000000 -0500
@@ -19,6 +19,7 @@
#include <xen/physdev.h>
#include <asm/shadow.h>
#include <public/sched_ctl.h>
+#include <acm/acm_hooks.h>
#define TRC_DOM0OP_ENTER_BASE 0x00020000
#define TRC_DOM0OP_LEAVE_BASE 0x00030000
@@ -133,10 +134,16 @@
ret = -EINVAL;
if ( d != current->domain )
{
+ if (shype_pre_domain_pause(current->domain->ssid, d->ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_pause_by_systemcontroller(d);
+ shype_post_domain_pause(d->ssid);
ret = 0;
}
put_domain(d);
+
}
}
break;
@@ -151,7 +158,12 @@
if ( (d != current->domain) &&
test_bit(DF_CONSTRUCTED, &d->d_flags) )
{
+ if (shype_pre_domain_unpause(current->domain->ssid, d->ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_unpause_by_systemcontroller(d);
+ shype_post_domain_unpause(d->ssid);
ret = 0;
}
put_domain(d);
@@ -165,15 +177,26 @@
unsigned int pro = 0;
domid_t dom;
+ if (shype_pre_domain_create(current->domain->ssid, op->u.createdomain.ssidref)) {
+ ret = -EINVAL;
+ break;
+ }
+
dom = op->u.createdomain.domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
{
ret = -EINVAL;
- if ( !is_free_domid(dom) )
+ if ( !is_free_domid(dom) ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
+ }
}
- else if ( (ret = allocate_domid(&dom)) != 0 )
+ else if ( (ret = allocate_domid(&dom)) != 0 ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
+ }
if ( op->u.createdomain.cpu == -1 )
{
@@ -197,18 +220,24 @@
pro = op->u.createdomain.cpu % smp_num_cpus;
ret = -ENOMEM;
- if ( (d = do_createdomain(dom, pro)) == NULL )
+ if ( (d = do_createdomain(dom, pro)) == NULL ) {
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
-
+ }
ret = alloc_new_dom_mem(d, op->u.createdomain.memory_kb);
if ( ret != 0 )
{
domain_kill(d);
+ shype_fail_domain_create(current->domain->ssid,
+ op->u.createdomain.ssidref);
break;
}
ret = 0;
-
+ /* sHype: post create hook */
+ shype_post_domain_create(d->id, op->u.createdomain.ssidref);
+
op->u.createdomain.domain = d->id;
copy_to_user(u_dom0_op, op, sizeof(*op));
}
@@ -218,13 +247,21 @@
{
struct domain *d = find_domain_by_id(op->u.destroydomain.domain);
ret = -ESRCH;
+
if ( d != NULL )
{
ret = -EINVAL;
if ( d != current->domain )
{
+ void *ssid=d->ssid; /* save ssid while domain might be destroyed */
+ if (shype_pre_domain_destroy(current->domain->ssid, ssid)) {
+ ret = -EINVAL;
+ break;
+ }
domain_kill(d);
+ shype_post_domain_destroy(ssid);
ret = 0;
+
}
put_domain(d);
}
@@ -342,7 +379,11 @@
op->u.getdomaininfo.cpu_time = ed->cpu_time;
op->u.getdomaininfo.shared_info_frame =
__pa(d->shared_info) >> PAGE_SHIFT;
-
+ if (d->ssid != NULL)
+ op->u.getdomaininfo.ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref;
+ else
+ op->u.getdomaininfo.ssidref = 0xffffffff;
+
if ( op->u.getdomaininfo.ctxt != NULL )
{
if ( (c = xmalloc(full_execution_context_t)) == NULL )
diff -Naur xeno-unstable.bk_orig/xen/common/event_channel.c xeno-unstable.bk/xen/common/event_channel.c
--- xeno-unstable.bk_orig/xen/common/event_channel.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/event_channel.c 2005-03-29 19:12:38.000000000 -0500
@@ -25,6 +25,7 @@
#include <public/xen.h>
#include <public/event_channel.h>
+#include <acm/acm_hooks.h>
#define INIT_EVENT_CHANNELS 16
#define MAX_EVENT_CHANNELS 1024
@@ -586,15 +587,30 @@
if ( copy_from_user(&op, uop, sizeof(op)) != 0 )
return -EFAULT;
+ /* sHype maintenance: whenever a new option is included that
+ * can setup an event channel, it must be accompanied by an
+ * authorization check as done below for existing commands */
switch ( op.cmd )
{
case EVTCHNOP_alloc_unbound:
+ if (shype_pre_eventchannel_unbound(op.u.alloc_unbound.dom)) {
+ printkd("%s: unbound ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ break;
+ }
+ /* fall through if access permitted */
rc = evtchn_alloc_unbound(&op.u.alloc_unbound);
if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
case EVTCHNOP_bind_interdomain:
+ if (shype_pre_eventchannel_interdomain(op.u.bind_interdomain.dom1, op.u.bind_interdomain.dom2)) {
+ printkd("%s: interdomain ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ break;
+ }
+ /* fall through if access permitted */
rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
diff -Naur xeno-unstable.bk_orig/xen/common/grant_table.c xeno-unstable.bk/xen/common/grant_table.c
--- xeno-unstable.bk_orig/xen/common/grant_table.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/common/grant_table.c 2005-03-29 19:12:38.000000000 -0500
@@ -28,6 +28,7 @@
#include <xen/sched.h>
#include <asm-x86/mm.h>
#include <asm-x86/shadow.h>
+#include <acm/acm_hooks.h>
#define PIN_FAIL(_rc, _f, _a...) \
do { \
@@ -98,7 +99,10 @@
DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
return -EFAULT; /* don't set status */
}
-
+ if (shype_pre_grant_map_ref(dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ rc = -EFAULT;
+ }
if ( ((host_virt_addr != 0) || (flags & GNTMAP_host_map) ) &&
unlikely(!__addr_ok(host_virt_addr)))
{
@@ -401,7 +405,6 @@
DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
return -EFAULT; /* don't set status */
}
-
map = &ld->grant_table->maptrack[handle];
if ( unlikely(handle >= NR_MAPTRACK_ENTRIES) ||
@@ -424,6 +427,10 @@
(void)__put_user(GNTST_bad_domain, &uop->status);
return GNTST_bad_domain;
}
+ if (shype_pre_grant_unmap_ref(dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ return -EFAULT;
+ }
DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
ref, dom, handle);
@@ -457,7 +464,7 @@
unsigned long _ol1e;
pl1e = &linear_pg_table[l1_linear_offset(virt)];
-
+
if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
{
DPRINTK("Could not find PTE entry for address %x\n", virt);
@@ -577,6 +584,11 @@
(void)put_user(GNTST_bad_domain, &uop->status);
return 0;
}
+ if (shype_pre_grant_setup(op.dom)) {
+ printkd("%s: grant table mapping ACCESS DENIED!\n", __func__);
+ (void)put_user(GNTST_bad_domain, &uop->status);
+ return 0;
+ }
if ( op.nr_frames == 1 )
{
diff -Naur xeno-unstable.bk_orig/xen/common/policy_ops.c xeno-unstable.bk/xen/common/policy_ops.c
--- xeno-unstable.bk_orig/xen/common/policy_ops.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/common/policy_ops.c 2005-03-29 23:17:58.105259808 -0500
@@ -0,0 +1,104 @@
+/******************************************************************************
+ *policy_ops.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Process policy command requests from guest OS.
+ *
+ */
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <public/policy_ops.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <asm/domain_page.h>
+#include <xen/trace.h>
+#include <xen/console.h>
+#include <asm/shadow.h>
+#include <public/sched_ctl.h>
+
+#include <public/acm.h>
+#include <acm/acm_hooks.h>
+
+/* function prototypes defined in acm/acm_policy.c */
+int acm_set_policy(void *buf, u16 buf_size, u16 policy);
+int acm_get_policy(void *buf, u16 buf_size);
+
+typedef enum policyoperation {
+ POLICY, /* access to policy interface (early drop) */
+ GETPOLICY, /* dump policy cache */
+ SETPOLICY, /* set policy cache (controls security) */
+} policyoperation_t;
+
+int
+shype_authorize_policyops(void *subject_ssid, policyoperation_t pops)
+{
+ traceprintk("%s.\n", __func__);
+ /* currently, all policy management functiosn are restricted to privileged domains */
+ if ( !IS_PRIV(((struct acm_ssid_domain *)subject_ssid)->subject) ) {
+ printk("%s: Domain management authorization denied ERROR!\n", __func__);
+ return ACM_ACCESS_DENIED;
+ }
+ return ACM_ACCESS_PERMITTED;
+}
+
+long do_policy_op(policy_op_t *u_policy_op)
+{
+ long ret = 0;
+ policy_op_t curop, *op = &curop;
+
+ /* check here policy decision for policy commands */
+ /* for now allow DOM0 only, later indepedently */
+ if (shype_authorize_policyops(current->domain->ssid, POLICY))
+ return -EACCES;
+
+ if ( copy_from_user(op, u_policy_op, sizeof(*op)) )
+ return -EFAULT;
+
+ if ( op->interface_version != POLICY_INTERFACE_VERSION )
+ return -EACCES;
+
+ switch ( op->cmd )
+ {
+ case POLICY_SETPOLICY:
+ {
+ if (shype_authorize_policyops(current->domain->ssid, SETPOLICY))
+ return -EACCES;
+ printkd("%s: setting policy.\n", __func__);
+ ret = acm_set_policy(op->u.setpolicy.pushcache, op->u.setpolicy.pushcache_size, op->u.setpolicy.policy_type);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ case POLICY_GETPOLICY:
+ {
+ if (shype_authorize_policyops(current->domain->ssid, GETPOLICY))
+ return -EACCES;
+ printkd("%s: getting policy.\n", __func__);
+ ret = acm_get_policy(op->u.getpolicy.pullcache, op->u.getpolicy.pullcache_size);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ default:
+ ret = -ESRCH;
+
+ }
+ return ret;
+}
diff -Naur xeno-unstable.bk_orig/xen/include/acm/acm_core.h xeno-unstable.bk/xen/include/acm/acm_core.h
--- xeno-unstable.bk_orig/xen/include/acm/acm_core.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/acm/acm_core.h 2005-03-29 23:16:47.870937048 -0500
@@ -0,0 +1,98 @@
+/****************************************************************
+ * acm_core.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype header file describing core data types and constants
+ * for the access control module and relevant policies
+ *
+ */
+#ifndef _ACM_CORE_H
+#define _ACM_CORE_H
+
+#include <xen/spinlock.h>
+#include <public/acm.h>
+#include <public/policy_ops.h>
+
+/* Xen-internal representation of the binary policy */
+typedef struct {
+ u16 primary_policy_code;
+ u16 secondary_policy_code;
+ void *primary_binary_policy;
+ void *secondary_binary_policy;
+
+} acm_binary_policy_t;
+
+typedef struct {
+ u16 max_types;
+ u16 max_ssidrefs;
+ u16 max_conflictsets;
+ domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */
+ domaintype_t *conflict_aggregate_set; /* [max_types] */
+ domaintype_t *running_types; /* [max_types] */
+ domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/
+} chwall_binary_policy_t;
+
+typedef struct {
+ u16 max_types;
+ u16 max_ssidrefs;
+ domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */
+} ste_binary_policy_t;
+
+/* global acm policy */
+extern acm_binary_policy_t acm_bin_pol;
+extern chwall_binary_policy_t chwall_bin_pol;
+extern ste_binary_policy_t ste_bin_pol;
+/* use the lock when reading / changing binary policy ! */
+extern rwlock_t acm_bin_pol_rwlock;
+
+/* subject and object type definitions */
+enum acm_datatype { DOMAIN };
+
+/* general definition of a subject security id */
+struct acm_ssid_domain {
+ enum acm_datatype datatype; /* type of subject (e.g., partition) */
+ ssidref_t ssidref; /* combined security reference */
+ void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */
+ void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */
+ struct domain *subject; /* backpointer to subject structure */
+ domid_t domainid; /* replicate id */
+};
+
+/* chinese wall ssid type */
+typedef struct chwall_ssid {
+ ssidref_t chwall_ssidref;
+} chwall_ssid_t;
+
+/* simple type enforcement ssid type */
+typedef struct ste_ssid {
+ ssidref_t ste_ssidref;
+} ste_ssid_t;
+
+/* macros to access ssidref for primary / secondary policy
+ * primary ssidref = lower 16 bit
+ * secondary ssidref = higher 16 bit
+ */
+#define GET_SSIDREF(POLICY, ssidref) \
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ((ssidref) & 0xffff) : ((ssidref) >> 16)
+
+/* macros to access ssid pointer for primary / secondary policy */
+#define GET_SSIDP(POLICY, ssid) \
+ ((POLICY) == acm_bin_pol.primary_policy_code) ? \
+ ((ssid)->primary_ssid) : ((ssid)->secondary_ssid)
+
+/* protos */
+int acm_init_domain_ssid(domid_t id, ssidref_t ssidref);
+int acm_free_domain_ssid(struct acm_ssid_domain *ssid);
+
+#endif
+
diff -Naur xeno-unstable.bk_orig/xen/include/acm/acm_hooks.h xeno-unstable.bk/xen/include/acm/acm_hooks.h
--- xeno-unstable.bk_orig/xen/include/acm/acm_hooks.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/acm/acm_hooks.h 2005-03-29 23:15:53.412216032 -0500
@@ -0,0 +1,488 @@
+/****************************************************************
+ * acm_hooks.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype header file implementing the global (policy-independent)
+ * sHype hooks that are called throughout Xen.
+ *
+ */
+#ifndef _ACM_HOOKS_H
+#define _ACM_HOOKS_H
+
+#include <xen/config.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/delay.h>
+#include <xen/sched.h>
+#include <public/acm.h>
+#include <acm/acm_core.h>
+
+/* if ACM_TRACE_MODE defined, all hooks should
+ * print a short trace message (comment #define
+ * out when not in testing mode )
+ */
+#define ACM_TRACE_MODE
+
+#ifdef ACM_TRACE_MODE
+# define traceprintk(fmt, args...) printk(fmt,## args)
+#else
+# define traceprintk(fmt, args...)
+#endif
+
+/* global variables */
+extern struct acm_operations *acm_primary_ops;
+extern struct acm_operations *acm_secondary_ops;
+
+/* currently, a privileged domain can manage any other domain,
+ * later, we will restrict privileged domains to manage domains
+ * that they are "authorized" to manage (by comparing types or
+ * introducing capabilities */
+static int
+shype_authorize_domops(void *subject_ssid, ssidref_t object_ssidref)
+{
+ traceprintk("%s.\n", __func__);
+ if ( !IS_PRIV(((struct acm_ssid_domain *)subject_ssid)->subject) ) {
+ printk("%s: Domain management authorization denied ERROR!\n", __func__);
+ return ACM_ACCESS_DENIED;
+ }
+ return ACM_ACCESS_PERMITTED;
+}
+
+/**********************************************************************************************
+ * HOOK structure and meaning (justifies a few words about our model):
+ *
+ * General idea: every policy-controlled system operation is reflected in a
+ * transaction in the system's security state
+ *
+ * Keeping the security state consistent requires "atomic" transactions.
+ * The name of the hooks to place around policy-controlled transactions
+ * reflects this. If authorizations do not involve security state changes,
+ * then and only then POST and FAIL hooks remain empty since we don't care
+ * about the eventual outcome of the operation from a security viewpoint.
+ *
+ * PURPOSE of hook types:
+ * ======================
+ * PRE-Hooks
+ * a) general authorization to guard a controlled system operation
+ * b) prepare security state change (means: fail hook must be able to "undo" this)
+ *
+ * POST-Hooks
+ * a) commit prepared state change
+ *
+ * FAIL-Hooks
+ * a) roll-back prepared security state change from PRE-Hook
+ *
+ *
+ * PLACEMENT of hook types:
+ * ========================
+ * PRE-Hooks must be called:
+ * a) before a guarded/controlled system operation is started
+ * (return is ACM_ACCESS_PERMITTED or ACM_ACCESS_DENIED or error)
+ * --> operation must be aborted if return is != ACM_ACCESS_PERMITTED
+ *
+ * POST-Hooks must be called:
+ * a) after successful transaction (no return value; commit shall never fail)
+ *
+ * FAIL-Hooks must be called:
+ * a) if system transaction (operation) fails somewhen after calling the PRE-hook
+ * (obviously the POST-Hook is not called in this case)
+ * b) if another (secondary) policy denies access in its PRE-Hook
+ * (policy layering is useful but requires additional handling)
+ *
+ *
+ *
+ * Hook model from a security transaction viewpoint:
+ *
+ * start-sys-ops--> prepare ----succeed-----> commit --> sys-ops success
+ * (pre-hook) \ (post-hook)
+ * \
+ * fail
+ * \
+ * \
+ * roll-back
+ * (fail-hook)
+ * \
+ * sys-ops error
+ *
+ *************************************************************************************************/
+
+struct acm_operations {
+ /* policy management functions */
+ int (*init_domain_ssid) (void **ssid, ssidref_t ssidref);
+ void (*free_domain_ssid) (void *ssid);
+ int (*dump_binary_policy) (u8 *buffer, u16 buf_size);
+ int (*set_binary_policy) (u8 *buffer, u16 buf_size);
+ /* domain management control hooks */
+ int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
+ void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
+ void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
+ int (*pre_domain_destroy) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_destroy) (void *object_ssid);
+ void (*fail_domain_destroy) (void *subject_ssid, void *object_ssid);
+ int (*pre_domain_pause) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_pause) (void *object_ssid);
+ void (*fail_domain_pause) (void *subject_ssid, void *object_ssid);
+ int (*pre_domain_unpause) (void *subject_ssid, void *object_ssid);
+ void (*post_domain_unpause) (void *object_ssid);
+ void (*fail_domain_unpause) (void *subject_ssid, void *object_ssid);
+ /* event channel control hooks */
+ int (*pre_eventchannel_unbound) (domid_t id);
+ void (*post_eventchannel_unbound) (domid_t id);
+ void (*fail_eventchannel_unbound) (domid_t id);
+ int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ void (*post_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ void (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ /* int (*pre_close_eventchannel) (domid_t id); once we find use for it
+ * void (*post_close_eventchannel) (domid_t id); */
+ /* grant table control hooks (not yet complete) */
+ int (*pre_grant_map_ref) (domid_t id);
+ void (*post_grant_map_ref) (domid_t id);
+ void (*fail_grant_map_ref) (domid_t id);
+ int (*pre_grant_unmap_ref) (domid_t id);
+ void (*post_grant_unmap_ref) (domid_t id);
+ void (*fail_grant_unmap_ref) (domid_t id);
+ int (*pre_grant_setup) (domid_t id);
+ void (*post_grant_setup) (domid_t id);
+ void (*fail_grant_setup) (domid_t id);
+};
+
+static inline int shype_pre_domain_create (void *subject_ssid, ssidref_t ssidref)
+{
+ if (shype_authorize_domops(subject_ssid, ssidref))
+ return ACM_ACCESS_DENIED;
+
+ else if ((acm_primary_ops->pre_domain_create != NULL) &&
+ acm_primary_ops->pre_domain_create (subject_ssid, ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_create != NULL) &&
+ acm_secondary_ops->pre_domain_create (subject_ssid, ssidref)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_create != NULL)
+ acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_create (domid_t domid, ssidref_t ssidref)
+{
+ /* always initialize ssid (even for null policy) so we can use it for general
+ * authorization of domain and policy commands */
+ acm_init_domain_ssid(domid, ssidref);
+ /* initialialize shared sHype security labels for new domain */
+ if (acm_primary_ops->post_domain_create != NULL)
+ acm_primary_ops->post_domain_create (domid, ssidref);
+ if (acm_secondary_ops->post_domain_create != NULL)
+ acm_secondary_ops->post_domain_create (domid, ssidref);
+ return;
+}
+
+static inline void shype_fail_domain_create (void *subject_ssid, ssidref_t ssidref)
+{
+ if (acm_primary_ops->fail_domain_create != NULL) {
+ acm_primary_ops->fail_domain_create (subject_ssid, ssidref);
+ if (acm_secondary_ops->fail_domain_create != NULL)
+ acm_secondary_ops->fail_domain_create (subject_ssid, ssidref);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_destroy (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_primary_ops->pre_domain_destroy != NULL) &&
+ acm_primary_ops->pre_domain_destroy (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_destroy != NULL) &&
+ acm_secondary_ops->pre_domain_destroy (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_destroy != NULL)
+ acm_primary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_destroy (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_destroy != NULL) {
+ acm_primary_ops->post_domain_destroy (object_ssid);
+ if (acm_secondary_ops->post_domain_destroy != NULL)
+ acm_secondary_ops->post_domain_destroy (object_ssid);
+ }
+ /* free security ssid for the destroyed domain (also if running null policy */
+ acm_free_domain_ssid((struct acm_ssid_domain *)object_ssid);
+ return;
+}
+
+static inline void shype_fail_domain_destroy (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_destroy != NULL) {
+ acm_primary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_destroy != NULL)
+ acm_secondary_ops->fail_domain_destroy (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_pause (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_primary_ops->pre_domain_pause != NULL) && acm_primary_ops->pre_domain_pause (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_pause != NULL) && acm_secondary_ops->pre_domain_pause (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_pause != NULL)
+ acm_primary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_pause (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_pause != NULL) {
+ acm_primary_ops->post_domain_pause (object_ssid);
+ if (acm_secondary_ops->post_domain_pause != NULL)
+ acm_secondary_ops->post_domain_pause (object_ssid);
+ }
+ return;
+}
+
+static inline void shype_fail_domain_pause (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_pause != NULL) {
+ acm_primary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_pause != NULL)
+ acm_secondary_ops->fail_domain_pause (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_domain_unpause (void *subject_ssid, void *object_ssid)
+{
+ if (shype_authorize_domops(subject_ssid, ((struct acm_ssid_domain *)object_ssid)->ssidref))
+ return ACM_ACCESS_DENIED;
+
+ else if ((acm_primary_ops->pre_domain_unpause != NULL) && acm_primary_ops->pre_domain_unpause (subject_ssid, object_ssid))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_domain_unpause != NULL) && acm_secondary_ops->pre_domain_unpause (subject_ssid, object_ssid)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_domain_unpause != NULL)
+ acm_primary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_domain_unpause (void *object_ssid)
+{
+ if (acm_primary_ops->post_domain_unpause != NULL) {
+ acm_primary_ops->post_domain_unpause (object_ssid);
+ if (acm_secondary_ops->post_domain_unpause != NULL)
+ acm_secondary_ops->post_domain_unpause (object_ssid);
+ }
+ return;
+}
+
+static inline void shype_fail_domain_unpause (void *subject_ssid, void *object_ssid)
+{
+ if (acm_primary_ops->fail_domain_unpause != NULL) {
+ acm_primary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ if (acm_secondary_ops->fail_domain_unpause != NULL)
+ acm_secondary_ops->fail_domain_unpause (subject_ssid, object_ssid);
+ }
+ return;
+}
+
+static inline int shype_pre_eventchannel_unbound (domid_t id)
+{
+ if ((acm_primary_ops->pre_eventchannel_unbound != NULL) &&
+ acm_primary_ops->pre_eventchannel_unbound (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) &&
+ acm_secondary_ops->pre_eventchannel_unbound (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_eventchannel_unbound != NULL)
+ acm_primary_ops->fail_eventchannel_unbound (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_eventchannel_unbound (domid_t id)
+{
+ if (acm_primary_ops->post_eventchannel_unbound != NULL) {
+ acm_primary_ops->post_eventchannel_unbound (id);
+ if (acm_secondary_ops->post_eventchannel_unbound != NULL)
+ acm_secondary_ops->post_eventchannel_unbound (id);
+ }
+ return;
+}
+
+static inline void shype_fail_eventchannel_unbound (domid_t id)
+{
+ if (acm_primary_ops->fail_eventchannel_unbound != NULL) {
+ acm_primary_ops->fail_eventchannel_unbound (id);
+ if (acm_secondary_ops->fail_eventchannel_unbound != NULL)
+ acm_secondary_ops->fail_eventchannel_unbound (id);
+ }
+ return;
+}
+
+static inline int shype_pre_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
+ acm_primary_ops->pre_eventchannel_interdomain (id1, id2))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
+ acm_secondary_ops->pre_eventchannel_interdomain (id1, id2)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
+ acm_primary_ops->fail_eventchannel_interdomain (id1, id2);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if (acm_primary_ops->post_eventchannel_interdomain != NULL) {
+ acm_primary_ops->post_eventchannel_interdomain (id1, id2);
+ if (acm_secondary_ops->post_eventchannel_interdomain != NULL)
+ acm_secondary_ops->post_eventchannel_interdomain (id1, id2);
+ }
+ return;
+}
+
+static inline void shype_fail_eventchannel_interdomain (domid_t id1, domid_t id2)
+{
+ if (acm_primary_ops->fail_eventchannel_interdomain != NULL) {
+ acm_primary_ops->fail_eventchannel_interdomain (id1, id2);
+ if (acm_secondary_ops->fail_eventchannel_interdomain != NULL)
+ acm_secondary_ops->fail_eventchannel_interdomain (id1, id2);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_map_ref (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_map_ref != NULL) &&
+ acm_primary_ops->pre_grant_map_ref (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_map_ref != NULL) &&
+ acm_secondary_ops->pre_grant_map_ref (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_map_ref != NULL)
+ acm_primary_ops->fail_grant_map_ref (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_map_ref(domid_t id)
+{
+ if (acm_primary_ops->post_grant_map_ref != NULL) {
+ acm_primary_ops->post_grant_map_ref (id);
+ if (acm_secondary_ops->post_grant_map_ref != NULL)
+ acm_secondary_ops->post_grant_map_ref (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_map_ref (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_map_ref != NULL) {
+ acm_primary_ops->fail_grant_map_ref (id);
+ if (acm_secondary_ops->fail_grant_map_ref != NULL)
+ acm_secondary_ops->fail_grant_map_ref (id);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_unmap_ref (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_unmap_ref != NULL) &&
+ acm_primary_ops->pre_grant_unmap_ref (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_unmap_ref != NULL) &&
+ acm_secondary_ops->pre_grant_unmap_ref (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_unmap_ref != NULL)
+ acm_primary_ops->fail_grant_unmap_ref (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_unmap_ref(domid_t id)
+{
+ if (acm_primary_ops->post_grant_unmap_ref != NULL) {
+ acm_primary_ops->post_grant_unmap_ref (id);
+ if (acm_secondary_ops->post_grant_unmap_ref != NULL)
+ acm_secondary_ops->post_grant_unmap_ref (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_unmap_ref (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_unmap_ref != NULL) {
+ acm_primary_ops->fail_grant_unmap_ref (id);
+ if (acm_secondary_ops->fail_grant_unmap_ref != NULL)
+ acm_secondary_ops->fail_grant_unmap_ref (id);
+ }
+ return;
+}
+
+static inline int shype_pre_grant_setup (domid_t id)
+{
+ /* we could check grant authorization independently here */
+ if ((acm_primary_ops->pre_grant_setup != NULL) &&
+ acm_primary_ops->pre_grant_setup (id))
+ return ACM_ACCESS_DENIED;
+ else if ((acm_secondary_ops->pre_grant_setup != NULL) &&
+ acm_secondary_ops->pre_grant_setup (id)) {
+ /* roll-back primary */
+ if (acm_primary_ops->fail_grant_setup != NULL)
+ acm_primary_ops->fail_grant_setup (id);
+ return ACM_ACCESS_DENIED;
+ } else
+ return ACM_ACCESS_PERMITTED;
+}
+
+static inline void shype_post_grant_setup (domid_t id)
+{
+ if (acm_primary_ops->post_grant_setup != NULL) {
+ acm_primary_ops->post_grant_setup (id);
+ if (acm_secondary_ops->post_grant_setup != NULL)
+ acm_secondary_ops->post_grant_setup (id);
+ }
+ return;
+}
+
+static inline void shype_fail_grant_setup (domid_t id)
+{
+ if (acm_primary_ops->fail_grant_setup != NULL) {
+ acm_primary_ops->fail_grant_setup (id);
+ if (acm_secondary_ops->fail_grant_setup != NULL)
+ acm_secondary_ops->fail_grant_setup (id);
+ }
+ return;
+}
+
+#endif
diff -Naur xeno-unstable.bk_orig/xen/include/public/acm.h xeno-unstable.bk/xen/include/public/acm.h
--- xeno-unstable.bk_orig/xen/include/public/acm.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/acm.h 2005-03-29 23:07:05.745433576 -0500
@@ -0,0 +1,139 @@
+/****************************************************************
+ * acm.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype general access control module header file.
+ * here are all definitions that are shared between
+ * xen-core, guest-kernels, and applications.
+ *
+ * todo: move from static policy choice to compile option.
+ */
+
+#ifndef _XEN_PUBLIC_ACM_H
+#define _XEN_PUBLIC_ACM_H
+
+#include "xen.h"
+#include "sched_ctl.h"
+
+/* if ACM_DEBUG defined, all hooks should
+ * print a short trace message (comment it out
+ * when not in testing mode )
+ */
+#define ACM_DEBUG
+
+#ifdef ACM_DEBUG
+# define printkd(fmt, args...) printk(fmt,## args)
+#else
+# define printkd(fmt, args...)
+#endif
+
+/* Internal ACM ERROR types */
+#define ACM_OK 0
+#define ACM_UNDEF -1
+#define ACM_INIT_SSID_ERROR -2
+#define ACM_INIT_SOID_ERROR -3
+#define ACM_ERROR -4
+
+/* External ACCESS DECISIONS */
+#define ACM_ACCESS_PERMITTED 0
+#define ACM_ACCESS_DENIED -111
+#define ACM_NULL_POINTER_ERROR -200
+
+#define ACM_MAX_POLICY 3
+
+#define ACM_NULL_POLICY 0
+#define ACM_CHINESE_WALL_POLICY 1
+#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
+#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3
+
+/* policy:
+ * include/public/acm.h defines the current policy.
+ */
+#define ACM_POLICY_NAME(X) \
+ (X == ACM_NULL_POLICY) ? "NULL policy" : \
+ (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \
+ (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT policy" : \
+ (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
+ "UNDEFINED policy"
+
+#ifndef ACM_USE_SECURITY_POLICY
+#define ACM_USE_SECURITY_POLICY ACM_NULL_POLICY
+#endif
+
+/* defines a ssid reference used by xen */
+typedef u32 ssidref_t;
+
+/* predefined ssidref for DOM0 used by xen when creating DOM0 */
+#define ACM_DOM0_SSIDREF 0
+
+
+/* -------security policy relevant type definitions-------- */
+
+/* type identifier; compares to "equal" or "not equal" */
+typedef u16 domaintype_t;
+
+/* CHINESE WALL POLICY DATA STRUCTURES
+ *
+ * current accumulated conflict type set:
+ * When a domain is started and has a type that is in
+ * a conflict set, the conflicting types are incremented in
+ * the aggregate set. When a domain is destroyed, the
+ * conflicting types to its type are decremented.
+ * If a domain has multiple types, this procedure works over
+ * all those types.
+ *
+ * conflict_aggregate_set[i] holds the number of
+ * running domains that have a conflict with type i.
+ *
+ * running_types[i] holds the number of running domains
+ * that include type i in their ssidref-referenced type set
+ *
+ * conflict_sets[i][j] is "0" if type j has no conflict
+ * with type i and is "1" otherwise.
+ */
+/* high-16 = version, low-16 = check magic */
+#define ACM_MAGIC 0x0001debc
+
+/* each offset in bytes from start of the struct they
+ * the are part of */
+/* each buffer consists of all policy information for
+ * the respective policy given in the policy code
+ */
+typedef struct {
+ u32 magic;
+ u32 policyversion;
+ u32 len;
+ u16 primary_policy_code;
+ u16 primary_buffer_offset;
+ u16 secondary_policy_code;
+ u16 secondary_buffer_offset;
+} PACKED acm_policy_buffer_t;
+
+typedef struct {
+ u16 policy_code;
+ u16 chwall_max_types;
+ u16 chwall_max_ssidrefs;
+ u16 chwall_max_conflictsets;
+ u16 chwall_ssid_offset;
+ u16 chwall_conflict_sets_offset;
+ u16 chwall_running_types_offset;
+ u16 chwall_conflict_aggregate_offset;
+} PACKED acm_chwall_policy_buffer_t;
+
+typedef struct {
+ u16 policy_code;
+ u16 ste_max_types;
+ u16 ste_max_ssidrefs;
+ u16 ste_ssid_offset;
+} PACKED acm_ste_policy_buffer_t;
+
+#endif
diff -Naur xeno-unstable.bk_orig/xen/include/public/dom0_ops.h xeno-unstable.bk/xen/include/public/dom0_ops.h
--- xeno-unstable.bk_orig/xen/include/public/dom0_ops.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/dom0_ops.h 2005-03-29 19:12:38.000000000 -0500
@@ -57,8 +57,9 @@
/* If 0, domain is allocated. If non-zero use it unless in use. */
domid_t domain; /* 16 */
u16 __pad1;
+ u32 ssidref;
/* OUT parameters. */
-} PACKED dom0_createdomain_t; /* 20 bytes */
+} PACKED dom0_createdomain_t; /* 24 bytes */
#define DOM0_DESTROYDOMAIN 9
typedef struct {
@@ -107,7 +108,8 @@
memory_t shared_info_frame; /* 32: MFN of shared_info struct */
MEMORY_PADDING;
u64 cpu_time; /* 40 */
-} PACKED dom0_getdomaininfo_t; /* 48 bytes */
+ u32 ssidref;
+} PACKED dom0_getdomaininfo_t; /* 52 bytes */
#define DOM0_SETDOMAININFO 13
typedef struct {
diff -Naur xeno-unstable.bk_orig/xen/include/public/policy_ops.h xeno-unstable.bk/xen/include/public/policy_ops.h
--- xeno-unstable.bk_orig/xen/include/public/policy_ops.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/policy_ops.h 2005-03-29 23:14:34.008287264 -0500
@@ -0,0 +1,66 @@
+/******************************************************************************
+ * policy_ops.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Process policy command requests from guest OS.
+ * access checked by policy; not restricted to DOM0
+ *
+ */
+
+
+#ifndef __XEN_PUBLIC_POLICY_OPS_H__
+#define __XEN_PUBLIC_POLICY_OPS_H__
+
+#include "xen.h"
+#include "sched_ctl.h"
+
+/*
+ * Make sure you increment the interface version whenever you modify this file!
+ * This makes sure that old versions of policy tools will stop working in a
+ * well-defined way (rather than crashing the machine, for instance).
+ */
+#define POLICY_INTERFACE_VERSION 0xAAAA0000
+
+/************************************************************************/
+
+#define POLICY_SETPOLICY 4
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pushcache;
+ u16 pushcache_size;
+} PACKED policy_setpolicy_t; /* 8 bytes */
+
+
+#define POLICY_GETPOLICY 5
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pullcache;
+ u16 pullcache_size;
+} PACKED policy_getpolicy_t; /* 8 bytes */
+
+typedef struct {
+ u32 cmd; /* 0 */
+ u32 interface_version; /* 4 */ /* POLICY_INTERFACE_VERSION */
+ union { /* 8 */
+ u32 dummy[18]; /* 72bytes */
+ policy_setpolicy_t setpolicy;
+ policy_getpolicy_t getpolicy;
+ } PACKED u;
+} PACKED policy_op_t; /* 80 bytes */
+
+#endif /* __XEN_PUBLIC_POLICY_OPS_H__ */
diff -Naur xeno-unstable.bk_orig/xen/include/public/xen.h xeno-unstable.bk/xen/include/public/xen.h
--- xeno-unstable.bk_orig/xen/include/public/xen.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/public/xen.h 2005-03-29 19:12:38.000000000 -0500
@@ -58,6 +58,7 @@
#define __HYPERVISOR_switch_to_user 23 /* x86/64 only */
#define __HYPERVISOR_boot_vcpu 24
#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
+#define __HYPERVISOR_policy_op 25 /* x86/32 for now only because sb messed up above */
/*
* MULTICALLS
diff -Naur xeno-unstable.bk_orig/xen/include/xen/sched.h xeno-unstable.bk/xen/include/xen/sched.h
--- xeno-unstable.bk_orig/xen/include/xen/sched.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/include/xen/sched.h 2005-03-29 19:12:38.000000000 -0500
@@ -147,6 +147,8 @@
unsigned long cpuset;
struct arch_domain arch;
+
+ void *ssid; /* sHype security subject identifier */
};
struct domain_setup_info
diff -Naur xeno-unstable.bk_orig/xen/Makefile xeno-unstable.bk/xen/Makefile
--- xeno-unstable.bk_orig/xen/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/Makefile 2005-03-29 19:12:38.000000000 -0500
@@ -42,6 +42,7 @@
$(MAKE) -C tools clean
$(MAKE) -C common clean
$(MAKE) -C drivers clean
+ $(MAKE) -C acm clean
$(MAKE) -C arch/$(TARGET_ARCH) clean
rm -f include/asm *.o $(TARGET)* *~ core
rm -f include/asm-*/asm-offsets.h
@@ -54,6 +55,7 @@
$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
$(MAKE) -C common
$(MAKE) -C drivers
+ $(MAKE) -C acm
$(MAKE) -C arch/$(TARGET_ARCH)
# drivers/char/console.o may contain static banner/compile info. Blow it away.
@@ -105,7 +107,7 @@
.PHONY: default debug install dist clean delete-unfresh-files TAGS tags
-SUBDIRS = arch/$(TARGET_ARCH) common drivers
+SUBDIRS = acm arch/$(TARGET_ARCH) common drivers
TAGS:
( find include/asm-$(TARGET_ARCH) -name '*.h'; \
find include -type d \( -name "asm-*" -o -name config \) -prune -o \
diff -Naur xeno-unstable.bk_orig/xen/Rules.mk xeno-unstable.bk/xen/Rules.mk
--- xeno-unstable.bk_orig/xen/Rules.mk 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/xen/Rules.mk 2005-03-29 19:12:38.000000000 -0500
@@ -35,6 +35,7 @@
ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
ALL_OBJS += $(BASEDIR)/drivers/pci/driver.o
+ALL_OBJS += $(BASEDIR)/acm/acm.o
ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
[-- Attachment #4: shype_4_xeno-unstable.bk_v0.2_tools.diff --]
[-- Type: application/octet-stream, Size: 28809 bytes --]
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc_domain.c xeno-unstable.bk/tools/libxc/xc_domain.c
--- xeno-unstable.bk_orig/tools/libxc/xc_domain.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc_domain.c 2005-03-29 19:12:44.000000000 -0500
@@ -9,6 +9,7 @@
#include "xc_private.h"
int xc_domain_create(int xc_handle,
+ u32 ssidref,
unsigned int mem_kb,
int cpu,
float cpu_weight,
@@ -21,6 +22,8 @@
op.u.createdomain.domain = (domid_t)*pdomid;
op.u.createdomain.memory_kb = mem_kb;
op.u.createdomain.cpu = cpu;
+ op.u.createdomain.ssidref = ssidref;
+
if ( (err = do_dom0_op(xc_handle, &op)) == 0 )
{
@@ -108,6 +111,7 @@
(op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) &
DOMFLAGS_SHUTDOWNMASK;
+ info->ssidref = op.u.getdomaininfo.ssidref;
info->nr_pages = op.u.getdomaininfo.tot_pages;
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc.h xeno-unstable.bk/tools/libxc/xc.h
--- xeno-unstable.bk_orig/tools/libxc/xc.h 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc.h 2005-03-29 19:12:44.000000000 -0500
@@ -77,6 +77,7 @@
typedef struct {
u32 domid;
+ u32 ssidref;
unsigned int cpu;
unsigned int dying:1, crashed:1, shutdown:1,
paused:1, blocked:1, running:1;
@@ -89,6 +90,7 @@
typedef dom0_getdomaininfo_t xc_domaininfo_t;
int xc_domain_create(int xc_handle,
+ u32 ssidref,
unsigned int mem_kb,
int cpu,
float cpu_weight,
diff -Naur xeno-unstable.bk_orig/tools/libxc/xc_linux_restore.c xeno-unstable.bk/tools/libxc/xc_linux_restore.c
--- xeno-unstable.bk_orig/tools/libxc/xc_linux_restore.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/libxc/xc_linux_restore.c 2005-03-29 19:12:44.000000000 -0500
@@ -163,7 +163,8 @@
}
/* Create domain on CPU -1 so that it may auto load-balance in future. */
- if ( xc_domain_create(xc_handle, nr_pfns * (PAGE_SIZE / 1024),
+ /* ssidref to be tested... R Sailer */
+ if ( xc_domain_create(xc_handle, 0xffffffff, nr_pfns * (PAGE_SIZE / 1024),
-1, 1, &dom) )
{
xcio_error(ioctxt, "Could not create domain. pfns=%d, %dKB",
diff -Naur xeno-unstable.bk_orig/tools/Makefile xeno-unstable.bk/tools/Makefile
--- xeno-unstable.bk_orig/tools/Makefile 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/Makefile 2005-03-29 19:12:44.000000000 -0500
@@ -11,6 +11,7 @@
SUBDIRS += xfrd
SUBDIRS += xcs
SUBDIRS += ioemu
+SUBDIRS += policy
.PHONY: all install clean check check_clean
diff -Naur xeno-unstable.bk_orig/tools/policy/Makefile xeno-unstable.bk/tools/policy/Makefile
--- xeno-unstable.bk_orig/tools/policy/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/tools/policy/Makefile 2005-03-29 19:12:44.000000000 -0500
@@ -0,0 +1,36 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+SRCS = policy_tool.c
+CFLAGS += -static
+CFLAGS += -Wall
+CFLAGS += -Werror
+CFLAGS += -O3
+CFLAGS += -fno-strict-aliasing
+CFLAGS += -I.
+
+all: build
+build: mk-symlinks
+ $(MAKE) policy_tool
+
+default: all
+
+install: all
+
+policy_tool : policy_tool.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+clean:
+ rm -rf policy_tool xen
+
+
+LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
+mk-symlinks:
+ [ -e xen/linux ] || mkdir -p xen/linux
+ [ -e xen/io ] || mkdir -p xen/io
+ ( cd xen >/dev/null ; \
+ ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
+ ( cd xen/io >/dev/null ; \
+ ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
+ ( cd xen/linux >/dev/null ; \
+ ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
diff -Naur xeno-unstable.bk_orig/tools/policy/policy_tool.c xeno-unstable.bk/tools/policy/policy_tool.c
--- xeno-unstable.bk_orig/tools/policy/policy_tool.c 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk/tools/policy/policy_tool.c 2005-03-29 23:00:13.758065176 -0500
@@ -0,0 +1,423 @@
+/****************************************************************
+ * policy_tool.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype policy management tool. This code runs in a domain and
+ * manages the Xen security policy by interacting with the
+ * Xen access control module via a /proc/xen/policycmd proc-ioctl,
+ * which is translated into a policy_op hypercall into Xen.
+ *
+ * todo: implement setpolicy to dynamically set a policy cache.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdint.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+#include <xen/acm.h>
+
+#include <xen/policy_ops.h>
+
+#include <xen/linux/policycmd.h>
+
+#define ERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m "\n" , ## _a )
+
+#define PERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
+ errno, strerror(errno))
+
+static inline int do_policycmd(int xc_handle,
+ unsigned int cmd,
+ unsigned long data)
+{
+ return ioctl(xc_handle, cmd, data);
+}
+
+static inline int do_xen_hypercall(int xc_handle,
+ policycmd_hypercall_t *hypercall)
+{
+ return do_policycmd(xc_handle,
+ IOCTL_POLICYCMD_HYPERCALL,
+ (unsigned long)hypercall);
+}
+
+static inline int do_policy_op(int xc_handle, policy_op_t *op)
+{
+ int ret = -1;
+ policycmd_hypercall_t hypercall;
+
+ op->interface_version = POLICY_INTERFACE_VERSION;
+
+ hypercall.op = __HYPERVISOR_policy_op;
+ hypercall.arg[0] = (unsigned long)op;
+
+ if ( mlock(op, sizeof(*op)) != 0 )
+ {
+ PERROR("Could not lock memory for Xen policy hypercall");
+ goto out1;
+ }
+
+ if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+ {
+ if ( errno == EACCES )
+ fprintf(stderr, "POLICY operation failed -- need to"
+ " rebuild the user-space tool set?\n");
+ goto out2;
+ }
+
+ out2: (void)munlock(op, sizeof(*op));
+ out1: return ret;
+}
+
+/*************************** DUMPS *******************************/
+
+void acm_dump_chinesewall_buffer(void *buf, int buflen) {
+
+ acm_chwall_policy_buffer_t *cwbuf = (acm_chwall_policy_buffer_t *)buf;
+ domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
+ int i,j;
+
+
+ if (cwbuf->policy_code != ACM_CHINESE_WALL_POLICY) {
+ printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\n\nChinese Wall policy:\n");
+ printf("====================\n");
+ printf("Max Types = %x.\n", cwbuf->chwall_max_types);
+ printf("Max Ssidrefs = %x.\n", cwbuf->chwall_max_ssidrefs);
+ printf("Max ConfSets = %x.\n", cwbuf->chwall_max_conflictsets);
+ printf("Ssidrefs Off = %x.\n", cwbuf->chwall_ssid_offset);
+ printf("Conflicts Off = %x.\n", cwbuf->chwall_conflict_sets_offset);
+ printf("Runing T. Off = %x.\n", cwbuf->chwall_running_types_offset);
+ printf("C. Agg. Off = %x.\n", cwbuf->chwall_conflict_aggregate_offset);
+ printf("\nSSID To CHWALL-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + cwbuf->chwall_ssid_offset);
+ for(i=0; i< cwbuf->chwall_max_ssidrefs; i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< cwbuf->chwall_max_types; j++)
+ printf("%02x ", ssids[i*cwbuf->chwall_max_types +j]);
+ }
+ printf("\n\nConfict Sets:\n");
+ conflicts = (domaintype_t *)(buf + cwbuf->chwall_conflict_sets_offset);
+ for(i=0; i< cwbuf->chwall_max_conflictsets; i++) {
+ printf("\n c-set%2x: ", i);
+ for(j=0; j< cwbuf->chwall_max_types; j++)
+ printf("%02x ", conflicts[i*cwbuf->chwall_max_types +j]);
+ }
+ printf("\n");
+
+ printf("\nRunning\nTypes: ");
+ if (cwbuf->chwall_running_types_offset) {
+ running_types = (domaintype_t *)(buf + cwbuf->chwall_running_types_offset);
+ for(i=0; i< cwbuf->chwall_max_types; i++) {
+ printf("%02x ", running_types[i]);
+ }
+ printf("\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+ printf("\nConflict\nAggregate Set: ");
+ if (cwbuf->chwall_conflict_aggregate_offset) {
+ conflict_aggregate = (domaintype_t *)(buf + cwbuf->chwall_conflict_aggregate_offset);
+ for(i=0; i< cwbuf->chwall_max_types; i++) {
+ printf("%02x ", conflict_aggregate[i]);
+ }
+ printf("\n\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+}
+
+void acm_dump_ste_buffer(void *buf, int buflen) {
+
+ acm_ste_policy_buffer_t *stebuf = (acm_ste_policy_buffer_t *)buf;
+ domaintype_t *ssids;
+ int i,j;
+
+
+ if (stebuf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\nSimple Type Enforcement policy:\n");
+ printf("===============================\n");
+ printf("Max Types = %x.\n", stebuf->ste_max_types);
+ printf("Max Ssidrefs = %x.\n", stebuf->ste_max_ssidrefs);
+ printf("Ssidrefs Off = %x.\n", stebuf->ste_ssid_offset);
+ printf("\nSSID To STE-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + stebuf->ste_ssid_offset);
+ for(i=0; i< stebuf->ste_max_ssidrefs; i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< stebuf->ste_max_types; j++)
+ printf("%02x ", ssids[i*stebuf->ste_max_types +j]);
+ }
+ printf("\n\n");
+}
+
+void acm_dump_policy_buffer(void *buf, int buflen) {
+ acm_policy_buffer_t *pol = (acm_policy_buffer_t *)buf;
+
+ /* int i;
+ * for (i=0; i< buflen; i++)
+ * printf(" %02x", ((u8 *)buf)[i]);
+ */
+ printf("\nPolicy dump:\n");
+ printf("============\n");
+ printf("Magic = %x.\n", pol->magic);
+ printf("PolVer = %x.\n", pol->policyversion);
+ printf("Len = %x.\n", pol->len);
+ printf("Primary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME((pol->primary_policy_code)),
+ pol->primary_policy_code, pol->primary_buffer_offset);
+ printf("Secondary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME((pol->secondary_policy_code)),
+ pol->secondary_policy_code, pol->secondary_buffer_offset);
+ switch (pol->primary_policy_code) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+pol->primary_buffer_offset,
+ pol->len - pol->primary_buffer_offset);
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+pol->primary_buffer_offset,
+ pol->len - pol->primary_buffer_offset);
+ break;
+ case ACM_NULL_POLICY:
+ printf("No primary policy (NULL).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ switch (pol->secondary_policy_code) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+pol->secondary_buffer_offset,
+ pol->len - pol->secondary_buffer_offset);
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+pol->secondary_buffer_offset,
+ pol->len - pol->secondary_buffer_offset);
+ break;
+ case ACM_NULL_POLICY:
+ printf("No secondary policy (NULL).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ printf("\nPolicy dump End.\n\n");
+}
+
+/*************************** set policy ****************************/
+
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
+#define CWALL_MAX_SSIDREFS 5
+#define CWALL_MAX_TYPES 10
+#define CWALL_MAX_CONFLICTSETS 2
+
+ acm_chwall_policy_buffer_t *chwall_bin_pol = (acm_chwall_policy_buffer_t *)bufstart;
+ domaintype_t *ssidrefs, *conflicts;
+ int ret = 0;
+ int i,j;
+
+ chwall_bin_pol->chwall_max_types = CWALL_MAX_TYPES;
+ chwall_bin_pol->chwall_max_ssidrefs = CWALL_MAX_SSIDREFS;
+ chwall_bin_pol->policy_code = ACM_CHINESE_WALL_POLICY;
+ chwall_bin_pol->chwall_ssid_offset = sizeof(acm_chwall_policy_buffer_t);
+ chwall_bin_pol->chwall_max_conflictsets = CWALL_MAX_CONFLICTSETS;
+ chwall_bin_pol->chwall_conflict_sets_offset =
+ chwall_bin_pol->chwall_ssid_offset +
+ sizeof(domaintype_t)*CWALL_MAX_SSIDREFS*CWALL_MAX_TYPES;
+ chwall_bin_pol->chwall_running_types_offset = 0; /* not set */
+ chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */
+ ret += sizeof(acm_chwall_policy_buffer_t);
+ /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
+ /* check buffer size */
+ if ((buflen - ret) < (CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+chwall_bin_pol->chwall_ssid_offset);
+ for(i=0; i< CWALL_MAX_SSIDREFS; i++) {
+ for (j=0; j< CWALL_MAX_TYPES; j++)
+ ssidrefs[i*CWALL_MAX_TYPES + j] = 0;
+ /* here, set type i for ssidref i; generally, a ssidref can have multiple chwall types */
+ if (i < CWALL_MAX_SSIDREFS)
+ ssidrefs[i*CWALL_MAX_TYPES + i] = 1;
+ }
+ ret += CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t);
+ if ((buflen - ret) < (CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ /* now the chinese wall policy conflict sets*/
+ conflicts = (domaintype_t *)(bufstart +
+ chwall_bin_pol->chwall_conflict_sets_offset);
+ memset((void *)conflicts, 0, CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t));
+ /* just 1 conflict set [0]={2,3}, [1]={0,5,6} */
+ if (CWALL_MAX_TYPES > 3) {
+ conflicts[2] = 1; conflicts[3] = 1; /* {2,3} */
+ conflicts[CWALL_MAX_TYPES] = 1; conflicts[CWALL_MAX_TYPES+5] = 1;
+ conflicts[CWALL_MAX_TYPES+6] = 1;/* {0,5,6} */
+ }
+ ret += sizeof(domaintype_t)*CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES;
+ return ret;
+}
+
+int acm_domain_set_stepolicy(void *bufstart, int buflen) {
+#define STE_MAX_SSIDREFS 5
+#define STE_MAX_TYPES 5
+
+ acm_ste_policy_buffer_t *ste_bin_pol = (acm_ste_policy_buffer_t *)bufstart;
+ domaintype_t *ssidrefs;
+ int i,j, ret = 0;
+
+ ste_bin_pol->ste_max_types = STE_MAX_TYPES;
+ ste_bin_pol->ste_max_ssidrefs = STE_MAX_SSIDREFS;
+ ste_bin_pol->policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ste_bin_pol->ste_ssid_offset = sizeof(acm_ste_policy_buffer_t);
+ ret += sizeof(acm_ste_policy_buffer_t);
+ /* check buffer size */
+ if ((buflen - ret) < (STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+ste_bin_pol->ste_ssid_offset);
+ for(i=0; i< STE_MAX_SSIDREFS; i++) {
+ for (j=0; j< STE_MAX_TYPES; j++)
+ ssidrefs[i*STE_MAX_TYPES + j] = 0;
+ /* set type i in ssidref 0 and ssidref i */
+ ssidrefs[i] = 1; /* ssidref 0 has all types set */
+ if (i < STE_MAX_SSIDREFS)
+ ssidrefs[i*STE_MAX_TYPES + i] = 1;
+ }
+ ret += STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t);
+ return ret;
+}
+
+#define MAX_PUSH_BUFFER 16384
+u8 push_buffer[MAX_PUSH_BUFFER];
+
+int acm_domain_setpolicy(int xc_handle)
+{
+ int ret;
+ acm_policy_buffer_t *bin_pol;
+ policy_op_t op;
+
+ /* future: read policy from file and set it */
+ bin_pol = (acm_policy_buffer_t *)push_buffer;
+ bin_pol->magic = ACM_MAGIC;
+ bin_pol->policyversion = POLICY_INTERFACE_VERSION;
+ bin_pol->primary_policy_code = ACM_CHINESE_WALL_POLICY;
+ bin_pol->secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+
+ bin_pol->len = sizeof(acm_policy_buffer_t);
+ bin_pol->primary_buffer_offset = bin_pol->len;
+ ret = acm_domain_set_chwallpolicy(push_buffer + bin_pol->primary_buffer_offset,
+ MAX_PUSH_BUFFER - bin_pol->primary_buffer_offset);
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len += ret;
+ bin_pol->secondary_buffer_offset = bin_pol->len;
+ ret = acm_domain_set_stepolicy(push_buffer + bin_pol->secondary_buffer_offset,
+ MAX_PUSH_BUFFER - bin_pol->secondary_buffer_offset);
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len += ret;
+
+ /* dump it and then push it down into xen/acm */
+ acm_dump_policy_buffer(push_buffer, bin_pol->len);
+ op.cmd = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)push_buffer;
+ op.u.setpolicy.pushcache_size = bin_pol->len;
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_op(xc_handle, &op);
+
+ if (ret)
+ printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+ else
+ printf("Successfully changed policy.\n");
+ return ret;
+}
+
+/******************************* get policy ******************************/
+
+#define PULL_CACHE_SIZE 8192
+u8 pull_buffer[PULL_CACHE_SIZE];
+int acm_domain_getpolicy(int xc_handle)
+{
+ policy_op_t op;
+ int ret;
+
+ memset(pull_buffer, 0x00, sizeof(pull_buffer));
+ op.cmd = POLICY_GETPOLICY;
+ op.u.getpolicy.pullcache = (void *)pull_buffer;
+ op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = do_policy_op(xc_handle, &op);
+ /* dump policy */
+ acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+ return ret;
+}
+
+/***************************** main **************************************/
+
+void
+usage(char *progname){
+ printf("Use: %s \n\t setpolicy\n\t getpolicy\n", progname);
+ exit(-1);
+}
+
+int
+main(int argc, char **argv) {
+
+ int policycmd_fd;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ if ((policycmd_fd = open("/proc/xen/policycmd", O_RDONLY)) == 0) {
+ printf("ERROR: Could not open xen policycmd device!\n");
+ exit(-1);
+ }
+
+ if (!strcmp(argv[1], "setpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_setpolicy(policycmd_fd);
+ } else if (!strcmp(argv[1], "getpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_getpolicy(policycmd_fd);
+ } else
+ usage(argv[0]);
+
+ close(policycmd_fd);
+ return 0;
+}
diff -Naur xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c xeno-unstable.bk/tools/python/xen/lowlevel/xc/xc.c
--- xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/lowlevel/xc/xc.c 2005-03-29 19:12:44.000000000 -0500
@@ -47,15 +47,16 @@
float cpu_weight = 1;
u32 dom = 0;
int ret;
+ u32 ssidref=5;
- static char *kwd_list[] = { "dom", "mem_kb", "cpu", "cpu_weight", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiif", kwd_list,
- &dom, &mem_kb, &cpu, &cpu_weight))
+ static char *kwd_list[] = { "dom", "ssidref", "mem_kb", "cpu", "cpu_weight", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiiif", kwd_list,
+ &dom, &ssidref, &mem_kb, &cpu, &cpu_weight))
return NULL;
if ( (ret = xc_domain_create(
- xc->xc_handle, mem_kb, cpu, cpu_weight, &dom)) < 0 )
+ xc->xc_handle, ssidref, mem_kb, cpu, cpu_weight, &dom)) < 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
@@ -171,7 +172,7 @@
PyList_SetItem(
list, i,
Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
- ",s:l,s:L,s:l,s:i}",
+ ",s:l,s:L,s:l,s:i,s:i}",
"dom", info[i].domid,
"cpu", info[i].cpu,
"dying", info[i].dying,
@@ -183,6 +184,7 @@
"mem_kb", info[i].nr_pages*4,
"cpu_time", info[i].cpu_time,
"maxmem_kb", info[i].max_memkb,
+ "ssidref", info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason
));
}
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py xeno-unstable.bk/tools/python/xen/xend/server/SrvDomainDir.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xend/server/SrvDomainDir.py 2005-03-29 19:12:44.000000000 -0500
@@ -151,6 +151,7 @@
% (url, d.name, d.name))
req.write('id=%s' % d.id)
req.write('memory=%d'% d.memory)
+ req.write('ssidref=%d'% d.ssidref)
req.write('</li>')
req.write('</ul>')
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py xeno-unstable.bk/tools/python/xen/xend/XendDomainInfo.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xend/XendDomainInfo.py 2005-03-29 19:12:44.000000000 -0500
@@ -148,7 +148,7 @@
def add_image_handler(name, h):
"""Add a handler for an image type
@param name: image type
- @param h: handler: fn(config, name, memory, image)
+ @param h: handler: fn(config, name, memory, ssidref, image)
"""
image_handlers[name] = h
@@ -300,6 +300,7 @@
self.start_time = None
self.name = None
self.memory = None
+ self.ssidref = None
self.image = None
self.ramdisk = None
self.cmdline = None
@@ -337,12 +338,14 @@
"""
self.info = info
self.memory = self.info['mem_kb'] / 1024
+ self.ssidref = self.info['ssidref']
def __str__(self):
s = "domain"
s += " id=" + self.id
s += " name=" + self.name
s += " memory=" + str(self.memory)
+ s += " ssidref=" + str(self.ssidref)
if self.console:
s += " console=" + str(self.console.console_port)
if self.image:
@@ -356,7 +359,8 @@
sxpr = ['domain',
['id', self.id],
['name', self.name],
- ['memory', self.memory] ]
+ ['memory', self.memory],
+ ['ssidref', self.ssidref]]
if self.info:
sxpr.append(['maxmem', self.info['maxmem_kb']/1024 ])
@@ -447,6 +451,7 @@
self.memory = int(sxp.child_value(config, 'memory'))
if self.memory is None:
raise VmError('missing memory size')
+ self.ssidref = int(sxp.child_value(config, 'ssidref'))
cpu = sxp.child_value(config, 'cpu')
if self.recreate and self.dom and cpu is not None:
xc.domain_pincpu(self.dom, int(cpu))
@@ -455,7 +460,6 @@
self.vcpus = int(sxp.child_value(image, 'vcpus'))
except:
raise VmError('invalid vcpus value')
-
self.find_image_handler()
self.init_domain()
self.configure_console()
@@ -716,7 +720,7 @@
def show(self):
"""Print virtual machine info.
"""
- print "[VM dom=%d name=%s memory=%d" % (self.dom, self.name, self.memory)
+ print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.dom, self.name, self.memory, self.ssidref)
print "image:"
sxp.show(self.image)
print
@@ -742,6 +746,7 @@
return
dom = self.dom or 0
memory = self.memory
+ ssidref = self.ssidref
name = self.name
# If the name is over the xen limit, use the end of it.
if len(name) > MAX_DOMAIN_NAME:
@@ -752,12 +757,14 @@
raise VmError('invalid cpu')
cpu_weight = self.cpu_weight
memory = memory * 1024 + self.pgtable_size(memory)
- dom = xc.domain_create(dom= dom, mem_kb= memory,
+ dom = xc.domain_create(dom= dom, ssidref= ssidref, mem_kb= memory,
cpu= cpu, cpu_weight= cpu_weight)
+ #dom = xc.domain_create(dom= dom, mem_kb= memory,
+ # cpu= cpu, cpu_weight= cpu_weight)
if dom <= 0:
raise VmError('Creating domain failed: name=%s memory=%d'
% (name, memory))
- log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
+ log.debug('init_domain> Created domain=%d name=%s memory=%d ssidref=%d', dom, name, memory, ssidref)
self.setdom(dom)
def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap):
@@ -805,7 +812,6 @@
@param ramdisk: kernel ramdisk
@param cmdline: kernel commandline
"""
-
self.create_channel()
if self.console:
self.console.registerChannel()
@@ -860,6 +866,7 @@
device_model = sxp.child_value(self.config, 'device_model')
device_config = sxp.child_value(self.config, 'device_config')
memory = sxp.child_value(self.config, "memory")
+ ssidref = sxp.child_value(self.config, "ssidref")
# Create an event channel
device_channel = channel.eventChannel(0, self.dom)
# Fork and exec device_model -f device_config <port>
@@ -1082,6 +1089,7 @@
self.setdom(dom)
#self.name = d['name']
self.memory = d['mem_kb']/1024
+ self.ssidref = d['ssidref']
deferred = self.construct(config)
finally:
self.restore = 0
@@ -1346,6 +1354,7 @@
# Ignore the fields we already handle.
add_config_handler('name', vm_field_ignore)
add_config_handler('memory', vm_field_ignore)
+add_config_handler('ssidref', vm_field_ignore)
add_config_handler('cpu', vm_field_ignore)
add_config_handler('cpu_weight', vm_field_ignore)
add_config_handler('console', vm_field_ignore)
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xm/create.py xeno-unstable.bk/tools/python/xen/xm/create.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/create.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xm/create.py 2005-03-29 19:12:44.000000000 -0500
@@ -110,6 +110,10 @@
fn=set_int, default=128,
use="Domain memory in MB.")
+gopts.var('ssidref', val='SSIDREF',
+ fn=set_int, default=05,
+ use="Security Identifier.")
+
gopts.var('maxmem', val='MEMORY',
fn=set_int, default=None,
use="Maximum domain memory in MB.")
@@ -379,9 +383,10 @@
"""Create the domain configuration.
"""
- config = ['vm',
+ config = ['vm',
['name', vals.name ],
- ['memory', vals.memory ]]
+ ['memory', vals.memory ],
+ ['ssidref', vals.ssidref ]]
if vals.maxmem:
config.append(['maxmem', vals.maxmem])
if vals.cpu is not None:
diff -Naur xeno-unstable.bk_orig/tools/python/xen/xm/main.py xeno-unstable.bk/tools/python/xen/xm/main.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/main.py 2005-03-29 19:10:18.000000000 -0500
+++ xeno-unstable.bk/tools/python/xen/xm/main.py 2005-03-29 19:12:44.000000000 -0500
@@ -350,7 +350,7 @@
self.brief_list(doms)
def brief_list(self, doms):
- print 'Name Id Mem(MB) CPU State Time(s) Console'
+ print 'Name Id Mem(MB) CPU State Time(s) Console SSID-REF'
for dom in doms:
info = server.xend_domain(dom)
d = {}
@@ -365,7 +365,9 @@
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
- print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f %(port)4s"
+ d['ssidref1'] = int(sxp.child_value(info, 'ssidref', '-1')) & 0xffff
+ d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '-1')) >> 16) & 0xffff
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f %(port)4s s:%(ssidref2)02x/p:%(ssidref1)02x"
% d)
def long_list(self, doms):
[-- Attachment #5: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [patches] shype for xen / patches
2005-03-30 5:23 [patches] shype for xen / patches Reiner Sailer
@ 2005-03-31 17:36 ` David Hopwood
0 siblings, 0 replies; 3+ messages in thread
From: David Hopwood @ 2005-03-31 17:36 UTC (permalink / raw)
To: xen-devel
Reiner Sailer wrote:
> Comments/feedback related to these patches are very welcome.
+++ xeno-unstable.bk/tools/policy/policy_tool.c 2005-03-29 ...
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
+#define CWALL_MAX_SSIDREFS 5
+#define CWALL_MAX_TYPES 10
+#define CWALL_MAX_CONFLICTSETS 2
+int acm_domain_set_stepolicy(void *bufstart, int buflen) {
+#define STE_MAX_SSIDREFS 5
+#define STE_MAX_TYPES 5
+++ xeno-unstable.bk/tools/python/xen/lowlevel/xc/xc.c 2005-03-29 ...
+ u32 ssidref=5;
+++ xeno-unstable.bk/tools/python/xen/xm/create.py 2005-03-29 ...
+gopts.var('ssidref', val='SSIDREF',
+ fn=set_int, default=05,
+ use="Security Identifier.")
What are all these magic numbers (5, 10, etc.)?
--
David Hopwood <david.nospam.hopwood@blueyonder.co.uk>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-03-31 17:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-30 5:23 [patches] shype for xen / patches Reiner Sailer
2005-03-31 17:36 ` David Hopwood
-- strict thread matches above, loose matches on Subject: below --
2005-03-30 5:11 Reiner Sailer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.