* [PATCH] sHype access control architecture for Xen
@ 2005-06-20 17:22 Reiner Sailer
2005-06-21 5:47 ` aq
0 siblings, 1 reply; 11+ messages in thread
From: Reiner Sailer @ 2005-06-20 17:22 UTC (permalink / raw)
To: xense-devel, steven.hand
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, stefanb
[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]
This E-mail contains the sHype access control architecture
for inclusion into the Xen hypervisor (xeno-unstable.bk).
This is a follow-up on earlier postings:
http://lists.xensource.com/archives/html/xen-devel/2005-04/msg00864.html
The *_xen.diff patch includes the core sHype access control
architecture. Default is the NULL-policy.
The *_tools.diff patch includes the necessary additions to the
tools directory:
a) adding support for an additional VM configuration paramter
b) adding basic policy management support into tools/policy
The default setting is the NULL policy. After patching in the diff-
files, you should see no change in behavior. Please refer to the
attached shype4xen_readme.txt file for instructions on how to
activate and experiment with sHype.
While we have added support for saving and restoring security
information when saving and restoring domains, the architecture
currently supports save/restore only on the same hypervisor system
running the same sHype policy. Future versions will include more
flexible support for save/restore/migration.
Our group will submit a java-based policy translation tool for sHype to
this mailing list today as well. This tool takes as input an XML-based
descriptions of user-defined sHype policies and translates them into a
binary policy format that can be loaded into sHype.
Thanks
Reiner
Signed-off by: Reiner Sailer <sailer@us.ibm.com>
Signed-off by: Stefan Berger <stefanb@us.ibm.com>
[-- Attachment #2: shype4xen_readme.txt --]
[-- Type: text/plain, Size: 21150 bytes --]
Copyright: IBM Corporation (C)
20 June 2005
Author: Reiner Sailer
This document is a very short introduction into the sHype access control
security architecture implementation and how it is perceived by users. It
is a very preliminary draft for the courageous ones to get "their feet wet"
and to be able to give feedback (via the xen-devel/xense-devel mailing lists).
Install:
cd into xeno-unstable.bk
(use --dry-run option if you want to test the patch only)
patch -p1 -g0 < *tools.diff
patch -p1 -g0 < *xen.diff
(no rejects, probably some line offsets)
make uninstall; make mrproper; make; ./install.sh should install the default
sHype into Xen (rebuild your initrd images if necessary). Reboot.
Debug output: there are two triggers for debug output:
a) General sHype debug:
xeno-unstable.bk/xen/include/public/acm.h
undefine ACM_DEBUG to switch this debug off
b) sHype enforcement hook trace: This prints a small trace for each enforcement
hook that is executed. The trigger is in
xeno-unstable.bk/xen/include/acm/acm_hooks.h
undefine ACM_TRACE_MODE to switch this debug off
1. The default NULL policy
***************************
When you apply the patches and startup xen, you should at first not notice any
difference because the default policy is the "NULL" policy, which as the name
implies does not enforce anything.
However, when you try
[root@laptop policy]# xm list
Name Id Mem(MB) CPU State Time(s) Console SSID-REF
Domain-0 0 620 0 r---- 25.6 default
You might detect a new parameter "SSID-REF" displayed for domains. This
parameter describes the subject security identifier reference of the domain. It
is shown as "default" since there is no policy to be enforced.
To display the currently enforced policy, use the policy tool under xeno-
unstable.bk/tools/policy: policy_tool getpolicy. You should see output like the
one below.
[root@laptop policy]#./policy_tool getpolicy
Policy dump:
============
Magic = 1debc.
PolVer = aaaa0000.
Len = 14.
Primary = NULL policy (c=0, off=14).
Secondary = NULL policy (c=0, off=14).
No primary policy (NULL).
No secondary policy (NULL).
Policy dump End.
Since this is a dump of a binary policy, it's not pretty. The important parts
are the "Primary" and "Secondary" policy fields set to "NULL policy". sHype
currently allows to set two independent policies; thus the two SSID-REF parts
shown in 'xm list'. Right here: primary policy only means this policy is
checked first, the secondary policy is checked if the primary results in
"permitted access". The result of the combined policy is "permitted" if both
policies return permitted (NULL policy always returns permitted). The result is
"denied" if at least one of the policies returns "denied". Look into xeno-
unstable.bk/xen/include/acm/acm_hooks.h for the general hook structure
integrating the policy decisions (if you like, you won't need it for the rest
of the Readme file).
2. Setting Chinese Wall and Simple Type Enforcement policies:
*************************************************************
We'll get fast to the point. However, in order to understand what we are doing,
we must at least understand the purpose of the policies that we are going to
enforce. The two policies presented here are just examples and the
implementation encourages adding new policies easily.
2.1. Chinese Wall policy: "decides whether a domain can be started based on
this domain's ssidref and the ssidrefs of the currently running domains".
Generally, the Chinese wall policy allows specifying certain types (or classes
or categories, whatever the preferred word) that conflict; we usually assign a
type to a workload and the set of types of those workloads running in a domain
make up the type set for this domain. Each domain is assigned a set of types
through its SSID-REF (we register Chinese Wall as primary policy, so the
ssidref used for determining the Chinese Wall types is the one annotated with
"p:" in xm list) since each SSID-REF points at a set of types. We'll see how
SSIDREFs are represented in Xen later when we will look at the policy. (A good
read for Chinese Wall is: Brewer/Nash The Chinese Wall Security Policy 1989.)
So let's assume the Chinese Wall policy we are running distinguishes 10 types:
t0 ... t9. Let us assume further that each SSID-REF points to a set that
includes exactly one type (attached to domains that run workloads of a single
type). SSID-REF 0 points to {t0}, ssidref 1 points to {t1} ... 9 points to
{t9}. [This is actually the example policy we are going to push into xen later]
Now the Chinese Wall policy allows you to define "Conflict type sets" and it
guarantees that of any conflict set at most one type is "running" at any time.
As an example, we have defined 2 conflict set: {t2, t3} and {t0, t5, t6}.
Specifying these conflict sets, sHype ensures that at most one type of each set
is running (either t2 or t3 but not both; either t0 or t5 or t6 but not
multiple of them).
The effect is that administrators can define which workload types cannot run
simultaneously on a single Xen system. This is useful to limit the covert
timing channels between such payloads or to ensure that payloads don't
interfere with each other through existing resource dependencies.
2.2. Simple Type Enforcement (ste) policy: "decides whether two domains can
share data, e.g., setup event channels or grant tables to each other, based on
the two domains' ssidref. This, as the name says, is a simple policy. Think of
each type as of a single color. Each domain has one or more colors, i.e., the
domains ssid for the ste policy points to a set that has set one or multiple
types. Let us assume in our example policy we differentiate 5 colors (types)
and define 5 different ssids referenced by ssidref=0..4. Each ssid shall have
exactly one type set, i.e., describes a uni-color. Only ssid(0) has all types
set, i.e., has all defined colors.
Sharing is enforced by the ste policy by requiring that two domains that want
to establish an event channel or grant pages to each other must have a common
color. Currently all domains communicate through DOM0 by default; i.e., Domain0
will necessarily have all colors to be able to create domains (thus, we will
assign ssidref(0) to Domain0 in our example below.
More complex mandatory access control policies governing sharing will follow;
such policies are more sophisticated than the "color" scheme above by allowing
more flexible (and complex :_) access control decisions than "share a color" or
"don't share a color" and will be able to express finer-grained policies.
2.3 Binary Policy:
In the future, we will have a policy tool that takes as input a more humane
policy description, using types such as development, home-banking, donated-
Grid, CorpA-Payload ... and translates the respective policy into what we see
today as the binary policy using 1s and 0s and sets of them. For now, we must
live with the binary policy when working with sHype.
2.4 Exemplary use of a real sHype policy on Xen. To activate a real policy,
edit the file (yes, this will soon be a compile option):
xeno-unstable.bk/xen/include/public/acm.h
Change: #define ACM_USE_SECURITY_POLICY ACM_NULL_POLICY
To : #define ACM_USE_SECURITY_POLICY ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
cd xeno-unstable.bk
make mrproper
make uninstall (manually remove /etc/xen.old if necessary)
make
./install.sh (recreate your kernel initrd's if necessary)
Reboot into new xen.gz
After booting, check out 'xm dmesg'; should show somewhere in the middle:
(XEN) acm_init: Enforcing Primary CHINESE WALL policy, Secondary SIMPLE TYPE
ENFORCEMENT policy.
Even though you can activate those policies in any combination and also
independently, the policy tool currently only supports setting the policy for
the above combination.
Now look at the minimal startup policy with:
xeno-unstable.bk/tools/policytool getpolicy
You should see something like:
[root@laptop policy]# ./policy_tool getpolicy
Policy dump:
============
Magic = 1debc.
PolVer = aaaa0000.
Len = 36.
Primary = CHINESE WALL policy (c=1, off=14).
Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=2c).
Chinese Wall policy:
====================
Max Types = 1.
Max Ssidrefs = 1.
Max ConfSets = 1.
Ssidrefs Off = 10.
Conflicts Off = 12.
Runing T. Off = 14.
C. Agg. Off = 16.
SSID To CHWALL-Type matrix:
ssidref 0: 00
Confict Sets:
c-set 0: 00
Running
Types: 00
Conflict
Aggregate Set: 00
Simple Type Enforcement policy:
===============================
Max Types = 1.
Max Ssidrefs = 1.
Ssidrefs Off = 8.
SSID To STE-Type matrix:
ssidref 0: 01
Policy dump End.
This is a minimal policy (of little use), except it will disable starting any
domain that does not have ssidref set to 0x0. The Chinese Wall policy has
nothing to enforce and the ste policy only knows one type, which is set for the
only defined ssidref.
The item that defines the ssidref in a domain configuration is:
ssidref = 0x12345678
Where ssidref is interpreted as a 32bit number, where the lower 16bits become
the ssidref for the primary policy and the higher 16bits become the ssidref for
the secondary policy. sHype currently supports two policies but this is an
implementation decision and can be extended if necessary.
This reference defines the security information of a domain. The meaning of the
SSID-REF depends on the policy, so we explain it when we explain the real
policies.
Setting a new Security Policy:
******************************
The policy tool with all its current limitations has one usable example policy
compiled-in. Please try at this time to use the setpolicy command:
xeno-unstable.bk/tools/policy/policy_tool setpolicy
You should see a dump of the policy you are setting. It should say at the very
end:
Policy successfully set.
Now try to dump the currently enforced policy, which is the policy we have just
set and the dynamic security state information of this policy
(<<< ... some additional explanations)
[root@laptop policy]# ./policy_tool getpolicy
Policy dump:
============
Magic = 1debc.
PolVer = aaaa0000.
Len = 112.
Primary = CHINESE WALL policy (c=1, off=14).
Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
Chinese Wall policy:
====================
Max Types = a.
Max Ssidrefs = 5.
Max ConfSets = 2.
Ssidrefs Off = 10.
Conflicts Off = 74.
Runing T. Off = 9c.
C. Agg. Off = b0.
SSID To CHWALL-Type matrix:
ssidref 0: 01 00 00 00 00 00 00 00 00 00 <<< type0 is set for ssidref0
ssidref 1: 00 01 00 00 00 00 00 00 00 00
ssidref 2: 00 00 01 00 00 00 00 00 00 00
ssidref 3: 00 00 00 01 00 00 00 00 00 00
ssidref 4: 00 00 00 00 01 00 00 00 00 00 <<< type4 is set for ssidref4
<<< types 5-9 are unused
Confict Sets:
c-set 0: 00 00 01 01 00 00 00 00 00 00 <<< type2 and type3 never run together
c-set 1: 01 00 00 00 00 01 01 00 00 00 <<< only one of types 0, 5 or 6
<<< can run simultaneously
Running
Types: 01 00 00 00 00 00 00 00 00 00 <<< ref-count for types of running domains
Conflict
Aggregate Set: 00 00 00 00 00 01 01 00 00 00 <<< aggregated set of types that
<<< cannot run because they
<<< are in conflict set 1 and
<<< (domain 0 is running w t0)
Simple Type Enforcement policy:
===============================
Max Types = 5.
Max Ssidrefs = 5.
Ssidrefs Off = 8.
SSID To STE-Type matrix:
ssidref 0: 01 01 01 01 01 <<< ssidref0 points to a set that
<<< has all types set (colors)
ssidref 1: 00 01 00 00 00 <<< ssidref1 has color1 set
ssidref 2: 00 00 01 00 00 <<< ...
ssidref 3: 00 00 00 01 00
ssidref 4: 00 00 00 00 01
Policy dump End.
This is a small example policy with which we will demonstrate the enforcement.
Starting Domains with policy enforcement
========================================
Now let us play with this policy.
Define 3 or 4 domain configurations. I use the following config using a ramdisk
only and about 8MBytes of memory for each DomU (test purposes):
#-------configuration xmsec1-------------------------
kernel = "/boot/vmlinuz-2.6.11-xenU"
ramdisk="/boot/U1_ramdisk.img"
#security reference identifier
ssidref= 0x00010001
memory = 10
name = "xmsec1"
cpu = -1 # leave to Xen to pick
# Number of network interfaces. Default is 1.
nics=1
dhcp="dhcp"
#-----------------------------------------------------
xmsec2 and xmsec3 look the same except for the name and the ssidref line. Use
your domain config file and add "ssidref = 0x00010001" to the first (xmsec1),
"ssidref= 0x00020002" to the second (call it xmsec2), and "ssidref=0x00030003"
to the third (we will call this one xmsec3).
First start xmsec1: xm create -c xmsec1 (succeeds)
Then
[root@laptop policy]# xm list
Name Id Mem(MB) CPU State Time(s) Console SSID-REF
Domain-0 0 620 0 r---- 42.3 s:00/p:00
xmnosec 1 9 0 -b--- 0.3 9601 s:00/p:05
xmsec1 2 9 0 -b--- 0.2 9602 s:01/p:01
Shows a new domain xmsec1 running with primary (here: chinese wall) ssidref 1
and secondary (here: simple type enforcement) ssidref 1. The ssidrefs are
independent and can differ for a domain.
[root@laptop policy]# ./policy_tool getpolicy
Policy dump:
============
Magic = 1debc.
PolVer = aaaa0000.
Len = 112.
Primary = CHINESE WALL policy (c=1, off=14).
Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
Chinese Wall policy:
====================
Max Types = a.
Max Ssidrefs = 5.
Max ConfSets = 2.
Ssidrefs Off = 10.
Conflicts Off = 74.
Runing T. Off = 9c.
C. Agg. Off = b0.
SSID To CHWALL-Type matrix:
ssidref 0: 01 00 00 00 00 00 00 00 00 00
ssidref 1: 00 01 00 00 00 00 00 00 00 00
ssidref 2: 00 00 01 00 00 00 00 00 00 00
ssidref 3: 00 00 00 01 00 00 00 00 00 00
ssidref 4: 00 00 00 00 01 00 00 00 00 00
Confict Sets:
c-set 0: 00 00 01 01 00 00 00 00 00 00
c-set 1: 01 00 00 00 00 01 01 00 00 00 <<< t1 is not part of any c-set
Running
Types: 01 01 00 00 00 00 00 00 00 00 <<< xmsec1 has ssidref 1->type1
^^ <<< ref-count at position 1 incr
Conflict
Aggregate Set: 00 00 00 00 00 01 01 00 00 00 <<< domain 1 was allowed to
<<< start since type 1 was not
<<< in conflict with running
<<< types
Simple Type Enforcement policy:
===============================
Max Types = 5.
Max Ssidrefs = 5.
Ssidrefs Off = 8.
SSID To STE-Type matrix:
ssidref 0: 01 01 01 01 01 <<< the ste policy does not maintain; we
ssidref 1: 00 01 00 00 00 <-- <<< see that domain xmsec1 has ste
ssidref 2: 00 00 01 00 00 <<< ssidref1->type1 and has this type in
ssidref 3: 00 00 00 01 00 <<< common with dom0
ssidref 4: 00 00 00 00 01
Policy dump End.
Look at sHype output in xen dmesg:
[root@laptop xen]# xm dmesg
.
.
[somewhere near the very end]
(XEN) chwall_init_domain_ssid: determined chwall_ssidref to 1.
(XEN) ste_init_domain_ssid.
(XEN) ste_init_domain_ssid: determined ste_ssidref to 1.
(XEN) acm_init_domain_ssid: Instantiated individual ssid for domain 0x01.
(XEN) chwall_post_domain_create.
(XEN) ste_pre_eventchannel_interdomain.
(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
(XEN) shype_authorize_domops.
(XEN) ste_pre_eventchannel_interdomain.
(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
(XEN) ste_pre_eventchannel_interdomain.
(XEN) ste_pre_eventchannel_interdomain: (evtchn 0 --> 1) common type #01.
You can see that the chinese wall policy does not complain and that the ste
policy makes three access control decisions for three event-channels setup
between domain 0 and the new domain 1. Each time, the two domains share the
type1 and setting up the eventchannel is permitted.
Starting up a second domain xmsec2:
[root@laptop xen]# xm create -c xmsec2
Using config file "xmsec2".
Started domain xmsec2, console on port 9602
************ REMOTE CONSOLE: CTRL-] TO QUIT ********
Linux version 2.6.11-xenU (root@laptop.home.org) (gcc version 3.4.2 20041017
(Red Hat 3.4.2-6.fc3)) #1 Wed Mar 30 13:14:31 EST 2005
.
.
.
[root@laptop policy]# xm list
Name Id Mem(MB) CPU State Time(s) Console SSID-REF
Domain-0 0 620 0 r---- 71.7 s:00/p:00
xmsec1 1 9 0 -b--- 0.3 9601 s:01/p:01
xmsec2 2 7 0 -b--- 0.3 9602 s:02/p:02 << our domain runs both policies with ssidref 2
[root@laptop policy]# ./policy_tool getpolicy
Policy dump:
============
Magic = 1debc.
PolVer = aaaa0000.
Len = 112.
Primary = CHINESE WALL policy (c=1, off=14).
Secondary = SIMPLE TYPE ENFORCEMENT policy (c=2, off=d8).
Chinese Wall policy:
====================
Max Types = a.
Max Ssidrefs = 5.
Max ConfSets = 2.
Ssidrefs Off = 10.
Conflicts Off = 74.
Runing T. Off = 9c.
C. Agg. Off = b0.
SSID To CHWALL-Type matrix:
ssidref 0: 01 00 00 00 00 00 00 00 00 00
ssidref 1: 00 01 00 00 00 00 00 00 00 00
ssidref 2: 00 00 01 00 00 00 00 00 00 00 <<< our domain has type 2 set
ssidref 3: 00 00 00 01 00 00 00 00 00 00
ssidref 4: 00 00 00 00 01 00 00 00 00 00
Confict Sets:
c-set 0: 00 00 01 01 00 00 00 00 00 00 <<< t2 is in c-set0 with type 3
c-set 1: 01 00 00 00 00 01 01 00 00 00
Running
Types: 01 01 01 00 00 00 00 00 00 00 <<< t2 is running since the
^^ <<< current aggregate conflict
<<< set (see above) does not
<<< include type 2
Conflict
Aggregate Set: 00 00 00 01 00 01 01 00 00 00 <<< type 3 is added to the
<<< conflict aggregate
Simple Type Enforcement policy:
===============================
Max Types = 5.
Max Ssidrefs = 5.
Ssidrefs Off = 8.
SSID To STE-Type matrix:
ssidref 0: 01 01 01 01 01
ssidref 1: 00 01 00 00 00
ssidref 2: 00 00 01 00 00
ssidref 3: 00 00 00 01 00
ssidref 4: 00 00 00 00 01
Policy dump End.
The sHype xen dmesg output looks similar to the one above when starting the
first domain.
Now we start xmsec3 and it has ssidref3. Thus, it tries to run as type3 which
conflicts with running type2 (from xmsec2). As expected, creating this domain
fails for security policy enforcement reasons.
[root@laptop xen]# xm create -c xmsec3
Using config file "xmsec3".
Error: Error creating domain: (22, 'Invalid argument')
[root@laptop xen]#
[root@laptop xen]# xm dmesg
.
.
[somewhere near the very end]
(XEN) chwall_pre_domain_create.
(XEN) chwall_pre_domain_create: CHINESE WALL CONFLICT in type 03.
xmsec3 ssidref3 points to type3, which is in the current conflict aggregate
set. This domain cannot start until domain xmsec2 is destroyed, at which time
the aggregate conflict set is reduced and type3 is excluded from it. Then,
xmsec3 can start. Of course, afterwards, xmsec2 cannot be restarted. Try it.
3. Policy tool
**************
toos/policy/policy_tool.c
a) ./policy_tool getpolicy
prints the currently enforced policy
(see for example section 1.)
b) ./policy_tool setpolicy
sets a predefined and hardcoded security
policy (the one described in section 2.)
c) ./policy_tool dumpstats
prints some status information about the caching
of access control decisions (number of cache hits
and number of policy evaluations for grant_table
and event channels).
d) ./policy_tool loadpolicy <binary_policy_file>
sets the policy defined in the <binary_policy_file>
please use the policy_processor that is posted to this
mailing list to create such a binary policy from an XML
policy description
4. Policy interface:
********************
The Policy interface is working in "network-byte-order" (big endian). The reason for this
is that policy files/management should be portable and independent of the platforms.
Our policy interface enables managers to create a single binary policy file in a trusted
environment and distributed it to multiple systems for enforcement.
====================end-of file=======================================
[-- Attachment #3: shype_4_xeno-unstable.bk_v3.0_xen.diff --]
[-- Type: text/x-patch, Size: 99779 bytes --]
diff -uprN xeno-unstable.bk_orig/xen/acm/acm_chinesewall_hooks.c xeno-unstable.bk-shype/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-shype/xen/acm/acm_chinesewall_hooks.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,503 @@
+/****************************************************************
+ * acm_chinesewall_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * Contributions:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype 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 <asm/atomic.h>
+#include <acm/acm_core.h>
+#include <acm/acm_hooks.h>
+#include <acm/acm_endian.h>
+
+/* local cache structures for chinese wall policy */
+struct chwall_binary_policy 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)
+{
+ struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid);
+ 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) {
+ struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf;
+ int ret = 0;
+
+ chwall_buf->chwall_max_types = htons(chwall_bin_pol.max_types);
+ chwall_buf->chwall_max_ssidrefs = htons(chwall_bin_pol.max_ssidrefs);
+ chwall_buf->policy_code = htons(ACM_CHINESE_WALL_POLICY);
+ chwall_buf->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer));
+ chwall_buf->chwall_max_conflictsets = htons(chwall_bin_pol.max_conflictsets);
+ chwall_buf->chwall_conflict_sets_offset =
+ htons(
+ ntohs(chwall_buf->chwall_ssid_offset) +
+ sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs *
+ chwall_bin_pol.max_types);
+
+ chwall_buf->chwall_running_types_offset =
+ htons(
+ ntohs(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 =
+ htons(
+ ntohs(chwall_buf->chwall_running_types_offset) +
+ sizeof(domaintype_t) * chwall_bin_pol.max_types);
+
+ ret = ntohs(chwall_buf->chwall_conflict_aggregate_offset) +
+ sizeof(domaintype_t) * chwall_bin_pol.max_types;
+
+ /* now copy buffers over */
+ arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_ssid_offset)),
+ chwall_bin_pol.ssidrefs,
+ chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types);
+
+ arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_sets_offset)),
+ chwall_bin_pol.conflict_sets,
+ chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types);
+
+ arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_running_types_offset)),
+ chwall_bin_pol.running_types,
+ chwall_bin_pol.max_types);
+
+ arrcpy16((u16 *)(buf + ntohs(chwall_buf->chwall_conflict_aggregate_offset)),
+ chwall_bin_pol.conflict_aggregate_set,
+ 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(struct acm_chwall_policy_buffer *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets,
+ domaintype_t *running_types, domaintype_t *conflict_aggregate_set)
+{
+ int violation = 0, i, j;
+ struct chwall_ssid *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_in_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)->domain_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 */
+ struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf;
+ void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL;
+
+ /* rewrite the policy due to endianess */
+ chwall_buf->policy_code = ntohs(chwall_buf->policy_code);
+ chwall_buf->chwall_max_types = ntohs(chwall_buf->chwall_max_types);
+ chwall_buf->chwall_max_ssidrefs = ntohs(chwall_buf->chwall_max_ssidrefs);
+ chwall_buf->chwall_max_conflictsets = ntohs(chwall_buf->chwall_max_conflictsets);
+ chwall_buf->chwall_ssid_offset = ntohs(chwall_buf->chwall_ssid_offset);
+ chwall_buf->chwall_conflict_sets_offset = ntohs(chwall_buf->chwall_conflict_sets_offset);
+ chwall_buf->chwall_running_types_offset = ntohs(chwall_buf->chwall_running_types_offset);
+ chwall_buf->chwall_conflict_aggregate_offset = ntohs(chwall_buf->chwall_conflict_aggregate_offset);
+
+ /* 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 */
+ if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) *
+ chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > buf_size)
+ goto error_free;
+ arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset,
+ sizeof(domaintype_t),
+ chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs);
+
+ if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) *
+ chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets > buf_size)
+ goto error_free;
+
+ arrcpy(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;
+}
+
+static int
+chwall_dump_stats(u8 *buf, u16 len)
+{
+ /* no stats for Chinese Wall Policy */
+ return 0;
+}
+
+/***************************
+ * 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 == ACM_DEFAULT_LOCAL_SSID) {
+ printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED; /* catching and indicating config error */
+ }
+ 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, domid_t id)
+{
+ int i,j;
+ struct chwall_ssid *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 = {
+ /* policy management services */
+ .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,
+ .dump_statistics = chwall_dump_stats,
+ /* domain management control hooks */
+ .pre_domain_create = chwall_pre_domain_create,
+ .post_domain_create = chwall_post_domain_create,
+ .fail_domain_create = chwall_fail_domain_create,
+ .post_domain_destroy = chwall_post_domain_destroy,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_setup = NULL,
+ .fail_grant_setup = NULL,
+};
diff -uprN xeno-unstable.bk_orig/xen/acm/acm_core.c xeno-unstable.bk-shype/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-shype/xen/acm/acm_core.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,205 @@
+/****************************************************************
+ * 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>
+#include <acm/acm_endian.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 */
+struct acm_binary_policy acm_bin_pol;
+/* acm binary policy lock */
+rwlock_t acm_bin_pol_rwlock = RW_LOCK_UNLOCKED;
+
+/* until we have endian support in Xen, we discover it at runtime */
+u8 little_endian = 1;
+void acm_set_endian(void)
+{
+ u32 test = 1;
+ if (*((u8 *)&test) == 1) {
+ printk("ACM module running in LITTLE ENDIAN.\n");
+ little_endian = 1;
+ } else {
+ printk("ACM module running in BIG ENDIAN.\n");
+ little_endian = 0;
+ }
+}
+
+/* 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;
+
+ acm_set_endian();
+ 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->domain_id;
+ ssid->primary_ssid = NULL;
+ ssid->secondary_ssid = NULL;
+
+ if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
+ ssid->ssidref = ssidref;
+ else
+ ssid->ssidref = ACM_DEFAULT_SSID;
+
+ 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->domain_id);
+ acm_free_domain_ssid(ssid);
+ put_domain(subj);
+ return ACM_INIT_SSID_ERROR;
+ }
+ printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref);
+ put_domain(subj);
+ return ACM_OK;
+}
+
+
+int
+acm_free_domain_ssid(struct acm_ssid_domain *ssid)
+{
+ domid_t id;
+
+ /* domain is already gone, just ssid is left */
+ 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 -uprN xeno-unstable.bk_orig/xen/acm/acm_null_hooks.c xeno-unstable.bk-shype/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-shype/xen/acm/acm_null_hooks.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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>
+
+static int
+null_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+{
+ return ACM_OK;
+}
+
+
+static void
+null_free_domain_ssid(void *chwall_ssid)
+{
+ return;
+}
+
+
+static int
+null_dump_binary_policy(u8 *buf, u16 buf_size)
+{
+ return 0;
+}
+
+
+
+static int
+null_set_binary_policy(u8 *buf, u16 buf_size)
+{
+ return -1;
+}
+
+
+static int
+null_dump_stats(u8 *buf, u16 buf_size)
+{
+ /* no stats for NULL policy */
+ return 0;
+}
+
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_null_ops = {
+ .init_domain_ssid = null_init_domain_ssid,
+ .free_domain_ssid = null_free_domain_ssid,
+ .dump_binary_policy = null_dump_binary_policy,
+ .set_binary_policy = null_set_binary_policy,
+ .dump_statistics = null_dump_stats,
+ /* domain management control hooks */
+ .pre_domain_create = NULL,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .post_domain_destroy = NULL,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = NULL,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = NULL,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = NULL,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_setup = NULL,
+ .fail_grant_setup = NULL
+
+};
diff -uprN xeno-unstable.bk_orig/xen/acm/acm_policy.c xeno-unstable.bk-shype/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-shype/xen/acm/acm_policy.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,197 @@
+/****************************************************************
+ * acm_policy.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * Contributions:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ * support for network-byte-order binary policies
+ *
+ * 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>
+#include <acm/acm_endian.h>
+
+int
+acm_set_policy(void *buf, u16 buf_size, u16 policy)
+{
+ u8 *policy_buffer = NULL;
+ struct acm_policy_buffer *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(struct acm_policy_buffer))
+ 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)) {
+ printk("%s: Error copying!\n",__func__);
+ goto error_free;
+ }
+ /* 2. some sanity checking */
+ pol = (struct acm_policy_buffer *)policy_buffer;
+
+ if ((ntohl(pol->magic) != ACM_MAGIC) ||
+ (ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) ||
+ (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) {
+ printkd("%s: Wrong policy magics!\n", __func__);
+ goto error_free;
+ }
+ if (buf_size != ntohl(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 + ntohs(pol->primary_buffer_offset),
+ ntohs(pol->secondary_buffer_offset) -
+ ntohs(pol->primary_buffer_offset))) {
+ goto error_lock_free;
+ }
+ /* 4. now get/set secondary policy data */
+ if (acm_secondary_ops->set_binary_policy(buf + ntohs(pol->secondary_buffer_offset),
+ ntohl(pol->len) -
+ ntohs(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;
+ struct acm_policy_buffer *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 = (struct acm_policy_buffer *)policy_buffer;
+ bin_pol->magic = htonl(ACM_MAGIC);
+ bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
+ bin_pol->primary_policy_code = htons(acm_bin_pol.primary_policy_code);
+ bin_pol->secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
+
+ bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
+ bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
+ bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
+
+ ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohs(bin_pol->primary_buffer_offset),
+ buf_size - ntohs(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 = htonl(ntohl(bin_pol->len) + ret);
+ bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
+
+ ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohs(bin_pol->secondary_buffer_offset),
+ buf_size - ntohs(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 = htonl(ntohl(bin_pol->len) + ret);
+ read_unlock(&acm_bin_pol_rwlock);
+ if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
+ return -EFAULT;
+ xfree(policy_buffer);
+ return ACM_OK;
+}
+
+int
+acm_dump_statistics(void *buf, u16 buf_size)
+{
+ /* send stats to user space */
+ u8 *stats_buffer;
+ int len1, len2;
+ struct acm_stats_buffer acm_stats;
+
+ if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ return -ENOMEM;
+
+ read_lock(&acm_bin_pol_rwlock);
+
+ len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer),
+ buf_size - sizeof(struct acm_stats_buffer));
+ if (len1 < 0)
+ goto error_lock_free;
+
+ len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1,
+ buf_size - sizeof(struct acm_stats_buffer) - len1);
+ if (len2 < 0)
+ goto error_lock_free;
+
+ acm_stats.magic = htonl(ACM_MAGIC);
+ acm_stats.policyversion = htonl(POLICY_INTERFACE_VERSION);
+ acm_stats.primary_policy_code = htons(acm_bin_pol.primary_policy_code);
+ acm_stats.secondary_policy_code = htons(acm_bin_pol.secondary_policy_code);
+ acm_stats.primary_stats_offset = htons(sizeof(struct acm_stats_buffer));
+ acm_stats.secondary_stats_offset = htons(sizeof(struct acm_stats_buffer) + len1);
+ acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2);
+ memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer));
+
+ if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2))
+ goto error_lock_free;
+
+ read_unlock(&acm_bin_pol_rwlock);
+ xfree(stats_buffer);
+ return ACM_OK;
+
+ error_lock_free:
+ read_unlock(&acm_bin_pol_rwlock);
+ xfree(stats_buffer);
+ return -EFAULT;
+}
+
+/*eof*/
diff -uprN xeno-unstable.bk_orig/xen/acm/acm_simple_type_enforcement_hooks.c xeno-unstable.bk-shype/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-shype/xen/acm/acm_simple_type_enforcement_hooks.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,638 @@
+/****************************************************************
+ * acm_simple_type_enforcement_hooks.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * Contributors:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ * support for network order binary policies
+ *
+ * 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 <xen/lib.h>
+#include <asm/types.h>
+#include <asm/current.h>
+#include <acm/acm_hooks.h>
+#include <asm/atomic.h>
+#include <acm/acm_endian.h>
+
+/* local cache structures for chinese wall policy */
+struct ste_binary_policy ste_bin_pol;
+
+static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) {
+ int i;
+ for(i=0; i< ste_bin_pol.max_types; i++)
+ if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] &&
+ ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) {
+ printkd("%s: common type #%02x.\n", __func__, i);
+ return 1;
+ }
+ return 0;
+}
+
+/* Helper function: return = (subj and obj share a common type) */
+static int share_common_type(struct domain *subj, struct domain *obj)
+{
+ ssidref_t ref_s, ref_o;
+ int ret;
+
+ if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL))
+ return 0;
+ read_lock(&acm_bin_pol_rwlock);
+ /* lookup the policy-local ssids */
+ ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref;
+ ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref;
+ /* check whether subj and obj share a common ste type */
+ ret = have_common_type(ref_s, ref_o);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ret;
+}
+
+/*
+ * 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;
+
+ /* init stats */
+ atomic_set(&(ste_bin_pol.ec_eval_count), 0);
+ atomic_set(&(ste_bin_pol.ec_denied_count), 0);
+ atomic_set(&(ste_bin_pol.ec_cachehit_count), 0);
+ atomic_set(&(ste_bin_pol.gt_eval_count), 0);
+ atomic_set(&(ste_bin_pol.gt_denied_count), 0);
+ atomic_set(&(ste_bin_pol.gt_cachehit_count), 0);
+ return ACM_OK;
+}
+
+
+/* ste initialization function hooks */
+static int
+ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref)
+{
+ int i;
+ struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid);
+ traceprintk("%s.\n", __func__);
+
+ if (ste_ssidp == NULL)
+ return ACM_INIT_SSID_ERROR;
+
+ /* get policy-local ssid reference */
+ 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;
+ }
+ /* clean ste cache */
+ for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+ ste_ssidp->ste_cache[i].valid = FREE;
+
+ (*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) {
+ struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
+ int ret = 0;
+
+ ste_buf->ste_max_types = htons(ste_bin_pol.max_types);
+ ste_buf->ste_max_ssidrefs = htons(ste_bin_pol.max_ssidrefs);
+ ste_buf->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+ ste_buf->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer));
+ ret = ntohs(ste_buf->ste_ssid_offset) +
+ sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types;
+
+ /* now copy buffer over */
+ arrcpy(buf + ntohs(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(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs)
+{
+ int violation = 1;
+ struct ste_ssid *ste_ssid, *ste_rssid;
+ ssidref_t ste_ssidref, ste_rssidref;
+ struct domain **pd, *rdom;
+ domid_t rdomid;
+ grant_entry_t sha_copy;
+ int port, i;
+
+ read_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_in_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 eventch domain %x (ste-Ref=%x).\n",
+ __func__, (*pd)->domain_id, ste_ssidref);
+ /* a) check for event channel conflicts */
+ for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
+ spin_lock(&(*pd)->evtchn_lock);
+ if ((*pd)->evtchn[port] == NULL) {
+ spin_unlock(&(*pd)->evtchn_lock);
+ continue;
+ }
+ if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) {
+ rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom;
+ rdomid = rdom->domain_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)->evtchn[port]->state == ECS_UNBOUND) {
+ rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid;
+ if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+ printk("%s: Error finding domain to id %x!\n", __func__, rdomid);
+ 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 {
+ spin_unlock(&(*pd)->evtchn_lock);
+ continue; /* port unused */
+ }
+ spin_unlock(&(*pd)->evtchn_lock);
+
+ /* 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: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n",
+ __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port);
+ /* check whether on subj->ssid, obj->ssid share a common type*/
+ if (!have_common_type(ste_ssidref, ste_rssidref)) {
+ printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
+ __func__, (*pd)->domain_id, rdomid);
+ goto out;
+ }
+ }
+ /* b) check for grant table conflicts on shared pages */
+ if ((*pd)->grant_table->shared == NULL) {
+ printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id);
+ continue;
+ }
+ for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) {
+ sha_copy = (*pd)->grant_table->shared[i];
+ if ( sha_copy.flags ) {
+ printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
+ __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid,
+ (unsigned long)sha_copy.frame);
+ rdomid = sha_copy.domid;
+ if ((rdom = find_domain_by_id(rdomid)) == NULL) {
+ printkd("%s: domain not found ERROR!\n", __func__);
+ 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);
+ if (!have_common_type(ste_ssidref, ste_rssidref)) {
+ printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n",
+ __func__, (*pd)->domain_id, rdomid);
+ goto out;
+ }
+ }
+ }
+ }
+ violation = 0;
+ out:
+ read_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)
+{
+ struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf;
+ void *ssidrefsbuf;
+ struct ste_ssid *ste_ssid;
+ struct domain **pd;
+ int i;
+
+ /* Convert endianess of policy */
+ ste_buf->policy_code = ntohs(ste_buf->policy_code);
+ ste_buf->ste_max_types = ntohs(ste_buf->ste_max_types);
+ ste_buf->ste_max_ssidrefs = ntohs(ste_buf->ste_max_ssidrefs);
+ ste_buf->ste_ssid_offset = ntohs(ste_buf->ste_ssid_offset);
+
+ /* 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;
+ }
+ if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size)
+ goto error_free;
+
+ arrcpy(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;
+
+ /* clear all ste caches */
+ read_lock(&domlist_lock);
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(*pd)->ssid);
+ for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+ ste_ssid->ste_cache[i].valid = FREE;
+ }
+ read_unlock(&domlist_lock);
+ return ACM_OK;
+
+error_free:
+ printk("%s: ERROR setting policy.\n", __func__);
+ if (ssidrefsbuf != NULL) xfree(ssidrefsbuf);
+ return -EFAULT;
+}
+
+static int
+ste_dump_stats(u8 *buf, u16 buf_len)
+{
+ struct acm_ste_stats_buffer stats;
+
+#ifdef ACM_DEBUG
+ int i;
+ struct ste_ssid *ste_ssid;
+ struct domain **pd;
+
+ printk("ste: Decision caches:\n");
+ /* go through all domains and adjust policy as if this domain was started now */
+ read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+ printk("ste: Cache Domain %02x.\n", (*pd)->domain_id);
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(*pd)->ssid);
+ for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+ printk("\t\tcache[%02x] = %s, domid=%x.\n", i,
+ (ste_ssid->ste_cache[i].valid == VALID) ?
+ "VALID" : "FREE",
+ (ste_ssid->ste_cache[i].valid == VALID) ?
+ ste_ssid->ste_cache[i].id : 0xffffffff);
+ }
+ read_unlock(&domlist_lock);
+ /* init stats */
+ printk("STE-Policy Security Hook Statistics:\n");
+ printk("ste: event_channel eval_count = %x\n", atomic_read(&(ste_bin_pol.ec_eval_count)));
+ printk("ste: event_channel denied_count = %x\n", atomic_read(&(ste_bin_pol.ec_denied_count)));
+ printk("ste: event_channel cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.ec_cachehit_count)));
+ printk("ste:\n");
+ printk("ste: grant_table eval_count = %x\n", atomic_read(&(ste_bin_pol.gt_eval_count)));
+ printk("ste: grant_table denied_count = %x\n", atomic_read(&(ste_bin_pol.gt_denied_count)));
+ printk("ste: grant_table cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.gt_cachehit_count)));
+#endif
+
+ if (buf_len < sizeof(struct acm_ste_stats_buffer))
+ return -ENOMEM;
+
+ /* now send the hook counts to user space */
+ stats.ec_eval_count = htonl(atomic_read(&ste_bin_pol.ec_eval_count));
+ stats.gt_eval_count = htonl(atomic_read(&ste_bin_pol.gt_eval_count));
+ stats.ec_denied_count = htonl(atomic_read(&ste_bin_pol.ec_denied_count));
+ stats.gt_denied_count = htonl(atomic_read(&ste_bin_pol.gt_denied_count));
+ stats.ec_cachehit_count = htonl(atomic_read(&ste_bin_pol.ec_cachehit_count));
+ stats.gt_cachehit_count = htonl(atomic_read(&ste_bin_pol.gt_cachehit_count));
+ memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));
+ return sizeof(struct acm_ste_stats_buffer);
+}
+
+
+/* we need to go through this before calling the hooks,
+ * returns 1 == cache hit */
+static int inline
+check_cache(struct domain *dom, domid_t rdom) {
+ struct ste_ssid *ste_ssid;
+ int i;
+
+ printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(dom)->ssid);
+
+ for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
+ if ((ste_ssid->ste_cache[i].valid == VALID) &&
+ (ste_ssid->ste_cache[i].id == rdom)) {
+ printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* we only get here if there is NO entry yet; no duplication check! */
+static void inline
+cache_result(struct domain *subj, struct domain *obj) {
+ struct ste_ssid *ste_ssid;
+ int i;
+ printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id);
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(subj)->ssid);
+ for(i=0; i< ACM_TE_CACHE_SIZE; i++)
+ if (ste_ssid->ste_cache[i].valid == FREE)
+ break;
+ if (i< ACM_TE_CACHE_SIZE) {
+ ste_ssid->ste_cache[i].valid = VALID;
+ ste_ssid->ste_cache[i].id = obj->domain_id;
+ } else
+ printk ("Cache of dom %x is full!\n", subj->domain_id);
+}
+
+/* deletes entries for domain 'id' from all caches (re-use) */
+static void inline
+clean_id_from_cache(domid_t id)
+{
+ struct ste_ssid *ste_ssid;
+ int i;
+ struct domain **pd;
+
+ printkd("deleting cache for dom %x.\n", id);
+
+ read_lock(&domlist_lock); /* look through caches of all domains */
+ pd = &domain_list;
+ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
+ ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+ (struct acm_ssid_domain *)(*pd)->ssid);
+ for (i=0; i<ACM_TE_CACHE_SIZE; i++)
+ if ((ste_ssid->ste_cache[i].valid == VALID) &&
+ (ste_ssid->ste_cache[i].id = id))
+ ste_ssid->ste_cache[i].valid = FREE;
+ }
+ read_unlock(&domlist_lock);
+}
+
+/***************************
+ * 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 == ACM_DEFAULT_LOCAL_SSID) {
+ printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__);
+ read_unlock(&acm_bin_pol_rwlock);
+ return ACM_ACCESS_DENIED; /* catching and indicating config error */
+ }
+ 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;
+}
+
+static void
+ste_post_domain_destroy(void *subject_ssid, domid_t id)
+{
+ /* clean all cache entries for destroyed domain (might be re-used) */
+ clean_id_from_cache(id);
+}
+
+/* -------- EVENTCHANNEL OPERATIONS -----------*/
+static int
+ste_pre_eventchannel_unbound(domid_t id) {
+ struct domain *subj, *obj;
+ int ret;
+ traceprintk("%s: dom%x-->dom%x.\n",
+ __func__, current->domain->domain_id, id);
+
+ if (check_cache(current->domain, id)) {
+ atomic_inc(&ste_bin_pol.ec_cachehit_count);
+ return ACM_ACCESS_PERMITTED;
+ }
+ atomic_inc(&ste_bin_pol.ec_eval_count);
+ subj = current->domain;
+ obj = find_domain_by_id(id);
+
+ if (share_common_type(subj, obj)) {
+ cache_result(subj, obj);
+ ret = ACM_ACCESS_PERMITTED;
+ } else {
+ atomic_inc(&ste_bin_pol.ec_denied_count);
+ ret = ACM_ACCESS_DENIED;
+ }
+ if (obj != NULL)
+ put_domain(obj);
+ return ret;
+}
+
+static int
+ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
+{
+ struct domain *subj, *obj;
+ int ret;
+ traceprintk("%s: dom%x-->dom%x.\n", __func__,
+ (id1 == DOMID_SELF) ? current->domain->domain_id : id1,
+ (id2 == DOMID_SELF) ? current->domain->domain_id : id2);
+
+ /* following is a bit longer but ensures that we
+ * "put" only domains that we where "find"-ing
+ */
+ if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
+ if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
+
+ subj = find_domain_by_id(id1);
+ obj = find_domain_by_id(id2);
+ if ((subj == NULL) || (obj == NULL)) {
+ ret = ACM_ACCESS_DENIED;
+ goto out;
+ }
+ /* cache check late, but evtchn is not on performance critical path */
+ if (check_cache(subj, obj->domain_id)) {
+ atomic_inc(&ste_bin_pol.ec_cachehit_count);
+ ret = ACM_ACCESS_PERMITTED;
+ goto out;
+ }
+ atomic_inc(&ste_bin_pol.ec_eval_count);
+
+ if (share_common_type(subj, obj)) {
+ cache_result(subj, obj);
+ ret = ACM_ACCESS_PERMITTED;
+ } else {
+ atomic_inc(&ste_bin_pol.ec_denied_count);
+ ret = ACM_ACCESS_DENIED;
+ }
+ out:
+ if (obj != NULL)
+ put_domain(obj);
+ if (subj != NULL)
+ put_domain(subj);
+ return ret;
+}
+
+/* -------- SHARED MEMORY OPERATIONS -----------*/
+
+static int
+ste_pre_grant_map_ref (domid_t id) {
+ struct domain *obj, *subj;
+ int ret;
+ traceprintk("%s: dom%x-->dom%x.\n", __func__,
+ current->domain->domain_id, id);
+
+ if (check_cache(current->domain, id)) {
+ atomic_inc(&ste_bin_pol.gt_cachehit_count);
+ return ACM_ACCESS_PERMITTED;
+ }
+ atomic_inc(&ste_bin_pol.gt_eval_count);
+ subj = current->domain;
+ obj = find_domain_by_id(id);
+
+ if (share_common_type(subj, obj)) {
+ cache_result(subj, obj);
+ ret = ACM_ACCESS_PERMITTED;
+ } else {
+ atomic_inc(&ste_bin_pol.gt_denied_count);
+ printkd("%s: ACCESS DENIED!\n", __func__);
+ ret = ACM_ACCESS_DENIED;
+ }
+ if (obj != NULL)
+ put_domain(obj);
+ return ret;
+}
+
+/* since setting up grant tables involves some implicit information
+ flow from the creating domain to the domain that is setup, we
+ check types in addition to the general authorization */
+static int
+ste_pre_grant_setup (domid_t id) {
+ struct domain *obj, *subj;
+ int ret;
+ traceprintk("%s: dom%x-->dom%x.\n", __func__,
+ current->domain->domain_id, id);
+
+ if (check_cache(current->domain, id)) {
+ atomic_inc(&ste_bin_pol.gt_cachehit_count);
+ return ACM_ACCESS_PERMITTED;
+ }
+ atomic_inc(&ste_bin_pol.gt_eval_count);
+ /* a) check authorization (eventually use specific capabilities) */
+ if (!IS_PRIV(current->domain)) {
+ printk("%s: Grant table management authorization denied ERROR!\n", __func__);
+ return ACM_ACCESS_DENIED;
+ }
+ /* b) check types */
+ subj = current->domain;
+ obj = find_domain_by_id(id);
+
+ if (share_common_type(subj, obj)) {
+ cache_result(subj, obj);
+ ret = ACM_ACCESS_PERMITTED;
+ } else {
+ atomic_inc(&ste_bin_pol.gt_denied_count);
+ ret = ACM_ACCESS_DENIED;
+ }
+ if (obj != NULL)
+ put_domain(obj);
+ return ret;
+}
+
+/* now define the hook structure similarly to LSM */
+struct acm_operations acm_simple_type_enforcement_ops = {
+ /* policy management services */
+ .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,
+ .dump_statistics = ste_dump_stats,
+ /* domain management control hooks */
+ .pre_domain_create = ste_pre_domain_create,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .post_domain_destroy = ste_post_domain_destroy,
+ /* event channel control hooks */
+ .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
+ .fail_eventchannel_unbound = NULL,
+ .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
+ .fail_eventchannel_interdomain = NULL,
+ /* grant table control hooks */
+ .pre_grant_map_ref = ste_pre_grant_map_ref,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_setup = ste_pre_grant_setup,
+ .fail_grant_setup = NULL,
+};
diff -uprN xeno-unstable.bk_orig/xen/acm/Makefile xeno-unstable.bk-shype/xen/acm/Makefile
--- xeno-unstable.bk_orig/xen/acm/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk-shype/xen/acm/Makefile 2005-06-20 11:53:17.000000000 -0400
@@ -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 -uprN xeno-unstable.bk_orig/xen/arch/x86/setup.c xeno-unstable.bk-shype/xen/arch/x86/setup.c
--- xeno-unstable.bk_orig/xen/arch/x86/setup.c 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/xen/arch/x86/setup.c 2005-06-20 11:53:17.000000000 -0400
@@ -20,6 +20,7 @@
#include <asm/desc.h>
#include <asm/shadow.h>
#include <asm/e820.h>
+#include <public/acm_dom0_setup.h>
extern void dmi_scan_machine(void);
extern void generic_apic_probe(void);
@@ -393,12 +394,17 @@ void __init __start_xen(multiboot_info_t
shadow_mode_init();
+ /* initialize access control security module */
+ acm_init();
+
/* Create initial domain 0. */
dom0 = do_createdomain(0, 0);
if ( dom0 == NULL )
panic("Error creating domain 0\n");
set_bit(_DOMF_privileged, &dom0->domain_flags);
+ /* post-create hooks sets security label */
+ acm_post_domain0_create(dom0->domain_id);
/* Grab the DOM0 command line. */
cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
diff -uprN xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S xeno-unstable.bk-shype/xen/arch/x86/x86_32/entry.S
--- xeno-unstable.bk_orig/xen/arch/x86/x86_32/entry.S 2005-06-10 18:04:25.000000000 -0400
+++ xeno-unstable.bk-shype/xen/arch/x86/x86_32/entry.S 2005-06-20 11:53:17.000000000 -0400
@@ -751,6 +751,7 @@ ENTRY(hypercall_table)
.long do_boot_vcpu
.long do_ni_hypercall /* 25 */
.long do_mmuext_op
+ .long do_policy_op /* 27 */
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
diff -uprN xeno-unstable.bk_orig/xen/common/dom0_ops.c xeno-unstable.bk-shype/xen/common/dom0_ops.c
--- xeno-unstable.bk_orig/xen/common/dom0_ops.c 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/xen/common/dom0_ops.c 2005-06-20 11:53:17.000000000 -0400
@@ -19,6 +19,7 @@
#include <asm/current.h>
#include <public/dom0_ops.h>
#include <public/sched_ctl.h>
+#include <acm/acm_hooks.h>
extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
extern void arch_getdomaininfo_ctxt(
@@ -91,6 +92,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
{
long ret = 0;
dom0_op_t curop, *op = &curop;
+ void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
if ( !IS_PRIV(current->domain) )
return -EPERM;
@@ -101,6 +103,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
if ( op->interface_version != DOM0_INTERFACE_VERSION )
return -EACCES;
+ if ( acm_pre_dom0_op(op, &ssid) )
+ return -EACCES;
+
switch ( op->cmd )
{
@@ -357,6 +362,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) |
d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT;
+ if (d->ssid != NULL)
+ op->u.getdomaininfo.ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref;
+ else
+ op->u.getdomaininfo.ssidref = ACM_DEFAULT_SSID;
+
op->u.getdomaininfo.tot_pages = d->tot_pages;
op->u.getdomaininfo.max_pages = d->max_pages;
op->u.getdomaininfo.shared_info_frame =
@@ -493,7 +503,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
ret = arch_do_dom0_op(op,u_dom0_op);
}
-
+ if (!ret)
+ acm_post_dom0_op(op, ssid);
+ else
+ acm_fail_dom0_op(op, ssid);
return ret;
}
diff -uprN xeno-unstable.bk_orig/xen/common/event_channel.c xeno-unstable.bk-shype/xen/common/event_channel.c
--- xeno-unstable.bk_orig/xen/common/event_channel.c 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/xen/common/event_channel.c 2005-06-20 11:53:17.000000000 -0400
@@ -26,6 +26,7 @@
#include <public/xen.h>
#include <public/event_channel.h>
+#include <acm/acm_hooks.h>
#define bucket_from_port(d,p) \
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
@@ -587,6 +588,9 @@ long do_event_channel_op(evtchn_op_t *uo
if ( copy_from_user(&op, uop, sizeof(op)) != 0 )
return -EFAULT;
+ if (acm_pre_event_channel(&op))
+ return -EACCES;
+
switch ( op.cmd )
{
case EVTCHNOP_alloc_unbound:
diff -uprN xeno-unstable.bk_orig/xen/common/grant_table.c xeno-unstable.bk-shype/xen/common/grant_table.c
--- xeno-unstable.bk_orig/xen/common/grant_table.c 2005-06-10 07:00:13.000000000 -0400
+++ xeno-unstable.bk-shype/xen/common/grant_table.c 2005-06-20 11:53:17.000000000 -0400
@@ -30,6 +30,7 @@
#include <xen/sched.h>
#include <xen/shadow.h>
#include <xen/mm.h>
+#include <acm/acm_hooks.h>
#define PIN_FAIL(_lbl, _rc, _f, _a...) \
do { \
@@ -357,6 +358,11 @@ __gnttab_map_grant_ref(
return GNTST_bad_gntref;
}
+ if (acm_pre_grant_map_ref(dom)) {
+ (void)__put_user(GNTST_permission_denied, &uop->handle);
+ return GNTST_permission_denied;
+ }
+
if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
unlikely(ld == rd) )
{
diff -uprN xeno-unstable.bk_orig/xen/common/policy_ops.c xeno-unstable.bk-shype/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-shype/xen/common/policy_ops.c 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,117 @@
+/******************************************************************************
+ *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 <xen/trace.h>
+#include <xen/console.h>
+#include <asm/shadow.h>
+#include <public/sched_ctl.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);
+int acm_dump_statistics(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) */
+ DUMPSTATS /* dump policy statistics */
+} policyoperation_t;
+
+int
+acm_authorize_policyops(struct domain *d, policyoperation_t pops)
+{
+ /* currently, all policy management functions are restricted to privileged domains,
+ * soon we will introduce finer-grained privileges for policy operations
+ */
+ if (!IS_PRIV(d)) {
+ printk("%s: Policy 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 (acm_authorize_policyops(current->domain, 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 (acm_authorize_policyops(current->domain, 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 (acm_authorize_policyops(current->domain, GETPOLICY))
+ return -EACCES;
+ printkd("%s: getting policy.\n", __func__);
+ ret = acm_get_policy(op->u.getpolicy.pullcache, op->u.getpolicy.pullcache_size);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ case POLICY_DUMPSTATS:
+ {
+ if (acm_authorize_policyops(current->domain, DUMPSTATS))
+ return -EACCES;
+ printkd("%s: dumping statistics.\n", __func__);
+ ret = acm_dump_statistics(op->u.dumpstats.pullcache, op->u.dumpstats.pullcache_size);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
+ default:
+ ret = -ESRCH;
+
+ }
+ return ret;
+}
diff -uprN xeno-unstable.bk_orig/xen/include/acm/acm_core.h xeno-unstable.bk-shype/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-shype/xen/include/acm/acm_core.h 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,117 @@
+/****************************************************************
+ * 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 */
+struct acm_binary_policy {
+ u16 primary_policy_code;
+ u16 secondary_policy_code;
+ void *primary_binary_policy;
+ void *secondary_binary_policy;
+
+};
+
+struct chwall_binary_policy {
+ 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]*/
+};
+
+struct ste_binary_policy {
+ u16 max_types;
+ u16 max_ssidrefs;
+ domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */
+ atomic_t ec_eval_count, gt_eval_count;
+ atomic_t ec_denied_count, gt_denied_count;
+ atomic_t ec_cachehit_count, gt_cachehit_count;
+};
+
+/* global acm policy */
+extern struct acm_binary_policy acm_bin_pol;
+extern struct chwall_binary_policy chwall_bin_pol;
+extern struct ste_binary_policy 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 };
+
+/* defines number of access decisions to other domains can be cached
+ * one entry per domain, TE does not distinguish evtchn or grant_table */
+#define ACM_TE_CACHE_SIZE 8
+enum acm_ste_flag { VALID, FREE };
+
+/* cache line:
+ * if cache_line.valid==VALID, then
+ * STE decision is cached as "permitted"
+ * on domain cache_line.id
+ */
+struct acm_ste_cache_line {
+ enum acm_ste_flag valid;
+ domid_t id;
+};
+
+/* 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 */
+struct chwall_ssid {
+ ssidref_t chwall_ssidref;
+};
+
+/* simple type enforcement ssid type */
+struct ste_ssid {
+ ssidref_t ste_ssidref;
+ struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */
+};
+
+/* 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 -uprN xeno-unstable.bk_orig/xen/include/acm/acm_endian.h xeno-unstable.bk-shype/xen/include/acm/acm_endian.h
--- xeno-unstable.bk_orig/xen/include/acm/acm_endian.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk-shype/xen/include/acm/acm_endian.h 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,88 @@
+/****************************************************************
+ * acm_endian.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
+ * Contributions:
+ * 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 defining endian-dependent functions for the
+ * big-endian policy interface
+ *
+ */
+#ifndef _ACM_ENDIAN_H
+#define _ACM_ENDIAN_H
+
+/* don't use these functions in performance critical sections! */
+
+/* set during initialization by testing */
+extern u8 little_endian;
+
+static inline u32 ntohl(u32 x)
+{
+ if (little_endian)
+ return
+ ( (((x) >> 24) & 0xff )|
+ (((x) >> 8) & 0xff00 )|
+ (((x) << 8) & 0xff0000 )|
+ (((x) << 24) & 0xff000000) );
+ else
+ return x;
+}
+
+static inline u16 ntohs(u16 x)
+{
+ if (little_endian)
+ return
+ ( (((x) >> 8) & 0xff )|
+ (((x) << 8) & 0xff00 ) );
+ else
+ return x;
+}
+
+#define htonl(x) ntohl(x)
+#define htons(x) ntohs(x)
+
+static inline void arrcpy16(u16 *dest, const u16 *src, size_t n)
+{
+ unsigned int i = 0;
+ while (i < n) {
+ dest[i] = htons(src[i]);
+ i++;
+ }
+}
+
+static inline void arrcpy32(u32 *dest, const u32 *src, size_t n)
+{
+ unsigned int i = 0;
+ while (i < n) {
+ dest[i] = htonl(src[i]);
+ i++;
+ }
+}
+
+static inline void arrcpy(void *dest, const void *src, unsigned int elsize, size_t n)
+{
+ switch (elsize) {
+ case sizeof(u16):
+ arrcpy16((u16 *)dest, (u16 *)src, n);
+ break;
+
+ case sizeof(u32):
+ arrcpy32((u32 *)dest, (u32 *)src, n);
+ break;
+
+ default:
+ memcpy(dest, src, elsize*n);
+ }
+}
+
+#endif
diff -uprN xeno-unstable.bk_orig/xen/include/acm/acm_hooks.h xeno-unstable.bk-shype/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-shype/xen/include/acm/acm_hooks.h 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,337 @@
+/****************************************************************
+ * 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.
+ *
+ * acm 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>
+#include <public/dom0_ops.h>
+#include <public/event_channel.h>
+#include <asm/current.h>
+
+/* if ACM_TRACE_MODE defined, all hooks should
+ * print a short trace message */
+/* #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;
+
+/**********************************************************************************************
+ * 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 (must always be defined!) */
+ 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);
+ int (*dump_statistics) (u8 *buffer, u16 buf_size);
+ /* domain management control hooks (can be NULL) */
+ 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);
+ void (*post_domain_destroy) (void *object_ssid, domid_t id);
+ /* event channel control hooks (can be NULL) */
+ int (*pre_eventchannel_unbound) (domid_t id);
+ void (*fail_eventchannel_unbound) (domid_t id);
+ int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ int (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
+ /* grant table control hooks (can be NULL) */
+ int (*pre_grant_map_ref) (domid_t id);
+ void (*fail_grant_map_ref) (domid_t id);
+ int (*pre_grant_setup) (domid_t id);
+ void (*fail_grant_setup) (domid_t id);
+};
+
+static inline int acm_pre_domain_create (void *subject_ssid, ssidref_t ssidref)
+{
+ 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 acm_post_domain_create (domid_t domid, ssidref_t ssidref)
+{
+ 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);
+}
+
+static inline void acm_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);
+}
+
+static inline void acm_post_domain_destroy (void *object_ssid, domid_t id)
+{
+ if (acm_primary_ops->post_domain_destroy != NULL)
+ acm_primary_ops->post_domain_destroy (object_ssid, id);
+ if (acm_secondary_ops->post_domain_destroy != NULL)
+ acm_secondary_ops->post_domain_destroy (object_ssid, id);
+ return;
+}
+
+/* event channel ops */
+
+static inline int acm_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 int acm_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;
+}
+
+/************ Xen inline hooks ***************/
+
+/* small macro to make the hooks more readable
+ * (eliminates hooks if NULL policy is active)
+ */
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
+{ return 0; }
+#else
+static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
+{
+ int ret = -EACCES;
+ struct domain *d;
+
+ switch(op->cmd) {
+ case DOM0_CREATEDOMAIN:
+ ret = acm_pre_domain_create(current->domain->ssid, op->u.createdomain.ssidref);
+ break;
+ case DOM0_DESTROYDOMAIN:
+ d = find_domain_by_id(op->u.destroydomain.domain);
+ if (d != NULL) {
+ *ssid = d->ssid; /* save for post destroy when d is gone */
+ /* no policy-specific hook */
+ put_domain(d);
+ ret = 0;
+ }
+ break;
+ default:
+ ret = 0; /* ok */
+ }
+ return ret;
+}
+#endif
+
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
+{ return; }
+#else
+static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
+{
+ switch(op->cmd) {
+ case DOM0_CREATEDOMAIN:
+ /* initialialize shared sHype security labels for new domain */
+ acm_init_domain_ssid(op->u.createdomain.domain, op->u.createdomain.ssidref);
+ acm_post_domain_create(op->u.createdomain.domain, op->u.createdomain.ssidref);
+ break;
+ case DOM0_DESTROYDOMAIN:
+ acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
+ /* free security ssid for the destroyed domain (also if running null policy */
+ acm_free_domain_ssid((struct acm_ssid_domain *)ssid);
+ break;
+ }
+}
+#endif
+
+
+#if (ACM_USE_SECURITY_POLICy == ACM_NULL_POLICY)
+static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
+{ return; }
+#else
+static inline void acm_fail_dom0_op(dom0_op_t *op, void *ssid)
+{
+ switch(op->cmd) {
+ case DOM0_CREATEDOMAIN:
+ acm_fail_domain_create(current->domain->ssid, op->u.createdomain.ssidref);
+ break;
+ }
+}
+#endif
+
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+static inline int acm_pre_event_channel(evtchn_op_t *op)
+{ return 0; }
+#else
+static inline int acm_pre_event_channel(evtchn_op_t *op)
+{
+ int ret = -EACCES;
+
+ switch(op->cmd) {
+ case EVTCHNOP_alloc_unbound:
+ ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom);
+ break;
+ case EVTCHNOP_bind_interdomain:
+ ret = acm_pre_eventchannel_interdomain(op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2);
+ break;
+ default:
+ ret = 0; /* ok */
+ }
+ return ret;
+}
+#endif
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+static inline int acm_pre_grant_map_ref(domid_t id)
+{ return 0; }
+#else
+static inline int acm_pre_grant_map_ref (domid_t id)
+{
+ 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;
+}
+#endif
+
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+static inline int acm_pre_grant_setup(domid_t id)
+{ return 0; }
+#else
+static inline int acm_pre_grant_setup (domid_t id)
+{
+ 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;
+}
+#endif
+
+
+#endif
diff -uprN xeno-unstable.bk_orig/xen/include/public/acm_dom0_setup.h xeno-unstable.bk-shype/xen/include/public/acm_dom0_setup.h
--- xeno-unstable.bk_orig/xen/include/public/acm_dom0_setup.h 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk-shype/xen/include/public/acm_dom0_setup.h 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,34 @@
+/****************************************************************
+ * acm_dom0_setup.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * Includes necessary definitions to bring-up dom0
+ */
+#include <acm/acm_hooks.h>
+
+extern int acm_init(void);
+
+#if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY)
+
+static inline void acm_post_domain0_create(domid_t domid)
+{
+ return;
+}
+
+#else
+
+/* predefined ssidref for DOM0 used by xen when creating DOM0 */
+#define ACM_DOM0_SSIDREF 0
+
+static inline void acm_post_domain0_create(domid_t domid)
+{
+ /* initialialize shared sHype security labels for new domain */
+ acm_init_domain_ssid(domid, ACM_DOM0_SSIDREF);
+ acm_post_domain_create(domid, ACM_DOM0_SSIDREF);
+}
+
+#endif
diff -uprN xeno-unstable.bk_orig/xen/include/public/acm.h xeno-unstable.bk-shype/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-shype/xen/include/public/acm.h 2005-06-20 11:53:50.000000000 -0400
@@ -0,0 +1,161 @@
+/****************************************************************
+ * acm.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Author:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ *
+ * Contributors:
+ * Stefan Berger <stefanb@watson.ibm.com>
+ * added network byte order support for binary policies
+ *
+ * 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_SHYPE_H
+#define _XEN_PUBLIC_SHYPE_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
+
+/* default ssid reference value if not supplied */
+#define ACM_DEFAULT_SSID 0xffffffff
+#define ACM_DEFAULT_LOCAL_SSID 0xffff
+
+/* 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: */
+#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;
+
+/* -------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
+ */
+struct acm_policy_buffer {
+ u32 magic;
+ u32 policyversion;
+ u32 len;
+ u16 primary_policy_code;
+ u16 primary_buffer_offset;
+ u16 secondary_policy_code;
+ u16 secondary_buffer_offset;
+};
+
+struct acm_chwall_policy_buffer {
+ 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;
+};
+
+struct acm_ste_policy_buffer {
+ u16 policy_code;
+ u16 ste_max_types;
+ u16 ste_max_ssidrefs;
+ u16 ste_ssid_offset;
+};
+
+struct acm_stats_buffer {
+ u32 magic;
+ u32 policyversion;
+ u32 len;
+ u16 primary_policy_code;
+ u16 primary_stats_offset;
+ u16 secondary_policy_code;
+ u16 secondary_stats_offset;
+};
+
+struct acm_ste_stats_buffer {
+ u32 ec_eval_count;
+ u32 gt_eval_count;
+ u32 ec_denied_count;
+ u32 gt_denied_count;
+ u32 ec_cachehit_count;
+ u32 gt_cachehit_count;
+};
+
+
+#endif
diff -uprN xeno-unstable.bk_orig/xen/include/public/dom0_ops.h xeno-unstable.bk-shype/xen/include/public/dom0_ops.h
--- xeno-unstable.bk_orig/xen/include/public/dom0_ops.h 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/xen/include/public/dom0_ops.h 2005-06-20 11:53:17.000000000 -0400
@@ -43,6 +43,8 @@ typedef struct sched_adjdom_cmd dom0_adj
#define DOM0_CREATEDOMAIN 8
typedef struct {
+ /* IN parameters */
+ u32 ssidref;
/* IN/OUT parameters. */
/* Identifier for new domain (auto-allocate if zero is specified). */
domid_t domain;
@@ -88,6 +90,7 @@ typedef struct {
u32 n_vcpu;
s32 vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */
cpumap_t cpumap[MAX_VIRT_CPUS]; /* allowable mapping */
+ u32 ssidref;
} dom0_getdomaininfo_t;
#define DOM0_SETDOMAININFO 13
diff -uprN xeno-unstable.bk_orig/xen/include/public/policy_ops.h xeno-unstable.bk-shype/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-shype/xen/include/public/policy_ops.h 2005-06-20 11:53:17.000000000 -0400
@@ -0,0 +1,74 @@
+/******************************************************************************
+ * 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 0xAAAA0001
+
+/************************************************************************/
+
+#define POLICY_SETPOLICY 4
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pushcache;
+ u16 pushcache_size;
+} PACKED policy_setpolicy_t;
+
+
+#define POLICY_GETPOLICY 5
+typedef struct {
+ /* IN variables. */
+ u16 policy_type;
+ u16 padding1;
+ /* OUT variables */
+ void *pullcache;
+ u16 pullcache_size;
+} PACKED policy_getpolicy_t;
+
+#define POLICY_DUMPSTATS 6
+typedef struct {
+ void *pullcache;
+ u16 pullcache_size;
+} PACKED policy_dumpstats_t;
+
+
+typedef struct {
+ u32 cmd; /* 0 */
+ u32 interface_version; /* 4 */ /* POLICY_INTERFACE_VERSION */
+ union { /* 8 */
+ u32 dummy[14]; /* 72bytes */
+ policy_setpolicy_t setpolicy;
+ policy_getpolicy_t getpolicy;
+ policy_dumpstats_t dumpstats;
+ } PACKED u;
+} PACKED policy_op_t; /* 80 bytes */
+
+#endif /* __XEN_PUBLIC_POLICY_OPS_H__ */
diff -uprN xeno-unstable.bk_orig/xen/include/public/xen.h xeno-unstable.bk-shype/xen/include/public/xen.h
--- xeno-unstable.bk_orig/xen/include/public/xen.h 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/xen/include/public/xen.h 2005-06-20 11:53:17.000000000 -0400
@@ -58,6 +58,7 @@
#define __HYPERVISOR_boot_vcpu 24
#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */
#define __HYPERVISOR_mmuext_op 26
+#define __HYPERVISOR_policy_op 27
/*
* VIRTUAL INTERRUPTS
diff -uprN xeno-unstable.bk_orig/xen/include/xen/sched.h xeno-unstable.bk-shype/xen/include/xen/sched.h
--- xeno-unstable.bk_orig/xen/include/xen/sched.h 2005-06-08 07:42:38.000000000 -0400
+++ xeno-unstable.bk-shype/xen/include/xen/sched.h 2005-06-20 11:53:17.000000000 -0400
@@ -137,6 +137,8 @@ struct domain
cpumask_t cpumask;
struct arch_domain arch;
+
+ void *ssid; /* sHype security subject identifier */
};
struct domain_setup_info
diff -uprN xeno-unstable.bk_orig/xen/Makefile xeno-unstable.bk-shype/xen/Makefile
--- xeno-unstable.bk_orig/xen/Makefile 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/xen/Makefile 2005-06-20 11:53:17.000000000 -0400
@@ -46,6 +46,7 @@ clean: delete-unfresh-files
$(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
@@ -58,6 +59,7 @@ $(TARGET): delete-unfresh-files
$(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.
@@ -109,7 +111,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h
.PHONY: default debug install dist clean delete-unfresh-files TAGS tags
-SUBDIRS = arch/$(TARGET_ARCH) common drivers
+SUBDIRS = acm arch/$(TARGET_ARCH) common drivers
define all_sources
( find include/asm-$(TARGET_ARCH) -name SCCS -prune -o -name '*.h' -print; \
find include -type d -name SCCS -prune -o \( -name "asm-*" -o \
diff -uprN xeno-unstable.bk_orig/xen/Rules.mk xeno-unstable.bk-shype/xen/Rules.mk
--- xeno-unstable.bk_orig/xen/Rules.mk 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/xen/Rules.mk 2005-06-20 11:53:17.000000000 -0400
@@ -35,6 +35,7 @@ OBJS += $(patsubst %.c,%.o,$(C_SRCS))
ALL_OBJS := $(BASEDIR)/common/common.o
ALL_OBJS += $(BASEDIR)/drivers/char/driver.o
ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o
+ALL_OBJS += $(BASEDIR)/acm/acm.o
ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o
[-- Attachment #4: shype_4_xeno-unstable.bk_v3.0_tools.diff --]
[-- Type: text/x-patch, Size: 34427 bytes --]
diff -uprN xeno-unstable.bk_orig/tools/libxc/xc_domain.c xeno-unstable.bk-shype/tools/libxc/xc_domain.c
--- xeno-unstable.bk_orig/tools/libxc/xc_domain.c 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/tools/libxc/xc_domain.c 2005-06-20 11:53:11.000000000 -0400
@@ -9,6 +9,7 @@
#include "xc_private.h"
int xc_domain_create(int xc_handle,
+ u32 ssidref,
u32 *pdomid)
{
int err;
@@ -16,6 +17,7 @@ int xc_domain_create(int xc_handle,
op.cmd = DOM0_CREATEDOMAIN;
op.u.createdomain.domain = (domid_t)*pdomid;
+ op.u.createdomain.ssidref = ssidref;
if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
return err;
@@ -101,6 +103,7 @@ int xc_domain_getinfo(int xc_handle,
info->crashed = 1;
}
+ info->ssidref = op.u.getdomaininfo.ssidref;
info->nr_pages = op.u.getdomaininfo.tot_pages;
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
diff -uprN xeno-unstable.bk_orig/tools/libxc/xc.h xeno-unstable.bk-shype/tools/libxc/xc.h
--- xeno-unstable.bk_orig/tools/libxc/xc.h 2005-06-10 07:00:13.000000000 -0400
+++ xeno-unstable.bk-shype/tools/libxc/xc.h 2005-06-20 11:53:11.000000000 -0400
@@ -110,6 +110,7 @@ int xc_waitdomain_core(int domain,
typedef struct {
u32 domid;
+ u32 ssidref;
unsigned int dying:1, crashed:1, shutdown:1,
paused:1, blocked:1, running:1;
unsigned int shutdown_reason; /* only meaningful if shutdown==1 */
@@ -124,6 +125,7 @@ typedef struct {
typedef dom0_getdomaininfo_t xc_domaininfo_t;
int xc_domain_create(int xc_handle,
+ u32 ssidref,
u32 *pdomid);
diff -uprN xeno-unstable.bk_orig/tools/Makefile xeno-unstable.bk-shype/tools/Makefile
--- xeno-unstable.bk_orig/tools/Makefile 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/tools/Makefile 2005-06-20 11:53:11.000000000 -0400
@@ -12,6 +12,7 @@ SUBDIRS += xcs
SUBDIRS += xcutils
SUBDIRS += pygrub
SUBDIRS += firmware
+SUBDIRS += policy
.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
diff -uprN xeno-unstable.bk_orig/tools/policy/Makefile xeno-unstable.bk-shype/tools/policy/Makefile
--- xeno-unstable.bk_orig/tools/policy/Makefile 1969-12-31 19:00:00.000000000 -0500
+++ xeno-unstable.bk-shype/tools/policy/Makefile 2005-06-20 11:53:11.000000000 -0400
@@ -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 -uprN xeno-unstable.bk_orig/tools/policy/policy_tool.c xeno-unstable.bk-shype/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-shype/tools/policy/policy_tool.c 2005-06-20 11:53:11.000000000 -0400
@@ -0,0 +1,557 @@
+/****************************************************************
+ * policy_tool.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Stefan Berger <stefanb@watson.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * sHype policy management tool. This code runs in a domain and
+ * manages the Xen security policy by interacting with the
+ * Xen access control module via a /proc/xen/policycmd proc-ioctl,
+ * which is translated into a policy_op hypercall into Xen.
+ *
+ * todo: implement setpolicy to dynamically set a policy cache.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <stdint.h>
+#include <netinet/in.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+#include <xen/acm.h>
+
+#include <xen/policy_ops.h>
+
+#include <xen/linux/privcmd.h>
+
+#define ERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m "\n" , ## _a )
+
+#define PERROR(_m, _a...) \
+ fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
+ errno, strerror(errno))
+
+static inline int do_policycmd(int xc_handle,
+ unsigned int cmd,
+ unsigned long data)
+{
+ return ioctl(xc_handle, cmd, data);
+}
+
+static inline int do_xen_hypercall(int xc_handle,
+ privcmd_hypercall_t *hypercall)
+{
+ return do_policycmd(xc_handle,
+ IOCTL_PRIVCMD_HYPERCALL,
+ (unsigned long)hypercall);
+}
+
+static inline int do_policy_op(int xc_handle, policy_op_t *op)
+{
+ int ret = -1;
+ privcmd_hypercall_t hypercall;
+
+ op->interface_version = POLICY_INTERFACE_VERSION;
+
+ hypercall.op = __HYPERVISOR_policy_op;
+ hypercall.arg[0] = (unsigned long)op;
+
+ if ( mlock(op, sizeof(*op)) != 0 )
+ {
+ PERROR("Could not lock memory for Xen policy hypercall");
+ goto out1;
+ }
+
+ if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+ {
+ if ( errno == EACCES )
+ fprintf(stderr, "POLICY operation failed -- need to"
+ " rebuild the user-space tool set?\n");
+ goto out2;
+ }
+
+ out2: (void)munlock(op, sizeof(*op));
+ out1: return ret;
+}
+
+/*************************** DUMPS *******************************/
+
+void acm_dump_chinesewall_buffer(void *buf, int buflen) {
+
+ struct acm_chwall_policy_buffer *cwbuf = (struct acm_chwall_policy_buffer *)buf;
+ domaintype_t *ssids, *conflicts, *running_types, *conflict_aggregate;
+ int i,j;
+
+
+ if (htons(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY) {
+ printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\n\nChinese Wall policy:\n");
+ printf("====================\n");
+ printf("Max Types = %x.\n", ntohs(cwbuf->chwall_max_types));
+ printf("Max Ssidrefs = %x.\n", ntohs(cwbuf->chwall_max_ssidrefs));
+ printf("Max ConfSets = %x.\n", ntohs(cwbuf->chwall_max_conflictsets));
+ printf("Ssidrefs Off = %x.\n", ntohs(cwbuf->chwall_ssid_offset));
+ printf("Conflicts Off = %x.\n", ntohs(cwbuf->chwall_conflict_sets_offset));
+ printf("Runing T. Off = %x.\n", ntohs(cwbuf->chwall_running_types_offset));
+ printf("C. Agg. Off = %x.\n", ntohs(cwbuf->chwall_conflict_aggregate_offset));
+ printf("\nSSID To CHWALL-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + ntohs(cwbuf->chwall_ssid_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_ssidrefs); i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
+ printf("%02x ", ntohs(ssids[i*ntohs(cwbuf->chwall_max_types) + j]));
+ }
+ printf("\n\nConfict Sets:\n");
+ conflicts = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_sets_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_conflictsets); i++) {
+ printf("\n c-set%2x: ", i);
+ for(j=0; j< ntohs(cwbuf->chwall_max_types); j++)
+ printf("%02x ", ntohs(conflicts[i*ntohs(cwbuf->chwall_max_types) +j]));
+ }
+ printf("\n");
+
+ printf("\nRunning\nTypes: ");
+ if (ntohs(cwbuf->chwall_running_types_offset)) {
+ running_types = (domaintype_t *)(buf + ntohs(cwbuf->chwall_running_types_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) {
+ printf("%02x ", ntohs(running_types[i]));
+ }
+ printf("\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+ printf("\nConflict\nAggregate Set: ");
+ if (ntohs(cwbuf->chwall_conflict_aggregate_offset)) {
+ conflict_aggregate = (domaintype_t *)(buf + ntohs(cwbuf->chwall_conflict_aggregate_offset));
+ for(i=0; i< ntohs(cwbuf->chwall_max_types); i++) {
+ printf("%02x ", ntohs(conflict_aggregate[i]));
+ }
+ printf("\n\n");
+ } else {
+ printf("Not Reported!\n");
+ }
+}
+
+void acm_dump_ste_buffer(void *buf, int buflen) {
+
+ struct acm_ste_policy_buffer *stebuf = (struct acm_ste_policy_buffer *)buf;
+ domaintype_t *ssids;
+ int i,j;
+
+
+ if (ntohs(stebuf->policy_code) != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
+ printf("SIMPLE TYPE ENFORCEMENT POLICY CODE not found ERROR!!\n");
+ return;
+ }
+ printf("\nSimple Type Enforcement policy:\n");
+ printf("===============================\n");
+ printf("Max Types = %x.\n", ntohs(stebuf->ste_max_types));
+ printf("Max Ssidrefs = %x.\n", ntohs(stebuf->ste_max_ssidrefs));
+ printf("Ssidrefs Off = %x.\n", ntohs(stebuf->ste_ssid_offset));
+ printf("\nSSID To STE-Type matrix:\n");
+
+ ssids = (domaintype_t *)(buf + ntohs(stebuf->ste_ssid_offset));
+ for(i=0; i< ntohs(stebuf->ste_max_ssidrefs); i++) {
+ printf("\n ssidref%2x: ", i);
+ for(j=0; j< ntohs(stebuf->ste_max_types); j++)
+ printf("%02x ", ntohs(ssids[i*ntohs(stebuf->ste_max_types) +j]));
+ }
+ printf("\n\n");
+}
+
+void acm_dump_policy_buffer(void *buf, int buflen) {
+ struct acm_policy_buffer *pol = (struct acm_policy_buffer *)buf;
+
+ printf("\nPolicy dump:\n");
+ printf("============\n");
+ printf("Magic = %x.\n", ntohl(pol->magic));
+ printf("PolVer = %x.\n", ntohl(pol->policyversion));
+ printf("Len = %x.\n", ntohl(pol->len));
+ printf("Primary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME(ntohs(pol->primary_policy_code)),
+ ntohs(pol->primary_policy_code), ntohs(pol->primary_buffer_offset));
+ printf("Secondary = %s (c=%x, off=%x).\n",
+ ACM_POLICY_NAME(ntohs(pol->secondary_policy_code)),
+ ntohs(pol->secondary_policy_code), ntohs(pol->secondary_buffer_offset));
+ switch (ntohs(pol->primary_policy_code)) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+ntohs(pol->primary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->primary_buffer_offset));
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+ntohs(pol->primary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->primary_buffer_offset));
+ break;
+ case ACM_NULL_POLICY:
+ printf("Primary policy is NULL Policy (n/a).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ switch (ntohs(pol->secondary_policy_code)) {
+ case ACM_CHINESE_WALL_POLICY:
+ acm_dump_chinesewall_buffer(buf+ntohs(pol->secondary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_dump_ste_buffer(buf+ntohs(pol->secondary_buffer_offset),
+ ntohl(pol->len) - ntohs(pol->secondary_buffer_offset));
+ break;
+ case ACM_NULL_POLICY:
+ printf("Secondary policy is NULL Policy (n/a).\n");
+ break;
+ default:
+ printf("UNKNOWN POLICY!\n");
+ }
+ printf("\nPolicy dump End.\n\n");
+}
+
+/*************************** set policy ****************************/
+
+int acm_domain_set_chwallpolicy(void *bufstart, int buflen) {
+#define CWALL_MAX_SSIDREFS 5
+#define CWALL_MAX_TYPES 10
+#define CWALL_MAX_CONFLICTSETS 2
+
+ struct acm_chwall_policy_buffer *chwall_bin_pol = (struct acm_chwall_policy_buffer *)bufstart;
+ domaintype_t *ssidrefs, *conflicts;
+ int ret = 0;
+ int i,j;
+
+ chwall_bin_pol->chwall_max_types = htons(CWALL_MAX_TYPES);
+ chwall_bin_pol->chwall_max_ssidrefs = htons(CWALL_MAX_SSIDREFS);
+ chwall_bin_pol->policy_code = htons(ACM_CHINESE_WALL_POLICY);
+ chwall_bin_pol->chwall_ssid_offset = htons(sizeof(struct acm_chwall_policy_buffer));
+ chwall_bin_pol->chwall_max_conflictsets = htons(CWALL_MAX_CONFLICTSETS);
+ chwall_bin_pol->chwall_conflict_sets_offset =
+ htons(
+ ntohs(chwall_bin_pol->chwall_ssid_offset) +
+ sizeof(domaintype_t)*CWALL_MAX_SSIDREFS*CWALL_MAX_TYPES);
+ chwall_bin_pol->chwall_running_types_offset = 0; /* not set */
+ chwall_bin_pol->chwall_conflict_aggregate_offset = 0; /* not set */
+ ret += sizeof(struct acm_chwall_policy_buffer);
+ /* now push example ssids into the buffer (max_ssidrefs x max_types entries) */
+ /* check buffer size */
+ if ((buflen - ret) < (CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+ntohs(chwall_bin_pol->chwall_ssid_offset));
+ for(i=0; i< CWALL_MAX_SSIDREFS; i++) {
+ for (j=0; j< CWALL_MAX_TYPES; j++)
+ ssidrefs[i*CWALL_MAX_TYPES + j] = htons(0);
+ /* here, set type i for ssidref i; generally, a ssidref can have multiple chwall types */
+ if (i < CWALL_MAX_SSIDREFS)
+ ssidrefs[i*CWALL_MAX_TYPES + i] = htons(1);
+ }
+ ret += CWALL_MAX_TYPES*CWALL_MAX_SSIDREFS*sizeof(domaintype_t);
+ if ((buflen - ret) < (CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ /* now the chinese wall policy conflict sets*/
+ conflicts = (domaintype_t *)(bufstart +
+ ntohs(chwall_bin_pol->chwall_conflict_sets_offset));
+ memset((void *)conflicts, 0, CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES*sizeof(domaintype_t));
+ /* just 1 conflict set [0]={2,3}, [1]={0,5,6} */
+ if (CWALL_MAX_TYPES > 3) {
+ conflicts[2] = htons(1); conflicts[3] = htons(1); /* {2,3} */
+ conflicts[CWALL_MAX_TYPES] = htons(1); conflicts[CWALL_MAX_TYPES+5] = htons(1);
+ conflicts[CWALL_MAX_TYPES+6] = htons(1);/* {0,5,6} */
+ }
+ ret += sizeof(domaintype_t)*CWALL_MAX_CONFLICTSETS*CWALL_MAX_TYPES;
+ return ret;
+}
+
+int acm_domain_set_stepolicy(void *bufstart, int buflen) {
+#define STE_MAX_SSIDREFS 5
+#define STE_MAX_TYPES 5
+
+ struct acm_ste_policy_buffer *ste_bin_pol = (struct acm_ste_policy_buffer *)bufstart;
+ domaintype_t *ssidrefs;
+ int i,j, ret = 0;
+
+ ste_bin_pol->ste_max_types = htons(STE_MAX_TYPES);
+ ste_bin_pol->ste_max_ssidrefs = htons(STE_MAX_SSIDREFS);
+ ste_bin_pol->policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+ ste_bin_pol->ste_ssid_offset = htons(sizeof(struct acm_ste_policy_buffer));
+ ret += sizeof(struct acm_ste_policy_buffer);
+ /* check buffer size */
+ if ((buflen - ret) < (STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t)))
+ return -1; /* not enough space */
+
+ ssidrefs = (domaintype_t *)(bufstart+ntohs(ste_bin_pol->ste_ssid_offset));
+ for(i=0; i< STE_MAX_SSIDREFS; i++) {
+ for (j=0; j< STE_MAX_TYPES; j++)
+ ssidrefs[i*STE_MAX_TYPES + j] = htons(0);
+ /* set type i in ssidref 0 and ssidref i */
+ ssidrefs[i] = htons(1); /* ssidref 0 has all types set */
+ if (i < STE_MAX_SSIDREFS)
+ ssidrefs[i*STE_MAX_TYPES + i] = htons(1);
+ }
+ ret += STE_MAX_TYPES*STE_MAX_SSIDREFS*sizeof(domaintype_t);
+ return ret;
+}
+
+#define MAX_PUSH_BUFFER 16384
+u8 push_buffer[MAX_PUSH_BUFFER];
+
+int acm_domain_setpolicy(int xc_handle)
+{
+ int ret;
+ struct acm_policy_buffer *bin_pol;
+ policy_op_t op;
+
+ /* future: read policy from file and set it */
+ bin_pol = (struct acm_policy_buffer *)push_buffer;
+ bin_pol->magic = htonl(ACM_MAGIC);
+ bin_pol->policyversion = htonl(POLICY_INTERFACE_VERSION);
+ bin_pol->primary_policy_code = htons(ACM_CHINESE_WALL_POLICY);
+ bin_pol->secondary_policy_code = htons(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY);
+
+ bin_pol->len = htonl(sizeof(struct acm_policy_buffer));
+ bin_pol->primary_buffer_offset = htons(ntohl(bin_pol->len));
+ ret = acm_domain_set_chwallpolicy(push_buffer + ntohs(bin_pol->primary_buffer_offset),
+ MAX_PUSH_BUFFER - ntohs(bin_pol->primary_buffer_offset));
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+ bin_pol->secondary_buffer_offset = htons(ntohl(bin_pol->len));
+ ret = acm_domain_set_stepolicy(push_buffer + ntohs(bin_pol->secondary_buffer_offset),
+ MAX_PUSH_BUFFER - ntohs(bin_pol->secondary_buffer_offset));
+ if (ret < 0) {
+ printf("ERROR creating chwallpolicy buffer.\n");
+ return -1;
+ }
+ bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
+
+ /* dump it and then push it down into xen/acm */
+ acm_dump_policy_buffer(push_buffer, ntohl(bin_pol->len));
+ op.cmd = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)push_buffer;
+ op.u.setpolicy.pushcache_size = ntohl(bin_pol->len);
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_op(xc_handle, &op);
+
+ if (ret)
+ printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+ else
+ printf("Successfully changed policy.\n");
+ return ret;
+}
+
+/******************************* get policy ******************************/
+
+#define PULL_CACHE_SIZE 8192
+u8 pull_buffer[PULL_CACHE_SIZE];
+int acm_domain_getpolicy(int xc_handle)
+{
+ policy_op_t op;
+ int ret;
+
+ memset(pull_buffer, 0x00, sizeof(pull_buffer));
+ op.cmd = POLICY_GETPOLICY;
+ op.u.getpolicy.pullcache = (void *)pull_buffer;
+ op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = do_policy_op(xc_handle, &op);
+ /* dump policy */
+ acm_dump_policy_buffer(pull_buffer, sizeof(pull_buffer));
+ return ret;
+}
+
+/************************ load binary policy ******************************/
+
+int acm_domain_loadpolicy(int xc_handle,
+ const char *filename)
+{
+ struct stat mystat;
+ int ret, fd;
+ off_t len;
+ u8 *buffer;
+
+ if ((ret = stat(filename, &mystat))) {
+ printf("File %s not found.\n",filename);
+ goto out;
+ }
+
+ len = mystat.st_size;
+ if ((buffer = malloc(len)) == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ if ((fd = open(filename, O_RDONLY)) <= 0) {
+ ret = -ENOENT;
+ printf("File %s not found.\n",filename);
+ goto free_out;
+ }
+ if (len == read(fd, buffer, len)) {
+ policy_op_t op;
+ /* dump it and then push it down into xen/acm */
+ acm_dump_policy_buffer(buffer, len);
+ op.cmd = POLICY_SETPOLICY;
+ op.u.setpolicy.pushcache = (void *)buffer;
+ op.u.setpolicy.pushcache_size = len;
+ op.u.setpolicy.policy_type = ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ ret = do_policy_op(xc_handle, &op);
+
+ if (ret)
+ printf("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+ else
+ printf("Successfully changed policy.\n");
+
+ } else {
+ ret = -1;
+ }
+ close(fd);
+ free_out:
+ free(buffer);
+ out:
+ return ret;
+}
+
+/************************ dump hook statistics ******************************/
+void
+dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
+{
+ printf("STE-Policy Security Hook Statistics:\n");
+ printf("ste: event_channel eval_count = %d\n", ntohl(ste_stats->ec_eval_count));
+ printf("ste: event_channel denied_count = %d\n", ntohl(ste_stats->ec_denied_count));
+ printf("ste: event_channel cache_hit_count = %d\n", ntohl(ste_stats->ec_cachehit_count));
+ printf("ste:\n");
+ printf("ste: grant_table eval_count = %d\n", ntohl(ste_stats->gt_eval_count));
+ printf("ste: grant_table denied_count = %d\n", ntohl(ste_stats->gt_denied_count));
+ printf("ste: grant_table cache_hit_count = %d\n", ntohl(ste_stats->gt_cachehit_count));
+}
+
+#define PULL_STATS_SIZE 8192
+int acm_domain_dumpstats(int xc_handle)
+{
+ u8 stats_buffer[PULL_STATS_SIZE];
+ policy_op_t op;
+ int ret;
+ struct acm_stats_buffer *stats;
+
+ memset(stats_buffer, 0x00, sizeof(stats_buffer));
+ op.cmd = POLICY_DUMPSTATS;
+ op.u.dumpstats.pullcache = (void *)stats_buffer;
+ op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
+ ret = do_policy_op(xc_handle, &op);
+
+ if (ret < 0) {
+ printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
+ return ret;
+ }
+ stats = (struct acm_stats_buffer *)stats_buffer;
+
+ printf("\nPolicy dump:\n");
+ printf("============\n");
+ printf("Magic = %x.\n", ntohl(stats->magic));
+ printf("PolVer = %x.\n", ntohl(stats->policyversion));
+ printf("Len = %x.\n", ntohl(stats->len));
+
+ switch(ntohs(stats->primary_policy_code)) {
+ case ACM_NULL_POLICY:
+ printf("NULL Policy: No statistics apply.\n");
+ break;
+ case ACM_CHINESE_WALL_POLICY:
+ printf("Chinese Wall Policy: No statistics apply.\n");
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->primary_stats_offset)));
+ break;
+ default:
+ printf("UNKNOWN PRIMARY POLICY ERROR!\n");
+ }
+ switch(ntohs(stats->secondary_policy_code)) {
+ case ACM_NULL_POLICY:
+ printf("NULL Policy: No statistics apply.\n");
+ break;
+ case ACM_CHINESE_WALL_POLICY:
+ printf("Chinese Wall Policy: No statistics apply.\n");
+ break;
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ dump_ste_stats((struct acm_ste_stats_buffer *)(stats_buffer + ntohs(stats->secondary_stats_offset)));
+ break;
+ default:
+ printf("UNKNOWN SECONDARY POLICY ERROR!\n");
+ }
+ return ret;
+}
+
+/***************************** main **************************************/
+
+void
+usage(char *progname){
+ printf("Use: %s \n"
+ "\t setpolicy\n"
+ "\t getpolicy\n"
+ "\t dumpstats\n"
+ "\t loadpolicy <binary policy file>\n", progname);
+ exit(-1);
+}
+
+int
+main(int argc, char **argv) {
+
+ int policycmd_fd;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ if ((policycmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
+ printf("ERROR: Could not open xen policycmd device!\n");
+ exit(-1);
+ }
+
+ if (!strcmp(argv[1], "setpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_setpolicy(policycmd_fd);
+
+ } else if (!strcmp(argv[1], "getpolicy")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_getpolicy(policycmd_fd);
+
+ } else if (!strcmp(argv[1], "loadpolicy")) {
+ if (argc != 3)
+ usage(argv[0]);
+ acm_domain_loadpolicy(policycmd_fd, argv[2]);
+
+ } else if (!strcmp(argv[1], "dumpstats")) {
+ if (argc != 2)
+ usage(argv[0]);
+ acm_domain_dumpstats(policycmd_fd);
+
+ } else
+ usage(argv[0]);
+
+ close(policycmd_fd);
+ return 0;
+}
diff -uprN xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c xeno-unstable.bk-shype/tools/python/xen/lowlevel/xc/xc.c
--- xeno-unstable.bk_orig/tools/python/xen/lowlevel/xc/xc.c 2005-06-10 07:00:13.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/lowlevel/xc/xc.c 2005-06-20 11:53:11.000000000 -0400
@@ -78,13 +78,14 @@ static PyObject *pyxc_domain_create(PyOb
u32 dom = 0;
int ret;
+ u32 ssidref = 0xFFFFFFFF;
- static char *kwd_list[] = { "dom", NULL };
+ static char *kwd_list[] = { "dom", "ssidref", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &dom))
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, &dom, &ssidref))
return NULL;
- if ( (ret = xc_domain_create(xc->xc_handle, &dom)) < 0 )
+ if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
@@ -230,7 +231,7 @@ static PyObject *pyxc_domain_getinfo(PyO
}
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
- ",s:l,s:L,s:l,s:i}",
+ ",s:l,s:L,s:l,s:i,s:i}",
"dom", info[i].domid,
"vcpus", info[i].vcpus,
"dying", info[i].dying,
@@ -242,6 +243,7 @@ static PyObject *pyxc_domain_getinfo(PyO
"mem_kb", info[i].nr_pages*4,
"cpu_time", info[i].cpu_time,
"maxmem_kb", info[i].max_memkb,
+ "ssidref", info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason);
PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
PyDict_SetItemString( info_dict, "cpumap", cpumap_list );
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xend/image.py xeno-unstable.bk-shype/tools/python/xen/xend/image.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/image.py 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/xend/image.py 2005-06-20 11:53:11.000000000 -0400
@@ -111,7 +111,7 @@ class ImageHandler:
except OSError, ex:
log.warning("error removing bootloader file '%s': %s", f, ex)
- def initDomain(self, dom, memory, cpu, cpu_weight):
+ def initDomain(self, dom, memory, ssidref, cpu, cpu_weight):
"""Initial domain create.
@return domain id
@@ -119,14 +119,14 @@ class ImageHandler:
mem_kb = self.getDomainMemory(memory)
if not self.vm.restore:
- dom = xc.domain_create(dom = dom or 0)
+ dom = xc.domain_create(dom = dom or 0, ssidref = ssidref)
# if bootloader, unlink here. But should go after buildDomain() ?
if self.vm.bootloader:
self.unlink(self.kernel)
self.unlink(self.ramdisk)
if dom <= 0:
raise VmError('Creating domain failed: name=%s' % self.vm.name)
- log.debug("initDomain: cpu=%d mem_kb=%d dom=%d", cpu, mem_kb, dom)
+ log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom)
# xc.domain_setuuid(dom, uuid)
xc.domain_setcpuweight(dom, cpu_weight)
xc.domain_setmaxmem(dom, mem_kb)
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py xeno-unstable.bk-shype/tools/python/xen/xend/server/SrvDomainDir.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/server/SrvDomainDir.py 2005-06-10 07:00:13.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/xend/server/SrvDomainDir.py 2005-06-20 11:53:11.000000000 -0400
@@ -142,6 +142,7 @@ class SrvDomainDir(SrvDir):
% (url, d.name, d.name))
req.write('id=%s' % d.id)
req.write('memory=%d'% d.memory)
+ req.write('ssidref=%d'% d.ssidref)
req.write('</li>')
req.write('</ul>')
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py xeno-unstable.bk-shype/tools/python/xen/xend/XendDomainInfo.py
--- xeno-unstable.bk_orig/tools/python/xen/xend/XendDomainInfo.py 2005-06-20 08:51:49.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/xend/XendDomainInfo.py 2005-06-20 11:53:11.000000000 -0400
@@ -202,7 +202,9 @@ class XendDomainInfo:
"""
db = parentdb.addChild(uuid)
vm = cls(db)
- id = xc.domain_create()
+ ssidref = int(sxp.child_value(config, 'ssidref'))
+ log.debug('restoring with ssidref='+str(ssidref))
+ id = xc.domain_create(ssidref = ssidref)
vm.setdom(id)
try:
vm.restore = True
@@ -241,6 +243,7 @@ class XendDomainInfo:
self.start_time = None
self.name = None
self.memory = None
+ self.ssidref = None
self.image = None
self.channel = None
@@ -316,6 +319,7 @@ class XendDomainInfo:
"""
self.info = info
self.memory = self.info['mem_kb'] / 1024
+ self.ssidref = self.info['ssidref']
def state_set(self, state):
self.state_updated.acquire()
@@ -336,6 +340,7 @@ class XendDomainInfo:
s += " id=" + str(self.id)
s += " name=" + self.name
s += " memory=" + str(self.memory)
+ s += " ssidref=" + str(self.ssidref)
console = self.getConsole()
if console:
s += " console=" + str(console.console_port)
@@ -398,7 +403,8 @@ class XendDomainInfo:
sxpr = ['domain',
['id', self.id],
['name', self.name],
- ['memory', self.memory] ]
+ ['memory', self.memory],
+ ['ssidref', self.ssidref] ]
if self.uuid:
sxpr.append(['uuid', self.uuid])
if self.info:
@@ -533,6 +539,7 @@ class XendDomainInfo:
self.memory = int(sxp.child_value(config, 'memory'))
if self.memory is None:
raise VmError('missing memory size')
+ self.ssidref = int(sxp.child_value(config, 'ssidref'))
cpu = sxp.child_value(config, 'cpu')
if self.recreate and self.id and cpu is not None and int(cpu) >= 0:
xc.domain_pincpu(self.id, 0, 1<<int(cpu))
@@ -644,7 +651,7 @@ class XendDomainInfo:
def show(self):
"""Print virtual machine info.
"""
- print "[VM dom=%d name=%s memory=%d" % (self.id, self.name, self.memory)
+ print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.id, self.name, self.memory, self.ssidref)
print "image:"
sxp.show(self.image)
print "]"
@@ -660,7 +667,7 @@ class XendDomainInfo:
cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
except:
raise VmError('invalid cpu')
- id = self.image.initDomain(self.id, self.memory, cpu, self.cpu_weight)
+ id = self.image.initDomain(self.id, self.memory, self.ssidref, cpu, self.cpu_weight)
log.debug('init_domain> Created domain=%d name=%s memory=%d',
id, self.name, self.memory)
self.setdom(id)
@@ -1011,6 +1018,7 @@ addImageHandlerClass(VmxImageHandler)
# Ignore the fields we already handle.
add_config_handler('name', vm_field_ignore)
add_config_handler('memory', vm_field_ignore)
+add_config_handler('ssidref', vm_field_ignore)
add_config_handler('cpu', vm_field_ignore)
add_config_handler('cpu_weight', vm_field_ignore)
add_config_handler('console', vm_field_ignore)
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xm/create.py xeno-unstable.bk-shype/tools/python/xen/xm/create.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/create.py 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/xm/create.py 2005-06-20 11:53:11.000000000 -0400
@@ -120,6 +120,10 @@ gopts.var('memory', val='MEMORY',
fn=set_int, default=128,
use="Domain memory in MB.")
+gopts.var('ssidref', val='SSIDREF',
+ fn=set_u32, default=0xffffffff,
+ use="Security Identifier.")
+
gopts.var('maxmem', val='MEMORY',
fn=set_int, default=None,
use="Maximum domain memory in MB.")
@@ -405,7 +409,8 @@ def make_config(opts, vals):
config = ['vm',
['name', vals.name ],
- ['memory', vals.memory ]]
+ ['memory', vals.memory ],
+ ['ssidref', vals.ssidref ]]
if vals.maxmem:
config.append(['maxmem', vals.maxmem])
if vals.cpu is not None:
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xm/main.py xeno-unstable.bk-shype/tools/python/xen/xm/main.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/main.py 2005-06-06 07:40:20.000000000 -0400
+++ xeno-unstable.bk-shype/tools/python/xen/xm/main.py 2005-06-20 11:53:11.000000000 -0400
@@ -383,7 +383,7 @@ class ProgList(Prog):
self.brief_list(doms)
def brief_list(self, doms):
- print 'Name Id Mem(MB) CPU VCPU(s) State Time(s) Console'
+ print 'Name Id Mem(MB) CPU VCPU(s) State Time(s) Console SSID-REF'
for dom in doms:
info = server.xend_domain(dom)
d = {}
@@ -399,8 +399,12 @@ class ProgList(Prog):
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
- print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s"
- % d)
+ if ((int(sxp.child_value(info, 'ssidref', '-1'))) != -1):
+ d['ssidref1'] = int(sxp.child_value(info, 'ssidref', '-1')) & 0xffff
+ d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '-1')) >> 16) & 0xffff
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
+ else:
+ print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(vcpus)5d %(state)5s %(cpu_time)7.1f %(port)4s default" % d)
def show_vcpus(self, doms):
print 'Name Id VCPU CPU CPUMAP'
diff -uprN xeno-unstable.bk_orig/tools/python/xen/xm/opts.py xeno-unstable.bk-shype/tools/python/xen/xm/opts.py
--- xeno-unstable.bk_orig/tools/python/xen/xm/opts.py 2005-03-31 16:17:05.000000000 -0500
+++ xeno-unstable.bk-shype/tools/python/xen/xm/opts.py 2005-06-20 11:53:11.000000000 -0400
@@ -451,6 +451,13 @@ def set_bool(opt, k, v):
else:
opt.opts.err('Invalid value:' +v)
+def set_u32(opt, k, v):
+ """Set an option to an u32 value."""
+ try:
+ v = u32(v)
+ except:
+ opt.opts.err('Invalid value: ' + str(v))
+ opt.set(v)
def set_value(opt, k, v):
"""Set an option to a value."""
[-- 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] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-20 17:22 [PATCH] sHype access control architecture for Xen Reiner Sailer
@ 2005-06-21 5:47 ` aq
2005-06-21 6:26 ` Tupshin Harper
2005-06-21 13:25 ` Alvin Starr
0 siblings, 2 replies; 11+ messages in thread
From: aq @ 2005-06-21 5:47 UTC (permalink / raw)
To: Reiner Sailer
Cc: leendert, ronpz, rvaldez, sailer, xen-devel, xense-devel, stefanb,
steven.hand
On 6/21/05, Reiner Sailer <sailer@watson.ibm.com> wrote:
> This E-mail contains the sHype access control architecture
> for inclusion into the Xen hypervisor (xeno-unstable.bk).
> This is a follow-up on earlier postings:
> http://lists.xensource.com/archives/html/xen-devel/2005-04/msg00864.html
>
> The *_xen.diff patch includes the core sHype access control
> architecture. Default is the NULL-policy.
>
> The *_tools.diff patch includes the necessary additions to the
> tools directory:
> a) adding support for an additional VM configuration paramter
> b) adding basic policy management support into tools/policy
>
> The default setting is the NULL policy. After patching in the diff-
> files, you should see no change in behavior. Please refer to the
> attached shype4xen_readme.txt file for instructions on how to
> activate and experiment with sHype.
>
> While we have added support for saving and restoring security
> information when saving and restoring domains, the architecture
> currently supports save/restore only on the same hypervisor system
> running the same sHype policy. Future versions will include more
> flexible support for save/restore/migration.
>
> Our group will submit a java-based policy translation tool for sHype to
> this mailing list today as well. This tool takes as input an XML-based
> descriptions of user-defined sHype policies and translates them into a
> binary policy format that can be loaded into sHype.
any plan to write the tool in other language, not Java? i guess not
many people (include me) are willing to install Java on their system.
since python is used in xen, i think it is a good candidate.
i will play with the code and give some feedbacks.
regards,
aq
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 5:47 ` aq
@ 2005-06-21 6:26 ` Tupshin Harper
2005-06-21 7:35 ` aq
2005-06-21 12:32 ` Scott Parish
2005-06-21 13:25 ` Alvin Starr
1 sibling, 2 replies; 11+ messages in thread
From: Tupshin Harper @ 2005-06-21 6:26 UTC (permalink / raw)
To: aq
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, xense-devel,
Reiner Sailer, stefanb, steven.hand
aq wrote:
>any plan to write the tool in other language, not Java? i guess not
>many people (include me) are willing to install Java on their system.
>
>since python is used in xen, i think it is a good candidate.
>
>i will play with the code and give some feedbacks.
>
>regards,
>aq
>
Ensuring that the code compiles cleanly with gcj would eliminate this issue.
-Tupshin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 6:26 ` Tupshin Harper
@ 2005-06-21 7:35 ` aq
2005-06-21 10:56 ` Tupshin Harper
` (3 more replies)
2005-06-21 12:32 ` Scott Parish
1 sibling, 4 replies; 11+ messages in thread
From: aq @ 2005-06-21 7:35 UTC (permalink / raw)
To: Tupshin Harper
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, xense-devel,
Reiner Sailer, stefanb, steven.hand
On 6/21/05, Tupshin Harper <tupshin@tupshin.com> wrote:
> aq wrote:
>
> >any plan to write the tool in other language, not Java? i guess not
> >many people (include me) are willing to install Java on their system.
> >
> >since python is used in xen, i think it is a good candidate.
> >
> >i will play with the code and give some feedbacks.
> >
> >regards,
> >aq
> >
> Ensuring that the code compiles cleanly with gcj would eliminate this issue.
but we still need java to run the binary code, dont we?
regards,
aq
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 7:35 ` aq
@ 2005-06-21 10:56 ` Tupshin Harper
2005-06-21 11:26 ` Mark Williamson
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Tupshin Harper @ 2005-06-21 10:56 UTC (permalink / raw)
To: aq
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, xense-devel,
Reiner Sailer, stefanb, steven.hand
aq wrote:
>On 6/21/05, Tupshin Harper <tupshin@tupshin.com> wrote:
>
>
>>aq wrote:
>>
>>
>>
>>>any plan to write the tool in other language, not Java? i guess not
>>>many people (include me) are willing to install Java on their system.
>>>
>>>since python is used in xen, i think it is a good candidate.
>>>
>>>i will play with the code and give some feedbacks.
>>>
>>>regards,
>>>aq
>>>
>>>
>>>
>>Ensuring that the code compiles cleanly with gcj would eliminate this issue.
>>
>>
>
>but we still need java to run the binary code, dont we?
>
>regards,
>aq
>
>
No. GCJ can make native binaries (even statically linked ones) with no
unusual dependencies.
-Tupshin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 7:35 ` aq
2005-06-21 10:56 ` Tupshin Harper
@ 2005-06-21 11:26 ` Mark Williamson
2005-06-21 12:11 ` Grzegorz Milos
2005-06-21 13:49 ` Ray Valdez
3 siblings, 0 replies; 11+ messages in thread
From: Mark Williamson @ 2005-06-21 11:26 UTC (permalink / raw)
To: xen-devel, aq
Cc: leendert, ronpz, rvaldez, sailer, Tupshin Harper, Reiner Sailer,
stefanb, steven.hand, xense-devel
> > Ensuring that the code compiles cleanly with gcj would eliminate this
> > issue.
>
> but we still need java to run the binary code, dont we?
The GCJ package can deal with binary Java code - you get:
* compiles .java files to .class or to native
* compiles .class to native
* GIJ interprets .class files that haven't been natively compiled
It's actually rather impressive!
But the binary that was originally mentioned earlier is the sHype policy,
right? i.e. not Java, just produced by the tool
Cheers,
Mark
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 7:35 ` aq
2005-06-21 10:56 ` Tupshin Harper
2005-06-21 11:26 ` Mark Williamson
@ 2005-06-21 12:11 ` Grzegorz Milos
2005-06-21 13:49 ` Ray Valdez
3 siblings, 0 replies; 11+ messages in thread
From: Grzegorz Milos @ 2005-06-21 12:11 UTC (permalink / raw)
To: xen-devel
> On 6/21/05, Tupshin Harper <tupshin@tupshin.com> wrote:
> > aq wrote:
> > >any plan to write the tool in other language, not Java? i guess not
> > >many people (include me) are willing to install Java on their system.
> > >
> > >since python is used in xen, i think it is a good candidate.
> > >
> > >i will play with the code and give some feedbacks.
> > >
> > >regards,
> > >aq
> >
> > Ensuring that the code compiles cleanly with gcj would eliminate this
> > issue.
>
> but we still need java to run the binary code, dont we?
gjc is supposed to be able to compile Java to native machine code, but I have
never used it myself. Assuming that it works you wouldn't need JRE or SDK.
Gregor
--
Quidquid latine dictum sit, altum viditur --- Anon
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 6:26 ` Tupshin Harper
2005-06-21 7:35 ` aq
@ 2005-06-21 12:32 ` Scott Parish
1 sibling, 0 replies; 11+ messages in thread
From: Scott Parish @ 2005-06-21 12:32 UTC (permalink / raw)
To: Tupshin Harper
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, xense-devel,
Reiner Sailer, stefanb, steven.hand
On Mon, Jun 20, 2005 at 11:26:08PM -0700, Tupshin Harper wrote:
> Ensuring that the code compiles cleanly with gcj would eliminate this issue.
Not everyone installs gcj either.
sRp
--
Scott Parish
Signed-off-by: srparish@us.ibm.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 5:47 ` aq
2005-06-21 6:26 ` Tupshin Harper
@ 2005-06-21 13:25 ` Alvin Starr
1 sibling, 0 replies; 11+ messages in thread
From: Alvin Starr @ 2005-06-21 13:25 UTC (permalink / raw)
To: aq
Cc: xen-devel, ronpz, leendert, rvaldez, sailer, xense-devel,
Reiner Sailer, stefanb, steven.hand
aq wrote:
>On 6/21/05, Reiner Sailer <sailer@watson.ibm.com> wrote:
>
>
>>This E-mail contains the sHype access control architecture
>>for inclusion into the Xen hypervisor (xeno-unstable.bk).
>>This is a follow-up on earlier postings:
>>http://lists.xensource.com/archives/html/xen-devel/2005-04/msg00864.html
>>
>>
>>
[snip]
>any plan to write the tool in other language, not Java? i guess not
>many people (include me) are willing to install Java on their system.
>
Hmmm. I have the same complaint about Python. I tend to like anything
that can be compiled into a more or less standalone binary.
The current Python tools have a whole chain of dependancies and I often
find that this kind of thing ends up leaving me in a situation where I
have conflicting dependancies.
I just love staicaly compiled binaries or somthing that at most requires
the libraries you get with a stock libc install.
I have not looked at the sHype tools but it may be that they can be
compiled with gcj and turned into a static binary.
>
>since python is used in xen, i think it is a good candidate.
>
>i will play with the code and give some feedbacks.
>
>regards,
>aq
>
>_______________________________________________
>Xen-devel mailing list
>Xen-devel@lists.xensource.com
>http://lists.xensource.com/xen-devel
>
>
--
Alvin Starr || voice: (416)585-9971
Interlink Connectivity || fax: (416)585-9974
alvin@iplink.net ||
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 7:35 ` aq
` (2 preceding siblings ...)
2005-06-21 12:11 ` Grzegorz Milos
@ 2005-06-21 13:49 ` Ray Valdez
2005-06-21 14:48 ` aq
3 siblings, 1 reply; 11+ messages in thread
From: Ray Valdez @ 2005-06-21 13:49 UTC (permalink / raw)
To: aq
Cc: xen-devel, Stefan Berger, Leendert Van Doorn, Reiner Sailer,
Tupshin Harper, Reiner Sailer, Ronald Perez, steven.hand,
xense-devel
On 6/21/05, Tupshin Harper <tupshin@tupshin.com> wrote:
> aq wrote:
>
> >any plan to write the tool in other language, not Java? i guess not
> >many people (include me) are willing to install Java on their system.
> >
> >since python is used in xen, i think it is a good candidate.
> >
> >i will play with the code and give some feedbacks.
> Ensuring that the code compiles cleanly with gcj would eliminate this
issue.
We will look into compiling the tool with gcj. Thanks. We will appreciate
your feedback.
> but we still need java to run the binary code, dont we?
No. The tool is used for generating a binary policy file, which can then be
loaded into sHype via the
xeno-unstable.bk/tools/policy/policy_tool command.
Thanks,
-Ray
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sHype access control architecture for Xen
2005-06-21 13:49 ` Ray Valdez
@ 2005-06-21 14:48 ` aq
0 siblings, 0 replies; 11+ messages in thread
From: aq @ 2005-06-21 14:48 UTC (permalink / raw)
To: Ray Valdez
Cc: xen-devel, Stefan Berger, Leendert Van Doorn, Reiner Sailer,
Tupshin Harper, Reiner Sailer, Ronald Perez, steven.hand,
xense-devel
On 6/21/05, Ray Valdez <rvaldez@us.ibm.com> wrote:
> On 6/21/05, Tupshin Harper <tupshin@tupshin.com> wrote:
> > aq wrote:
> >
> > >any plan to write the tool in other language, not Java? i guess not
> > >many people (include me) are willing to install Java on their system.
> > >
> > >since python is used in xen, i think it is a good candidate.
> > >
> > >i will play with the code and give some feedbacks.
>
> > Ensuring that the code compiles cleanly with gcj would eliminate this
> issue.
>
> We will look into compiling the tool with gcj. Thanks. We will appreciate
> your feedback.
>
> > but we still need java to run the binary code, dont we?
>
> No. The tool is used for generating a binary policy file, which can then be
> loaded into sHype via the
> xeno-unstable.bk/tools/policy/policy_tool command.
>
to tell the truth, installing java into any of my machines is the last
thing i want to do. if it is possible to compile java code to native
binary, that would be great. then java turns out to be even better
than python, right ;-)
regards,
aq
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2005-06-21 14:48 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-20 17:22 [PATCH] sHype access control architecture for Xen Reiner Sailer
2005-06-21 5:47 ` aq
2005-06-21 6:26 ` Tupshin Harper
2005-06-21 7:35 ` aq
2005-06-21 10:56 ` Tupshin Harper
2005-06-21 11:26 ` Mark Williamson
2005-06-21 12:11 ` Grzegorz Milos
2005-06-21 13:49 ` Ray Valdez
2005-06-21 14:48 ` aq
2005-06-21 12:32 ` Scott Parish
2005-06-21 13:25 ` Alvin Starr
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.