merge with xen-unstable.hg

This commit is contained in:
awilliam@xenbuild.aw committed 2006-04-25 23:35:55 -06:00
commit aaf9402dab
159 files changed
+7002 -5697

No files matched your search

+176 -176
View File
@@ -1,176 +1,176 @@
################################
__ __ _____ ___
\ \/ /___ _ __ |___ / / _ \
\ // _ \ '_ \ |_ \| | | |
/ \ __/ | | | ___) | |_| |
/_/\_\___|_| |_| |____(_)___/
################################
http://www.xensource.com/xen/about.html
What is Xen?
============
Xen is a Virtual Machine Monitor (VMM) originally developed by the
Systems Research Group of the University of Cambridge Computer
Laboratory, as part of the UK-EPSRC funded XenoServers project. Xen
is freely-distributable Open Source software, released under the GNU
GPL. Since its initial public release, Xen has grown a large
development community, spearheaded by XenSource Inc, a company created
by the original Xen development team to build enterprise products
around Xen.
The 3.0 release offers excellent performance, hardware support and
enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
live relocation of VMs. This install tree contains source for a Linux
2.6 guest; ports to Linux 2.4, NetBSD, FreeBSD and Solaris will follow
later (and are already available for previous Xen releases).
This file contains some quick-start instructions to install Xen on
your system. For full documentation, see the Xen User Manual. If this
is a pre-built release then you can find the manual at:
dist/install/usr/share/doc/xen/pdf/user.pdf
If you have a source release, then 'make -C docs' will build the
manual at docs/pdf/user.pdf.
Quick-Start Guide - Pre-Built Binary Release
============================================
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Install the binary distribution onto your filesystem:
# sh ./install.sh
Among other things, this will install Xen and Xen-ready Linux
kernel files in /boot, kernel modules and Python packages in /lib,
and various control tools in standard 'bin' directories.
2. Configure your bootloader to boot Xen and an initial Linux virtual
machine. Note that Xen currently only works with GRUB and pxelinux
derived boot loaders: less common alternatives such as LILO are
*not* supported. You can most likely find your GRUB menu file at
/boot/grub/menu.lst: edit this file to include an entry like the
following:
title Xen 3.0 / XenLinux 2.6
kernel /boot/xen-3.0.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
NB: Not all kernel configs need an initial ram disk (initrd), but
if you do specify one you'll need to use the 'module' grub directive
rather than 'initrd'.
The linux command line takes all the usual options, such as
root=<root-dev> to specify your usual root partition (e.g.,
/dev/hda1).
The Xen command line takes a number of optional arguments described
in the manual. The most common is 'dom0_mem=xxxM' which sets the
amount of memory to allocate for use by your initial virtual
machine (known as domain 0). Note that Xen itself reserves about
32MB memory for internal use, which is not available for allocation
to virtual machines.
3. Reboot your system and select the "Xen 3.0 / XenLinux 2.6" menu
option. After booting Xen, Linux will start and your initialisation
scripts should execute in the usual way.
Quick-Start Guide - Source Release
==================================
First, there are a number of prerequisites for building a Xen source
release. Make sure you have all the following installed, either by
visiting the project webpage or installing a pre-built package
provided by your Linux distributor:
* GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib-dev)
* Development install of Python v2.3 or later (e.g., python-dev)
* bridge-utils package (/sbin/brctl)
* iproute package (/sbin/ip)
* hotplug or udev
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Download and untar the source tarball file. This will be a
file named xen-unstable-src.tgz, or xen-$version-src.tgz.
You can also pull the current version from the SCMS
that is being used (Bitkeeper, scheduled to change shortly).
# tar xzf xen-unstable-src.tgz
Assuming you are using the unstable tree, this will
untar into xen-unstable. The rest of the instructions
use the unstable tree as an example, substitute the
version for unstable.
2. cd to xen-unstable (or whatever you sensibly rename it to).
The Linux, netbsd and freebsd kernel source trees are in
the $os-$version-xen-sparse directories.
On Linux:
3. For the very first build, or if you want to destroy existing
.configs and build trees, perform the following steps:
# make world
# make install
This will create and install onto the local machine. It will build
the xen binary (xen.gz), and a linux kernel and modules that can be
used in both dom0 and an unprivileged guest kernel (vmlinuz-2.6.x-xen),
the tools and the documentation.
You can override the destination for make install by setting DESTDIR
to some value.
The make command line defaults to building the kernel vmlinuz-2.6.x-xen.
You can override this default by specifying KERNELS=kernelname. For
example, you can make two kernels - linux-2.6-xen0
and linux-2.6-xenU - which are smaller builds containing only selected
modules, intended primarily for developers that don't like to wait
for a full -xen kernel to build. The -xenU kernel is particularly small,
as it does not contain any physical device drivers, and hence is
only useful for guest domains.
To make these two kernels, simply specify
KERNELS="linux-2.6-xen0 linux-2.6-xenU"
in the make command line.
If you want to build an x86_32 PAE capable xen and kernel to work
on machines with >= 4GB of memory, use XEN_TARGET_X86_PAE=y on the
make command line.
4. To rebuild an existing tree without modifying the config:
# make dist
This will build and install xen, kernels, tools, and
docs into the local dist/ directory.
You can override the destination for make install by setting DISTDIR
to some value.
make install and make dist differ in that make install does the
right things for your local machine (installing the appropriate
version of hotplug or udev scripts, for example), but make dist
includes all versions of those scripts, so that you can copy the dist
directory to another machine and install from that distribution.
5. To rebuild a kernel with a modified config:
# make linux-2.6-xen-config CONFIGMODE=menuconfig (or xconfig)
# make linux-2.6-xen-build
# make linux-2.6-xen-install
Depending on your config, you may need to use 'mkinitrd' to create
an initial ram disk, just like a native system e.g.
# depmod 2.6.16-xen
# mkinitrd -v -f --with=aacraid --with=sd_mod --with=scsi_mod initrd-2.6.16-xen.img 2.6.16-xen
################################
__ __ _____ ___
\ \/ /___ _ __ |___ / / _ \
\ // _ \ '_ \ |_ \| | | |
/ \ __/ | | | ___) | |_| |
/_/\_\___|_| |_| |____(_)___/
################################
http://www.xensource.com/xen/about.html
What is Xen?
============
Xen is a Virtual Machine Monitor (VMM) originally developed by the
Systems Research Group of the University of Cambridge Computer
Laboratory, as part of the UK-EPSRC funded XenoServers project. Xen
is freely-distributable Open Source software, released under the GNU
GPL. Since its initial public release, Xen has grown a large
development community, spearheaded by XenSource Inc, a company created
by the original Xen development team to build enterprise products
around Xen.
The 3.0 release offers excellent performance, hardware support and
enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
live relocation of VMs. This install tree contains source for a Linux
2.6 guest; ports to Linux 2.4, NetBSD, FreeBSD and Solaris will follow
later (and are already available for previous Xen releases).
This file contains some quick-start instructions to install Xen on
your system. For full documentation, see the Xen User Manual. If this
is a pre-built release then you can find the manual at:
dist/install/usr/share/doc/xen/pdf/user.pdf
If you have a source release, then 'make -C docs' will build the
manual at docs/pdf/user.pdf.
Quick-Start Guide - Pre-Built Binary Release
============================================
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Install the binary distribution onto your filesystem:
# sh ./install.sh
Among other things, this will install Xen and Xen-ready Linux
kernel files in /boot, kernel modules and Python packages in /lib,
and various control tools in standard 'bin' directories.
2. Configure your bootloader to boot Xen and an initial Linux virtual
machine. Note that Xen currently only works with GRUB and pxelinux
derived boot loaders: less common alternatives such as LILO are
*not* supported. You can most likely find your GRUB menu file at
/boot/grub/menu.lst: edit this file to include an entry like the
following:
title Xen 3.0 / XenLinux 2.6
kernel /boot/xen-3.0.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
NB: Not all kernel configs need an initial ram disk (initrd), but
if you do specify one you'll need to use the 'module' grub directive
rather than 'initrd'.
The linux command line takes all the usual options, such as
root=<root-dev> to specify your usual root partition (e.g.,
/dev/hda1).
The Xen command line takes a number of optional arguments described
in the manual. The most common is 'dom0_mem=xxxM' which sets the
amount of memory to allocate for use by your initial virtual
machine (known as domain 0). Note that Xen itself reserves about
32MB memory for internal use, which is not available for allocation
to virtual machines.
3. Reboot your system and select the "Xen 3.0 / XenLinux 2.6" menu
option. After booting Xen, Linux will start and your initialisation
scripts should execute in the usual way.
Quick-Start Guide - Source Release
==================================
First, there are a number of prerequisites for building a Xen source
release. Make sure you have all the following installed, either by
visiting the project webpage or installing a pre-built package
provided by your Linux distributor:
* GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib-dev)
* Development install of Python v2.3 or later (e.g., python-dev)
* bridge-utils package (/sbin/brctl)
* iproute package (/sbin/ip)
* hotplug or udev
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Download and untar the source tarball file. This will be a
file named xen-unstable-src.tgz, or xen-$version-src.tgz.
You can also pull the current version from the SCMS
that is being used (Bitkeeper, scheduled to change shortly).
# tar xzf xen-unstable-src.tgz
Assuming you are using the unstable tree, this will
untar into xen-unstable. The rest of the instructions
use the unstable tree as an example, substitute the
version for unstable.
2. cd to xen-unstable (or whatever you sensibly rename it to).
The Linux, netbsd and freebsd kernel source trees are in
the $os-$version-xen-sparse directories.
On Linux:
3. For the very first build, or if you want to destroy existing
.configs and build trees, perform the following steps:
# make world
# make install
This will create and install onto the local machine. It will build
the xen binary (xen.gz), and a linux kernel and modules that can be
used in both dom0 and an unprivileged guest kernel (vmlinuz-2.6.x-xen),
the tools and the documentation.
You can override the destination for make install by setting DESTDIR
to some value.
The make command line defaults to building the kernel vmlinuz-2.6.x-xen.
You can override this default by specifying KERNELS=kernelname. For
example, you can make two kernels - linux-2.6-xen0
and linux-2.6-xenU - which are smaller builds containing only selected
modules, intended primarily for developers that don't like to wait
for a full -xen kernel to build. The -xenU kernel is particularly small,
as it does not contain any physical device drivers, and hence is
only useful for guest domains.
To make these two kernels, simply specify
KERNELS="linux-2.6-xen0 linux-2.6-xenU"
in the make command line.
If you want to build an x86_32 PAE capable xen and kernel to work
on machines with >= 4GB of memory, use XEN_TARGET_X86_PAE=y on the
make command line.
4. To rebuild an existing tree without modifying the config:
# make dist
This will build and install xen, kernels, tools, and
docs into the local dist/ directory.
You can override the destination for make install by setting DISTDIR
to some value.
make install and make dist differ in that make install does the
right things for your local machine (installing the appropriate
version of hotplug or udev scripts, for example), but make dist
includes all versions of those scripts, so that you can copy the dist
directory to another machine and install from that distribution.
5. To rebuild a kernel with a modified config:
# make linux-2.6-xen-config CONFIGMODE=menuconfig (or xconfig)
# make linux-2.6-xen-build
# make linux-2.6-xen-install
Depending on your config, you may need to use 'mkinitrd' to create
an initial ram disk, just like a native system e.g.
# depmod 2.6.16-xen
# mkinitrd -v -f --with=aacraid --with=sd_mod --with=scsi_mod initrd-2.6.16-xen.img 2.6.16-xen
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+6
View File
@@ -109,6 +109,12 @@ If the value is 0, all available CPUs will be used by Domain0.
A boolean value that tells xend whether or not core dumps of guest
domains should be saved when a crash occurrs. Defaults to I<no>.
=item I<external-migration-tool>
The name of an application or script that can handle external device
migration, such as for example virtual TPM migration. An example
script is I</etc/xen/scripts/external-device-migrate>.
=back
=head1 EXAMPLES
+270 -1
View File
@@ -136,7 +136,7 @@ Displays the short help message (i.e. common commands).
The I<--long> option prints out the complete set of B<xm> subcommands,
grouped by function.
=item B<list> I<[--long]> I<[domain-id, ...]>
=item B<list> I<[--long | --label]> I<[domain-id, ...]>
Prints information about one or more domains. If no domains are
specified it prints out information about all domains.
@@ -213,6 +213,18 @@ Use at your own risk.
=back
B<LABEL OUTPUT>
=over 4
If I<--label> is specified, the security labels are added to the
output of xm list and the lines are sorted by the labels (ignoring
case). The I<--long> option prints the labels by default and cannot be
combined with I<--label>. See the ACCESS CONTROL SUBCOMMAND section of
this man page for more information about labels.
==back
B<NOTES>
=over 4
@@ -775,6 +787,262 @@ Delete a vnet.
=back
=head1 ACCESS CONTROL SUBCOMMANDS
Access Control in Xen consists of two components: (i) The Access
Control Policy (ACP) defines security labels and access rules based on
these labels. (ii) The Access Control Module (ACM) makes access control
decisions by interpreting the policy when domains require to
communicate or to access resources. The Xen access control has
sufficient mechanisms in place to enforce the access decisions even
against maliciously acting user domains (mandatory access control).
Access rights for domains in Xen are determined by the domain security
label only and not based on the domain Name or ID. The ACP specifies
security labels that can then be assigned to domains and
resources. Every domain must be assigned exactly one security label,
otherwise access control decisions could become indeterministic. ACPs
are distinguished by their name, which is a parameter to most of the
subcommands described below. Currently, the ACP specifies two ways to
interpret labels:
(1) Simple Type Enforcement: Labels are interpreted to decide access
of domains to comunication means and virtual or physical
resources. Communication between domains as well as access to
resources are forbidden by default and can only take place if they are
explicitly allowed by the security policy. The proper assignment of
labels to domains controls the sharing of information (directly
through communication or indirectly through shared resources) between
domains. This interpretation allows to control the overt (intended)
communication channels in Xen.
(2) Chinese Wall: Labels are interpreted to decide which domains can
co-exist (be run simultaneously) on the same system. This
interpretation allows to prevent direct covert (unintended) channels
and mitigates risks caused by imperfect core domain isolation
(trade-off between security and other system requirements). For a
short introduction to covert channels, please refer to
http://www.multicians.org/timing-chn.html.
The following subcommands help you to manage security policies in Xen
and to assign security labels to domains. To enable access control
security in Xen, you must compile Xen with ACM support enabled as
described under "Configuring Security" below. There, you will find
also examples of each subcommand described here.
=item B<makepolicy> I<policy>
Compiles the XML source representation of the security I<policy>. It
creates a mapping (.map) as well as a binary (.bin) version of the
policy. The compiled policy can be loaded into Xen with the
B<loadpolicy> subcommand or can be configured to be loaded at boot
time with the B<cfgbootpolicy> subcommand.
=over 4
I<policy> is a dot-separated list of names. The last part is the file
name pre-fix for the policy xml file. The preceding name parts are
translated into the local path pointing to the policy xml file
relative to the global policy root directory
(/etc/xen/acm-security/policies). For example,
example.chwall_ste.client_v1 denotes the policy file
example/chwall_ste/client_v1-security_policy.xml relative to the
global policy root directory.
=back
=item B<loadpolicy> I<policy>
Loads the binary representation of the I<policy> into Xen. The binary
representation can be created with the B<makepolicy> subcommand.
=item B<cfgbootpolicy> I<policy> [I<kernelversion>]
Configures I<policy> as the boot policy for Xen. It copies the binary
policy representation into the /boot directory and adds a module line
specifying the binary policy to the /boot/grub/menu.lst file. If your
boot configuration includes multiple Xen boot titles, then use the
I<kernelversion> parameter to select the proper title.
=item B<dumppolicy>
Prints the current security policy state information of Xen.
=item B<labels> [I<policy>] [I<type>=dom|res|any]
Lists all labels of a I<type> (domain, resource, or both) that are
defined in the I<policy>. Unless specified, the default I<policy> is
the currently enforced access control policy. The default for I<type>
is 'dom'. The labels are arranged in alphabetical order.
=item B<addlabel> I<configfile> I<label> [I<policy>]
Adds the security label with name I<label> to a domain
I<configfile>. Unless specified, the default I<policy> is the
currently enforced access control policy. This subcommand also
verifies that the I<policy> definition supports the specified I<label>
name.
B<CONFIGURING SECURITY>
=over 4
In xen_source_dir/Config.mk set the following parameters:
ACM_SECURITY ?= y
ACM_DEFAULT_SECURITY_POLICY ?= \
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
Then recompile and install xen and the security tools and then reboot:
cd xen_source_dir/xen; make clean; make; cp xen.gz /boot;
cd xen_source_dir/tools/security; make install;
reboot into xen
=back
B<COMPILING A SECURITY POLICY>
=over 4
This step creates client_v1.map and client_v1.bin files in
/etc/xen/acm-security/policies/example/chwall_ste.
xm makepolicy example.chwall_ste.client_v1
=back
B<LOADING A SECURITY POLICY>
=over 4
This step activates client_v1.bin as new security policy in Xen. You
can use the dumppolicy subcommand before and afterwards to see the
change in the Xen policy state.
xm loadpolicy example.chwall_ste.client_v1
=back
B<CONFIGURING A BOOT SECURITY POLICY>
=over 4
This configures the boot loader to load client_v1.bin at boot
time. During system start, the ACM configures Xen with this policy and
Xen enforces this policy from then on.
xm cfgbootpolicy example.chwall_ste.client_v1
=back
B<LISTING SECURITY LABELS>
=over 4
This subcommand shows all labels that are defined and which can be
attached to domains.
xm labels example.chwall_ste.client_v1 type=dom
will print for our example policy:
dom_BoincClient
dom_Fun
dom_HomeBanking
dom_NetworkDomain
dom_StorageDomain
dom_SystemManagement
=back
B<ATTACHING A SECURITY LABEL TO A DOMAIN>
=over 4
This subcommand attaches a security label to a domain configuration
file, here a HomeBanking label. The example policy ensures that this
domain does not share information with other non-hombanking user
domains (i.e., domains labeled as dom_Fun or dom_Boinc) and that it
will not run simultaneously with domains labeled as dom_Fun.
We assume that the specified myconfig.xm configuration file actually
instantiates a domain that runs workloads related to home-banking,
probably just a browser environment for online-banking.
xm addlabel myconfig.xm dom_HomeBanking
The very simple configuration file might now look as printed
below. The I<addlabel> subcommand added the B<access_control> entry at
the end of the file, consisting of a label name and the policy that
specifies this label name:
kernel = "/boot/vmlinuz-2.6.16-xen"
ramdisk="/boot/U1_home_banking_ramdisk.img"
memory = 164
name = "homebanking"
vif = [ '' ]
dhcp = "dhcp"
access_control = ['policy=example.chwall_ste.client_v1,
label=dom_HomeBanking']
Security labels must be assigned to domain configurations because
these labels are essential for making access control decisions as
early as during the configuration phase of a newly instantiated
domain. Consequently, a security-enabled Xen hypervisor will only
start domains that have a security label configured and whose security
label is consistent with the currently enforced policy. Otherwise,
starting the domain will fail with the error condition "operation not
permitted".
=back
B<STARTING AND LISTING LABELED DOMAINS>
=over 4
xm create myconfig.xm
xm list --label
Name ID ... Time(s) Label
homebanking 23 ... 4.4 dom_HomeBanking
Domain-0 0 ... 2658.8 dom_SystemManagement
=back
B<POLICY REPRESENTATIONS>
=over 4
We distinguish three representations of the Xen access control policy:
the I<source XML> version, its I<binary> counterpart, and a I<mapping>
representation that enables the tools to deterministically translate
back and forth between label names of the XML policy and label
identifiers of the binary policy. All three versions must be kept
consistent to achieve predictable security guarantees.
The XML version is the version that users are supposed to create or
change, either by manually editing the XML file or by using the Xen
policy generation tool (B<xensec_gen>). After changing the XML file,
run the B<makepolicy> subcommand to ensure that these changes are
reflected in the other versions. Use, for example, the subcommand
B<cfgbootpolicy> to activate the changes during the next system
reboot.
The binary version of the policy is derived from the XML policy by
tokenizing the specified labels and is used inside Xen only. It is
created with the B<makepolicy> subcommand. Essentially, the binary
version is much more compact than the XML version and is easier to
evaluate during access control decisions.
The mapping version of the policy is created during the XML-to-binary
policy translation (B<makepolicy>) and is used by the Xen management
tools to translate between label names used as input to the tools and
their binary identifiers (ssidrefs) used inside Xen.
=back
=head1 EXAMPLES
=head1 SEE ALSO
@@ -791,5 +1059,6 @@ Operating Systems Review, pages 261-267
Sean Dague <sean at dague dot net>
Daniel Stekloff <dsteklof at us dot ibm dot com>
Reiner Sailer <sailer at us dot ibm dot com>
=head1 BUGS
+11 -14
View File
@@ -17,13 +17,8 @@ Development Prerequisites: An emulator for TESTING ONLY is provided
Compiling XEN tree:
-------------------
Compile the XEN tree as usual.
make uninstall; make mrproper; make install
After compiling the tree, verify that in the linux-2.6.XX-xen0/.config
file at least the following entries are set as below (they should be set
by default):
Compile the XEN tree as usual after the following lines set in the
linux-2.6.??-xen/.config file:
CONFIG_XEN_TPMDEV_BACKEND=y
CONFIG_XEN_TPMDEV_GRANT=y
@@ -32,18 +27,20 @@ CONFIG_TCG_TPM=m
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
You must also enable the virtual TPM to be built:
Verify that in the linux-2.6.XX-xenU/.config file at least the
Following entries are set as below (they should be set by default):
In Config.mk in the Xen root directory set the line
CONFIG_XEN_TPMDEV_FRONTEND=y
CONFIG_XEN_TPMDEV_GRANT=y
VTPM_TOOLS ?= y
CONFIG_TCG_TPM=y
CONFIG_TCG_XEN=y
Now build the Xen sources from Xen's root directory:
make install
Reboot the machine with the created XEN-0 kernel.
Also build the initial RAM disk if necessary.
Reboot the machine with the created Xen kernel.
Note: If you do not want any TPM-related code compiled into your
kernel or built as module then comment all the above lines like
+1 -2
View File
@@ -1983,8 +1983,7 @@ editing \path{grub.conf}.
kilobytes. In previous versions of Xen, suffixes were not supported
and the value is always interpreted as kilobytes.
\item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
pages (default 1). Note that the trace buffers are only enabled in
debug builds. Most users can ignore this feature completely.
pages (default 0).
\item [ sched=xxx ] Select the CPU scheduler Xen should use. The
current possibilities are `sedf' (default) and `bvt'.
\item [ apic\_verbosity=debug,verbose ] Print more detailed
-5
View File
@@ -1180,11 +1180,6 @@ config X86_NO_TSS
depends on X86_XEN
default y
config X86_SYSENTER
bool
depends on !X86_NO_TSS
default y
config X86_NO_IDT
bool
depends on X86_XEN
@@ -49,14 +49,12 @@ else
vsyscall_note := vsyscall-note.o
endif
VSYSCALL_TYPES-y := int80
VSYSCALL_TYPES-$(CONFIG_X86_SYSENTER) += sysenter
# vsyscall.o contains the vsyscall DSO images as __initdata.
# We must build both images before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/vsyscall.o: $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.so)
targets += $(foreach F,$(VSYSCALL_TYPES-y),vsyscall-$F.o vsyscall-$F.so)
targets += $(vsyscall_note) vsyscall.lds
$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
targets += vsyscall-note.o vsyscall.lds
# The DSO images are built using a special linker script.
quiet_cmd_syscall = SYSCALL $@
@@ -83,8 +81,7 @@ $(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
SYSCFLAGS_vsyscall-syms.o = -r
$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
$(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.o) \
$(obj)/$(vsyscall_note) FORCE
$(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
$(call if_changed,syscall)
ifdef CONFIG_XEN
@@ -64,10 +64,13 @@ void foo(void)
OFFSET(pbe_orig_address, pbe, orig_address);
OFFSET(pbe_next, pbe, next);
#ifdef CONFIG_X86_SYSENTER
#ifndef CONFIG_X86_NO_TSS
/* Offset from the sysenter stack to tss.esp0 */
DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) -
DEFINE(SYSENTER_stack_esp0, offsetof(struct tss_struct, esp0) -
sizeof(struct tss_struct));
#else
/* sysenter stack points directly to esp0 */
DEFINE(SYSENTER_stack_esp0, 0);
#endif
DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
@@ -202,13 +202,12 @@ need_resched:
jmp need_resched
#endif
#ifdef CONFIG_X86_SYSENTER
/* SYSENTER_RETURN points to after the "sysenter" instruction in
the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
# sysenter call handler stub
ENTRY(sysenter_entry)
movl TSS_sysenter_esp0(%esp),%esp
movl SYSENTER_stack_esp0(%esp),%esp
sysenter_past_esp:
sti
pushl $(__USER_DS)
@@ -240,7 +239,7 @@ sysenter_past_esp:
jae syscall_badsys
call *sys_call_table(,%eax,4)
movl %eax,EAX(%esp)
cli
DISABLE_INTERRUPTS
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx
jne syscall_exit_work
@@ -248,9 +247,23 @@ sysenter_past_esp:
movl EIP(%esp), %edx
movl OLDESP(%esp), %ecx
xorl %ebp,%ebp
#ifdef CONFIG_XEN
__ENABLE_INTERRUPTS
sysexit_scrit: /**** START OF SYSEXIT CRITICAL REGION ****/
__TEST_PENDING
jnz 14f # process more events if necessary...
movl ESI(%esp), %esi
sysexit
14: __DISABLE_INTERRUPTS
sysexit_ecrit: /**** END OF SYSEXIT CRITICAL REGION ****/
push %esp
call evtchn_do_upcall
add $4,%esp
jmp ret_from_intr
#else
sti
sysexit
#endif /* CONFIG_X86_SYSENTER */
#endif /* !CONFIG_XEN */
# system call handler stub
@@ -532,6 +545,11 @@ error_code:
# So, on entry to the handler we detect whether we interrupted an
# existing activation in its critical region -- if so, we pop the current
# activation and restart the handler using the previous one.
#
# The sysexit critical region is slightly different. sysexit
# atomically removes the entire stack frame. If we interrupt in the
# critical region we know that the entire frame is present and correct
# so we can simply throw away the new one.
ENTRY(hypervisor_callback)
pushl %eax
SAVE_ALL
@@ -540,6 +558,11 @@ ENTRY(hypervisor_callback)
jb 11f
cmpl $ecrit,%eax
jb critical_region_fixup
cmpl $sysexit_scrit,%eax
jb 11f
cmpl $sysexit_ecrit,%eax
ja 11f
addl $0x34,%esp # Remove cs...ebx from stack frame.
11: push %esp
call evtchn_do_upcall
add $4,%esp
@@ -683,13 +706,13 @@ device_available_emulate:
call math_state_restore
jmp ret_from_exception
#ifdef CONFIG_X86_SYSENTER
#ifndef CONFIG_XEN
/*
* Debug traps and NMI can happen at the one SYSENTER instruction
* that sets up the real kernel stack. Check here, since we can't
* allow the wrong stack to be used.
*
* "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
* "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
* already pushed 3 words if it hits on the sysenter instruction:
* eflags, cs and eip.
*
@@ -701,19 +724,19 @@ device_available_emulate:
cmpw $__KERNEL_CS,4(%esp); \
jne ok; \
label: \
movl TSS_sysenter_esp0+offset(%esp),%esp; \
movl SYSENTER_stack_esp0+offset(%esp),%esp; \
pushfl; \
pushl $__KERNEL_CS; \
pushl $sysenter_past_esp
#endif /* CONFIG_X86_SYSENTER */
#endif /* CONFIG_XEN */
KPROBE_ENTRY(debug)
#ifdef CONFIG_X86_SYSENTER
#ifndef CONFIG_XEN
cmpl $sysenter_entry,(%esp)
jne debug_stack_correct
FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
debug_stack_correct:
#endif /* !CONFIG_X86_SYSENTER */
#endif /* !CONFIG_XEN */
pushl $-1 # mark this as an int
SAVE_ALL
xorl %edx,%edx # error code 0
@@ -1205,7 +1205,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; *
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR;
physdev_op_t op;
BUG_ON(irq >= NR_IRQ_VECTORS);
@@ -1216,13 +1215,12 @@ int assign_irq_vector(int irq)
op.u.irq_op.irq = irq;
if (HYPERVISOR_physdev_op(&op))
return -ENOSPC;
current_vector = op.u.irq_op.vector;
vector_irq[current_vector] = irq;
vector_irq[op.u.irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
IO_APIC_VECTOR(irq) = current_vector;
IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
return current_vector;
return op.u.irq_op.vector;
}
#ifndef CONFIG_XEN
@@ -2485,6 +2483,12 @@ static int __init io_apic_bug_finalize(void)
{
if(sis_apic_bug == -1)
sis_apic_bug = 0;
if (xen_start_info->flags & SIF_INITDOMAIN) {
dom0_op_t op = { .cmd = DOM0_PLATFORM_QUIRK };
op.u.platform_quirk.quirk_id = sis_apic_bug ?
QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
HYPERVISOR_dom0_op(&op);
}
return 0;
}
@@ -20,11 +20,15 @@
#include <asm/pgtable.h>
#include <asm/unistd.h>
#ifdef CONFIG_XEN
#include <xen/interface/callback.h>
#endif
extern asmlinkage void sysenter_entry(void);
void enable_sep_cpu(void)
{
#ifdef CONFIG_X86_SYSENTER
#ifndef CONFIG_X86_NO_TSS
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
@@ -54,14 +58,24 @@ int __init sysenter_setup(void)
{
syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
#ifdef CONFIG_X86_SYSENTER
#ifdef CONFIG_XEN
if (boot_cpu_has(X86_FEATURE_SEP)) {
struct callback_register sysenter = {
.type = CALLBACKTYPE_sysenter,
.address = { __KERNEL_CS, (unsigned long)sysenter_entry },
};
if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0)
clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
}
#endif
if (boot_cpu_has(X86_FEATURE_SEP)) {
memcpy(syscall_page,
&vsyscall_sysenter_start,
&vsyscall_sysenter_end - &vsyscall_sysenter_start);
return 0;
}
#endif
memcpy(syscall_page,
&vsyscall_int80_start,
@@ -7,11 +7,9 @@ vsyscall_int80_start:
.incbin "arch/i386/kernel/vsyscall-int80.so"
vsyscall_int80_end:
#ifdef CONFIG_X86_SYSENTER
.globl vsyscall_sysenter_start, vsyscall_sysenter_end
vsyscall_sysenter_start:
.incbin "arch/i386/kernel/vsyscall-sysenter.so"
vsyscall_sysenter_end:
#endif
__FINIT
@@ -306,14 +306,14 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
BUG_ON(rc);
}
if (HAVE_SHARED_KERNEL_PMD)
memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
KERNEL_PGD_PTRS);
} else {
spin_lock_irqsave(&pgd_lock, flags);
memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
swapper_pg_dir + USER_PTRS_PER_PGD,
KERNEL_PGD_PTRS);
memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
pgd_list_add(pgd);
spin_unlock_irqrestore(&pgd_lock, flags);
@@ -360,7 +360,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
if (!pmd)
goto out_oom;
set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
}
spin_lock_irqsave(&pgd_lock, flags);
@@ -35,8 +35,9 @@ static void xenoprof_stop(void);
void * vm_map_xen_pages(unsigned long maddr, int vm_size, pgprot_t prot);
static int xenoprof_enabled = 0;
static int num_events = 0;
static unsigned int num_events = 0;
static int is_primary = 0;
static int active_defined;
/* sample buffers shared with Xen */
xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
@@ -106,7 +107,7 @@ static irqreturn_t
xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
int head, tail, size;
xenoprof_buf_t * buf;
struct xenoprof_buf * buf;
int cpu;
cpu = smp_processor_id();
@@ -196,28 +197,49 @@ static int bind_virq(void)
static int xenoprof_setup(void)
{
int ret;
int i;
ret = bind_virq();
if (ret)
return ret;
if (is_primary) {
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters,
(unsigned long)NULL,
(unsigned long)NULL);
struct xenoprof_counter counter;
/* Define dom0 as an active domain if not done yet */
if (!active_defined) {
domid_t domid;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
goto err;
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
goto err;
active_defined = 1;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL);
if (ret)
goto err;
for (i=0; i<num_events; i++) {
counter.ind = i;
counter.count = (uint64_t)counter_config[i].count;
counter.enabled = (uint32_t)counter_config[i].enabled;
counter.event = (uint32_t)counter_config[i].event;
counter.kernel = (uint32_t)counter_config[i].kernel;
counter.user = (uint32_t)counter_config[i].user;
counter.unit_mask = (uint64_t)counter_config[i].unit_mask;
HYPERVISOR_xenoprof_op(XENOPROF_counter,
&counter);
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events, NULL);
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events,
(unsigned long)&counter_config,
(unsigned long)num_events);
if (ret)
goto err;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq,
(unsigned long)NULL,
(unsigned long)NULL);
ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq, NULL);
if (ret)
goto err;
@@ -233,17 +255,15 @@ static void xenoprof_shutdown(void)
{
xenoprof_enabled = 0;
HYPERVISOR_xenoprof_op(XENOPROF_disable_virq,
(unsigned long)NULL,
(unsigned long)NULL);
HYPERVISOR_xenoprof_op(XENOPROF_disable_virq, NULL);
if (is_primary) {
HYPERVISOR_xenoprof_op(XENOPROF_release_counters,
(unsigned long)NULL,
(unsigned long)NULL);
HYPERVISOR_xenoprof_op(XENOPROF_release_counters, NULL);
active_defined = 0;
}
unbind_virq();
}
@@ -252,9 +272,8 @@ static int xenoprof_start(void)
int ret = 0;
if (is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_start,
(unsigned long)NULL,
(unsigned long)NULL);
ret = HYPERVISOR_xenoprof_op(XENOPROF_start, NULL);
return ret;
}
@@ -262,20 +281,43 @@ static int xenoprof_start(void)
static void xenoprof_stop(void)
{
if (is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_stop,
(unsigned long)NULL,
(unsigned long)NULL);
HYPERVISOR_xenoprof_op(XENOPROF_stop, NULL);
}
static int xenoprof_set_active(int * active_domains,
unsigned int adomains)
unsigned int adomains)
{
int ret = 0;
if (is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active,
(unsigned long)active_domains,
(unsigned long)adomains);
int i;
int set_dom0 = 0;
domid_t domid;
if (!is_primary)
return 0;
if (adomains > MAX_OPROF_DOMAINS)
return -E2BIG;
ret = HYPERVISOR_xenoprof_op(XENOPROF_reset_active_list, NULL);
if (ret)
return ret;
for (i=0; i<adomains; i++) {
domid = active_domains[i];
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
if (ret)
return (ret);
if (active_domains[i] == 0)
set_dom0 = 1;
}
/* dom0 must always be active but may not be in the list */
if (!set_dom0) {
domid = 0;
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active, &domid);
}
active_defined = 1;
return ret;
}
@@ -325,44 +367,48 @@ static int using_xenoprof;
int __init oprofile_arch_init(struct oprofile_operations * ops)
{
xenoprof_init_result_t result;
xenoprof_buf_t * buf;
int max_samples = 16;
struct xenoprof_init init;
struct xenoprof_buf * buf;
int vm_size;
int npages;
int ret;
int i;
int ret = HYPERVISOR_xenoprof_op(XENOPROF_init,
(unsigned long)max_samples,
(unsigned long)&result);
init.max_samples = 16;
ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init);
if (!ret) {
pgprot_t prot = __pgprot(_KERNPG_TABLE);
num_events = result.num_events;
is_primary = result.is_primary;
nbuf = result.nbuf;
num_events = init.num_events;
is_primary = init.is_primary;
nbuf = init.nbuf;
npages = (result.bufsize * nbuf - 1) / PAGE_SIZE + 1;
/* just in case - make sure we do not overflow event list
(i.e. counter_config list) */
if (num_events > OP_MAX_COUNTER)
num_events = OP_MAX_COUNTER;
npages = (init.bufsize * nbuf - 1) / PAGE_SIZE + 1;
vm_size = npages * PAGE_SIZE;
shared_buffer = (char *) vm_map_xen_pages(result.buf_maddr,
vm_size, prot);
shared_buffer = (char *)vm_map_xen_pages(init.buf_maddr,
vm_size, prot);
if (!shared_buffer) {
ret = -ENOMEM;
goto out;
}
for (i=0; i< nbuf; i++) {
buf = (xenoprof_buf_t*)
&shared_buffer[i * result.bufsize];
buf = (struct xenoprof_buf*)
&shared_buffer[i * init.bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
xenoprof_buf[buf->vcpu_id] = buf;
}
/* cpu_type is detected by Xen */
cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
strncpy(cpu_type, result.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
strncpy(cpu_type, init.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
xenoprof_ops.cpu_type = cpu_type;
init_driverfs();
@@ -371,6 +417,8 @@ int __init oprofile_arch_init(struct oprofile_operations * ops)
for (i=0; i<NR_CPUS; i++)
ovf_irq[i] = -1;
active_defined = 0;
}
out:
printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
@@ -389,7 +437,5 @@ void __exit oprofile_arch_exit(void)
shared_buffer = NULL;
}
if (is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_shutdown,
(unsigned long)NULL,
(unsigned long)NULL);
HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL);
}
@@ -869,7 +869,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR;
physdev_op_t op;
BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
@@ -880,13 +879,12 @@ int assign_irq_vector(int irq)
op.u.irq_op.irq = irq;
if (HYPERVISOR_physdev_op(&op))
return -ENOSPC;
current_vector = op.u.irq_op.vector;
vector_irq[current_vector] = irq;
vector_irq[op.u.irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
IO_APIC_VECTOR(irq) = current_vector;
IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
return current_vector;
return op.u.irq_op.vector;
}
extern void (*interrupt[NR_IRQS])(void);
@@ -11,6 +11,8 @@
#include <xen/xenbus.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <xen/interface/io/pciif.h>
struct pci_dev_entry {
@@ -18,6 +20,9 @@ struct pci_dev_entry {
struct pci_dev *dev;
};
#define _PDEVF_op_active (0)
#define PDEVF_op_active (1<<(_PDEVF_op_active))
struct pciback_device {
void *pci_dev_data;
spinlock_t dev_lock;
@@ -29,7 +34,12 @@ struct pciback_device {
int evtchn_irq;
struct vm_struct *sh_area;
struct xen_pci_sharedinfo *sh_info;
unsigned long flags;
struct work_struct op_work;
};
struct pciback_dev_data {
@@ -70,6 +80,7 @@ void pciback_release_devices(struct pciback_device *pdev);
/* Handles events from front-end */
irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
void pciback_do_op(void *data);
int pciback_xenbus_register(void);
void pciback_xenbus_unregister(void);
@@ -40,18 +40,25 @@ void pciback_reset_device(struct pci_dev *dev)
pciback_config_reset(dev);
}
irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
static inline void test_and_schedule_op(struct pciback_device *pdev)
{
struct pciback_device *pdev = dev_id;
/* Check that frontend is requesting an operation and that we are not
* already processing a request */
if (test_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)
&& !test_and_set_bit(_PDEVF_op_active, &pdev->flags))
schedule_work(&pdev->op_work);
}
/* Performing the configuration space reads/writes must not be done in atomic
* context because some of the pci_* functions can sleep (mostly due to ACPI
* use of semaphores). This function is intended to be called from a work
* queue in process context taking a struct pciback_device as a parameter */
void pciback_do_op(void *data)
{
struct pciback_device *pdev = data;
struct pci_dev *dev;
struct xen_pci_op *op = &pdev->sh_info->op;
if (unlikely(!test_bit(_XEN_PCIF_active,
(unsigned long *)&pdev->sh_info->flags))) {
pr_debug("pciback: interrupt, but no active operation\n");
goto out;
}
dev = pciback_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
if (dev == NULL)
@@ -65,10 +72,26 @@ irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
else
op->err = XEN_PCI_ERR_not_implemented;
/* Tell the driver domain that we're done. */
wmb();
clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
notify_remote_via_irq(pdev->evtchn_irq);
out:
/* Mark that we're done. */
smp_mb__before_clear_bit(); /* /after/ clearing PCIF_active */
clear_bit(_PDEVF_op_active, &pdev->flags);
smp_mb__after_clear_bit(); /* /before/ final check for work */
/* Check to see if the driver domain tried to start another request in
* between clearing _XEN_PCIF_active and clearing _PDEVF_op_active. */
test_and_schedule_op(pdev);
}
irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
{
struct pciback_device *pdev = dev_id;
test_and_schedule_op(pdev);
return IRQ_HANDLED;
}
@@ -26,10 +26,13 @@ static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
spin_lock_init(&pdev->dev_lock);
pdev->sh_area = NULL;
pdev->sh_info = NULL;
pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
pdev->be_watching = 0;
INIT_WORK(&pdev->op_work, pciback_do_op, pdev);
if (pciback_init_devices(pdev)) {
kfree(pdev);
pdev = NULL;
@@ -47,8 +50,13 @@ static void free_pdev(struct pciback_device *pdev)
if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ)
unbind_from_irqhandler(pdev->evtchn_irq, pdev);
/* If the driver domain started an op, make sure we complete it or
* delete it before releasing the shared memory */
cancel_delayed_work(&pdev->op_work);
flush_scheduled_work();
if (pdev->sh_info)
xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info);
xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_area);
pciback_release_devices(pdev);
@@ -63,15 +71,19 @@ static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
{
int err = 0;
int evtchn;
struct vm_struct *area;
dev_dbg(&pdev->xdev->dev,
"Attaching to frontend resources - gnt_ref=%d evtchn=%d\n",
gnt_ref, remote_evtchn);
err =
xenbus_map_ring_valloc(pdev->xdev, gnt_ref,
(void **)&pdev->sh_info);
if (err)
area = xenbus_map_ring_valloc(pdev->xdev, gnt_ref);
if (IS_ERR(area)) {
err = PTR_ERR(area);
goto out;
}
pdev->sh_area = area;
pdev->sh_info = area->addr;
err = xenbus_bind_evtchn(pdev->xdev, remote_evtchn, &evtchn);
if (err)
@@ -49,6 +49,7 @@ typedef struct tpmif_st {
grant_handle_t shmem_handle;
grant_ref_t shmem_ref;
struct page *pagerange;
} tpmif_t;
void tpmif_disconnect_complete(tpmif_t * tpmif);
@@ -22,7 +22,6 @@ LIST_HEAD(tpmif_list);
static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
{
struct page *page;
tpmif_t *tpmif;
tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
@@ -35,9 +34,10 @@ static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
tpmif->tpm_instance = instance;
atomic_set(&tpmif->refcnt, 1);
page = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
BUG_ON(page == NULL);
tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE);
BUG_ON(tpmif->pagerange == NULL);
tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr(
page_to_pfn(tpmif->pagerange));
list_add(&tpmif->tpmif_list, &tpmif_list);
num_frontends++;
@@ -49,6 +49,7 @@ static void free_tpmif(tpmif_t * tpmif)
{
num_frontends--;
list_del(&tpmif->tpmif_list);
balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE);
kmem_cache_free(tpmif_cachep, tpmif);
}
@@ -115,11 +116,11 @@ int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.remote_dom = tpmif->domid,
.u.bind_interdomain.remote_port = evtchn,
};
};
if (tpmif->irq) {
return 0;
}
if (tpmif->irq) {
return 0;
}
if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -271,6 +271,7 @@ int _packet_write(struct packet *pak,
struct gnttab_map_grant_ref map_op;
struct gnttab_unmap_grant_ref unmap_op;
tpmif_tx_request_t *tx;
unsigned long pfn, mfn, mfn_orig;
tx = &tpmif->tx->ring[i].req;
@@ -293,9 +294,12 @@ int _packet_write(struct packet *pak,
DPRINTK(" Grant table operation failure !\n");
return 0;
}
set_phys_to_machine(__pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT,
FOREIGN_FRAME(map_op.
dev_bus_addr >> PAGE_SHIFT));
pfn = __pa(MMAP_VADDR(tpmif, i)) >> PAGE_SHIFT;
mfn = FOREIGN_FRAME(map_op.dev_bus_addr >> PAGE_SHIFT);
mfn_orig = phys_to_machine_mapping[pfn];
set_phys_to_machine(pfn, mfn);
tocopy = MIN(size - offset, PAGE_SIZE);
@@ -307,6 +311,8 @@ int _packet_write(struct packet *pak,
}
tx->size = tocopy;
set_phys_to_machine(pfn, mfn_orig);
gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i),
GNTMAP_host_map, handle);
@@ -49,6 +49,8 @@ static int tpmback_remove(struct xenbus_device *dev)
{
struct backend_info *be = dev->data;
if (!be) return 0;
if (be->backend_watch.node) {
unregister_xenbus_watch(&be->backend_watch);
kfree(be->backend_watch.node);
@@ -119,37 +121,9 @@ static void backend_changed(struct xenbus_watch *watch,
return;
}
if (be->is_instance_set != 0 && be->instance != instance) {
printk(KERN_WARNING
"tpmback: changing instance (from %ld to %ld) "
"not allowed.\n",
be->instance, instance);
return;
}
if (be->is_instance_set == 0) {
be->tpmif = tpmif_find(dev->otherend_id,
instance);
if (IS_ERR(be->tpmif)) {
err = PTR_ERR(be->tpmif);
be->tpmif = NULL;
xenbus_dev_fatal(dev,err,"creating block interface");
return;
}
be->instance = instance;
be->is_instance_set = 1;
/*
* There's an unfortunate problem:
* Sometimes after a suspend/resume the
* state switch to XenbusStateInitialised happens
* *before* I get to this point here. Since then
* the connect_ring() must have failed (be->tpmif is
* still NULL), I just call it here again indirectly.
*/
if (be->frontend_state == XenbusStateInitialised) {
frontend_changed(dev, be->frontend_state);
}
}
}
@@ -186,6 +160,7 @@ static void frontend_changed(struct xenbus_device *dev,
*/
tpmif_vtpm_close(be->instance);
device_unregister(&be->dev->dev);
tpmback_remove(dev);
break;
case XenbusStateUnknown:
@@ -279,6 +254,18 @@ static int connect_ring(struct backend_info *be)
dev->otherend);
return err;
}
if (!be->tpmif) {
be->tpmif = tpmif_find(dev->otherend_id,
be->instance);
if (IS_ERR(be->tpmif)) {
err = PTR_ERR(be->tpmif);
be->tpmif = NULL;
xenbus_dev_fatal(dev,err,"creating vtpm interface");
return err;
}
}
if (be->tpmif != NULL) {
err = tpmif_map(be->tpmif, ring_ref, evtchn);
if (err) {
@@ -30,21 +30,20 @@
* IN THE SOFTWARE.
*/
#include <linux/err.h>
#include <xen/gnttab.h>
#include <xen/xenbus.h>
#include <xen/driver_util.h>
/* Based on Rusty Russell's skeleton driver's map_page */
int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref)
{
struct gnttab_map_grant_ref op;
struct vm_struct *area;
*vaddr = NULL;
area = alloc_vm_area(PAGE_SIZE);
if (!area)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
gnttab_set_map_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
gnt_ref, dev->otherend_id);
@@ -58,14 +57,14 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
xenbus_dev_fatal(dev, op.status,
"mapping in shared page %d from domain %d",
gnt_ref, dev->otherend_id);
return op.status;
BUG_ON(!IS_ERR(ERR_PTR(op.status)));
return ERR_PTR(op.status);
}
/* Stuff the handle in an unused field */
area->phys_addr = (unsigned long)op.handle;
*vaddr = area->addr;
return 0;
return area;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
@@ -92,31 +91,11 @@ EXPORT_SYMBOL_GPL(xenbus_map_ring);
/* Based on Rusty Russell's skeleton driver's unmap_page */
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *area)
{
struct vm_struct *area;
struct gnttab_unmap_grant_ref op;
/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
* method so that we don't have to muck with vmalloc internals here.
* We could force the user to hang on to their struct vm_struct from
* xenbus_map_ring_valloc, but these 6 lines considerably simplify
* this API.
*/
read_lock(&vmlist_lock);
for (area = vmlist; area != NULL; area = area->next) {
if (area->addr == vaddr)
break;
}
read_unlock(&vmlist_lock);
if (!area) {
xenbus_dev_error(dev, -ENOENT,
"can't find mapped virtual address %p", vaddr);
return GNTST_bad_virt_addr;
}
gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map,
gnttab_set_unmap_op(&op, (unsigned long)area->addr, GNTMAP_host_map,
(grant_handle_t)area->phys_addr);
lock_vm_area(area);
@@ -338,9 +338,9 @@ HYPERVISOR_callback_op(
static inline int
HYPERVISOR_xenoprof_op(
int op, unsigned long arg1, unsigned long arg2)
int op, void *arg)
{
return _hypercall3(int, xenoprof_op, op, arg1, arg2);
return _hypercall2(int, xenoprof_op, op, arg);
}
@@ -497,13 +497,11 @@ struct thread_struct {
static inline void __load_esp0(struct tss_struct *tss, struct thread_struct *thread)
{
tss->esp0 = thread->esp0;
#ifdef CONFIG_X86_SYSENTER
/* This can only happen when SEP is enabled, no need to test "SEP"arately */
if (unlikely(tss->ss1 != thread->sysenter_cs)) {
tss->ss1 = thread->sysenter_cs;
wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
}
#endif
}
#define load_esp0(tss, thread) \
__load_esp0(tss, thread)
@@ -24,6 +24,7 @@ extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
int ret;
struct xen_platform_parameters pp;
struct callback_register event = {
.type = CALLBACKTYPE_event,
@@ -33,7 +34,10 @@ static void __init machine_specific_arch_setup(void)
.type = CALLBACKTYPE_failsafe,
.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
};
struct xennmi_callback cb;
struct callback_register nmi_cb = {
.type = CALLBACKTYPE_nmi,
.address = { __KERNEL_CS, (unsigned long)nmi },
};
if (xen_feature(XENFEAT_auto_translated_physmap) &&
xen_start_info->shared_info < xen_start_info->nr_pages) {
@@ -42,11 +46,22 @@ static void __init machine_specific_arch_setup(void)
memset(empty_zero_page, 0, sizeof(empty_zero_page));
}
HYPERVISOR_callback_op(CALLBACKOP_register, &event);
HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
if (ret == 0)
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
if (ret == -ENOSYS)
ret = HYPERVISOR_set_callbacks(
event.address.cs, event.address.eip,
failsafe.address.cs, failsafe.address.eip);
BUG_ON(ret);
cb.handler_address = (unsigned long)&nmi;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
if (ret == -ENOSYS) {
struct xennmi_callback cb;
cb.handler_address = nmi_cb.address.eip;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
}
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
&pp) == 0)
@@ -14,6 +14,7 @@ extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
int ret;
struct callback_register event = {
.type = CALLBACKTYPE_event,
.address = (unsigned long) hypervisor_callback,
@@ -27,15 +28,31 @@ static void __init machine_specific_arch_setup(void)
.address = (unsigned long)system_call,
};
#ifdef CONFIG_X86_LOCAL_APIC
struct xennmi_callback cb;
struct callback_register nmi_cb = {
.type = CALLBACKTYPE_nmi,
.address = (unsigned long)nmi,
};
#endif
HYPERVISOR_callback_op(CALLBACKOP_register, &event);
HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
if (ret == 0)
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
if (ret == 0)
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
if (ret == -ENOSYS)
ret = HYPERVISOR_set_callbacks(
event.address,
failsafe.address,
syscall.address);
BUG_ON(ret);
#ifdef CONFIG_X86_LOCAL_APIC
cb.handler_address = (unsigned long)&nmi;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
if (ret == -ENOSYS) {
struct xennmi_callback cb;
cb.handler_address = nmi_cb.address;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
}
#endif
}
+3 -3
View File
@@ -228,8 +228,8 @@ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
* or -ENOMEM on error. If an error is returned, device will switch to
* XenbusStateClosing and the error message will be saved in XenStore.
*/
int xenbus_map_ring_valloc(struct xenbus_device *dev,
int gnt_ref, void **vaddr);
struct vm_struct *xenbus_map_ring_valloc(struct xenbus_device *dev,
int gnt_ref);
int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
grant_handle_t *handle, void *vaddr);
@@ -241,7 +241,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
* Returns 0 on success and returns GNTST_* on error
* (see xen/include/interface/grant_table.h).
*/
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, struct vm_struct *);
int xenbus_unmap_ring(struct xenbus_device *dev,
grant_handle_t handle, void *vaddr);
+1 -1
View File
@@ -405,7 +405,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_
* Remove this test eventually!
*/
if (unlikely(!pfn_valid(pfn))) {
if (!vma->vm_flags & VM_RESERVED)
if (!(vma->vm_flags & VM_RESERVED))
print_bad_pte(vma, pte, addr);
return NULL;
}
+44 -32
View File
@@ -1220,6 +1220,43 @@ int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
} \
}
#ifdef CONFIG_XEN
inline int skb_checksum_setup(struct sk_buff *skb)
{
if (skb->proto_csum_blank) {
if (skb->protocol != htons(ETH_P_IP))
goto out;
skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
if (skb->h.raw >= skb->tail)
goto out;
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
skb->csum = offsetof(struct tcphdr, check);
break;
case IPPROTO_UDP:
skb->csum = offsetof(struct udphdr, check);
break;
default:
if (net_ratelimit())
printk(KERN_ERR "Attempting to checksum a non-"
"TCP/UDP packet, dropping a protocol"
" %d packet", skb->nh.iph->protocol);
goto out;
}
if ((skb->h.raw + skb->csum + 2) > skb->tail)
goto out;
skb->ip_summed = CHECKSUM_HW;
skb->proto_csum_blank = 0;
}
return 0;
out:
return -EPROTO;
}
#else
inline int skb_checksum_setup(struct sk_buff *skb) { return 0; }
#endif
/**
* dev_queue_xmit - transmit a buffer
* @skb: buffer to transmit
@@ -1266,38 +1303,12 @@ int dev_queue_xmit(struct sk_buff *skb)
__skb_linearize(skb, GFP_ATOMIC))
goto out_kfree_skb;
#ifdef CONFIG_XEN
/* If a checksum-deferred packet is forwarded to a device that needs a
* checksum, correct the pointers and force checksumming.
*/
if (skb->proto_csum_blank) {
if (skb->protocol != htons(ETH_P_IP))
goto out_kfree_skb;
skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
if (skb->h.raw >= skb->tail)
goto out_kfree_skb;
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
skb->csum = offsetof(struct tcphdr, check);
break;
case IPPROTO_UDP:
skb->csum = offsetof(struct udphdr, check);
break;
default:
if (net_ratelimit())
printk(KERN_ERR "Attempting to checksum a non-"
"TCP/UDP packet, dropping a protocol"
" %d packet", skb->nh.iph->protocol);
rc = -EPROTO;
goto out_kfree_skb;
}
if ((skb->h.raw + skb->csum + 2) > skb->tail)
goto out_kfree_skb;
skb->ip_summed = CHECKSUM_HW;
skb->proto_csum_blank = 0;
}
#endif
/* If a checksum-deferred packet is forwarded to a device that needs a
* checksum, correct the pointers and force checksumming.
*/
if(skb_checksum_setup(skb))
goto out_kfree_skb;
/* If packet is not checksummed and device does not support
* checksumming for this protocol, complete checksumming here.
*/
@@ -3351,6 +3362,7 @@ EXPORT_SYMBOL(unregister_netdevice_notifier);
EXPORT_SYMBOL(net_enable_timestamp);
EXPORT_SYMBOL(net_disable_timestamp);
EXPORT_SYMBOL(dev_get_flags);
EXPORT_SYMBOL(skb_checksum_setup);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
EXPORT_SYMBOL(br_handle_frame_hook);
+23
View File
@@ -39,3 +39,26 @@ diff -pruN ../pristine-linux-2.6.16/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/
*portptr = newport;
return 1;
}
diff -r 601fa226a761 net/ipv4/xfrm4_output.c
--- a/net/ipv4/xfrm4_output.c Wed Apr 19 18:52:30 2006
+++ b/net/ipv4/xfrm4_output.c Thu Apr 20 15:49:40 2006
@@ -16,6 +16,8 @@
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/icmp.h>
+
+extern int skb_checksum_setup(struct sk_buff *skb);
/* Add encapsulation header.
*
@@ -103,6 +105,10 @@
struct xfrm_state *x = dst->xfrm;
int err;
+ err = skb_checksum_setup(skb);
+ if (err)
+ goto error_nolock;
+
if (skb->ip_summed == CHECKSUM_HW) {
err = skb_checksum_help(skb, 0);
if (err)
@@ -0,0 +1,31 @@
Index: sysenter/linux-2.6-xen-sparse/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.16.orig/arch/i386/kernel/entry.S 2006-04-05 11:12:51.000000000 +0100
+++ linux-2.6.16/arch/i386/kernel/entry.S 2006-04-05 11:12:52.000000000 +0100
@@ -177,7 +177,7 @@
# sysenter call handler stub
ENTRY(sysenter_entry)
- movl TSS_sysenter_esp0(%esp),%esp
+ movl SYSENTER_stack_esp0(%esp),%esp
sysenter_past_esp:
sti
pushl $(__USER_DS)
@@ -492,7 +492,7 @@
* that sets up the real kernel stack. Check here, since we can't
* allow the wrong stack to be used.
*
- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
* already pushed 3 words if it hits on the sysenter instruction:
* eflags, cs and eip.
*
@@ -504,7 +504,7 @@
cmpw $__KERNEL_CS,4(%esp); \
jne ok; \
label: \
- movl TSS_sysenter_esp0+offset(%esp),%esp; \
+ movl SYSENTER_stack_esp0+offset(%esp),%esp; \
pushfl; \
pushl $__KERNEL_CS; \
pushl $sysenter_past_esp
@@ -664,17 +664,13 @@ main (int argc, char *argv[])
For the traditional remote protocol close the connection,
and re-open it at the top of the loop. */
if (extended_protocol)
{
remote_close ();
detach_inferior ();
remote_close ();
if (extended_protocol)
exit (0);
}
else
{
else
fprintf (stderr, "Remote side has terminated connection. "
"GDBserver will reopen the connection.\n");
remote_close ();
}
sigaction(SIGINT, &old_sigaction, NULL);
}
}
+2
View File
@@ -28,9 +28,11 @@ XEN_SCRIPTS += block
XEN_SCRIPTS += block-enbd block-nbd
XEN_SCRIPTS += vtpm vtpm-delete
XEN_SCRIPTS += xen-hotplug-cleanup
XEN_SCRIPTS += external-device-migrate
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
XEN_SCRIPT_DATA += vtpm-migration.sh
XEN_HOTPLUG_DIR = /etc/hotplug
XEN_HOTPLUG_SCRIPTS = xen-backend.agent
+85
View File
@@ -0,0 +1,85 @@
#!/bin/sh
# Copyright (c) 2005 IBM Corporation
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# This script is called by XenD for migration of external devices
# It does not handle the migration of those devices itself, but
# passes the requests on to further applications
# It handles the low-level command line parsing and some of the
# synchronization
dir=$(dirname "$0")
. "$dir/logging.sh"
function usage() {
echo " Pass the following command line paremeters to the script:"
echo ""
echo "-step <n> : n-th migration step"
echo "-host <host> : the destination host"
echo "-domname <domain name> : name of the domain that is migrating"
echo "-type <device type> : the type of device that is migrating"
echo "-recover : indicates recovery request; an error"
echo " occurred during migration"
echo "-help : display this help screen"
}
while [ 1 ]; do
if [ "$1" == "-step" ]; then
shift
step=$1
elif [ "$1" == "-host" ]; then
shift
host=$1
elif [ "$1" == "-domname" ]; then
shift
domname=$1
elif [ "$1" == "-type" ]; then
shift
typ=$1
elif [ "$1" == "-recover" ]; then
recover=1
elif [ "$1" == "-help" ]; then
usage
exit
else
break
fi
shift
done
if [ "$step" == "" -o \
"$host" == "" -o \
"$typ" == "" -o \
"$domname" == "" ]; then
echo "Error: Parameter(s) missing (-step/-host/-type/-domname)"
set
echo ""
echo "$0 --help for usage."
exit
fi
. "$dir/$typ-migration.sh"
if [ "$recover" == "1" ]; then
func="$typ"_recover
eval $func $host $domname $step
else
func="$typ"_migration_step
eval $func $host $domname $step
fi
+75 -10
View File
@@ -48,6 +48,12 @@ if [ -z "$VTPM_IMPL_DEFINED" ]; then
function vtpm_delete() {
true
}
function vtpm_migrate() {
echo "Error: vTPM migration accross machines not implemented."
}
function vtpm_migrate_recover() {
true
}
fi
@@ -60,7 +66,7 @@ fi
function vtpmdb_find_instance () {
local vmname=$1
local ret=0
instance=`cat $VTPMDB | \
instance=$(cat $VTPMDB | \
awk -vvmname=$vmname \
'{ \
if ( 1 != index($1,"#")) { \
@@ -69,7 +75,7 @@ function vtpmdb_find_instance () {
exit; \
} \
} \
}'`
}')
if [ "$instance" != "" ]; then
ret=$instance
fi
@@ -86,13 +92,13 @@ function vtpmdb_is_free_instancenum () {
if [ $instance -eq 0 -o $instance -gt 255 ]; then
avail=0
else
instances=`cat $VTPMDB | \
instances=$(cat $VTPMDB | \
gawk \
'{ \
if (1 != index($1,"#")) { \
printf("%s ",$2); \
} \
}'`
}')
for i in $instances; do
if [ $i -eq $instance ]; then
avail=0
@@ -110,13 +116,13 @@ function vtpmdb_get_free_instancenum () {
local ctr
local instances
local don
instances=`cat $VTPMDB | \
instances=$(cat $VTPMDB | \
gawk \
'{ \
if (1 != index($1,"#")) { \
printf("%s ",$2); \
} \
}'`
}')
ctr=1
don=0
while [ $don -eq 0 ]; do
@@ -163,7 +169,7 @@ function vtpmdb_validate_entry () {
local vmname=$1
local inst=$2
res=`cat $VTPMDB | \
res=$(cat $VTPMDB | \
gawk -vvmname=$vmname \
-vinst=$inst \
'{ \
@@ -179,7 +185,7 @@ function vtpmdb_validate_entry () {
printf("2"); \
exit; \
} \
}'`
}')
if [ "$res" == "1" ]; then
let rc=1
@@ -196,13 +202,13 @@ function vtpmdb_remove_entry () {
local vmname=$1
local instance=$2
local VTPMDB_TMP="$VTPMDB".tmp
`cat $VTPMDB | \
$(cat $VTPMDB | \
gawk -vvmname=$vmname \
'{ \
if ( $1 != vmname ) { \
print $0; \
} \
'} > $VTPMDB_TMP`
'} > $VTPMDB_TMP)
if [ -e $VTPMDB_TMP ]; then
mv -f $VTPMDB_TMP $VTPMDB
vtpm_delete $instance
@@ -300,3 +306,62 @@ function vtpm_delete_instance () {
release_lock vtpmdb
}
# Determine whether the given address is local to this machine
# Return values:
# "-1" : the given machine name is invalid
# "0" : this is not an address of this machine
# "1" : this is an address local to this machine
function isLocalAddress() {
local addr=$(ping $1 -c 1 | \
gawk '{ print substr($3,2,length($3)-2); exit }')
if [ "$addr" == "" ]; then
echo "-1"
return
fi
local res=$(ifconfig | grep "inet addr" | \
gawk -vaddr=$addr \
'{ \
if ( addr == substr($2, 6)) {\
print "1"; \
} \
}' \
)
if [ "$res" == "" ]; then
echo "0"
return
fi
echo "1"
}
# Perform a migration step. This function differentiates between migration
# to the local host or to a remote machine.
# Parameters:
# 1st: destination host to migrate to
# 2nd: name of the domain to migrate
# 3rd: the migration step to perform
function vtpm_migration_step() {
local instance=$(vtpmdb_find_instance $2)
if [ "$instance" == "" ]; then
echo "Error: Translation of domain name ($2) to instance failed. Check /etc/xen/vtpm.db"
log err "Error during translation of domain name"
else
res=$(isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate $1 $2 $3
fi
fi
}
# Recover from migration due to an error. This function differentiates
# between migration to the local host or to a remote machine.
# Parameters:
# 1st: destination host the migration was going to
# 2nd: name of the domain that was to be migrated
# 3rd: the last successful migration step that was done
function vtpm_recover() {
res=$(isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate_recover $1 $2 $3
fi
}
+19
View File
@@ -0,0 +1,19 @@
#
# Copyright (c) 2005 IBM Corporation
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
dir=$(dirname "$0")
. "$dir/vtpm-common.sh"
+4
View File
@@ -21,6 +21,10 @@ kernel = "/usr/lib/xen/boot/hvmloader"
builder='hvm'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
# A name for your domain. All domains must have different names.
+5
View File
@@ -10,7 +10,12 @@
kernel = "/boot/vmlinuz-2.6.13-15b-xen"
ramdisk = "/boot/initrd-2.6.13-15b-xen"
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 128
name = "nbd4"
vif = [ '' ]
# Please change PORT
+4
View File
@@ -18,6 +18,10 @@ kernel = "/boot/Flash.fd"
builder='hvm'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 256
# A name for your domain. All domains must have different names.
+4
View File
@@ -17,6 +17,10 @@ kernel = "/boot/vmlinuz-2.6.10-xenU"
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for your domain. All domains must have different names.
+4
View File
@@ -45,6 +45,10 @@ kernel = "/boot/vmlinuz-2.6.10-xenU"
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for the new domain. All domains have to have different names,
+4
View File
@@ -45,6 +45,10 @@ kernel = "/path/to/domU/kernel"
#builder='linux'
# Initial memory allocation (in megabytes) for the new domain.
#
# WARNING: Creating a domain with insufficient memory may cause out of
# memory errors. The domain needs enough memory to boot kernel
# and modules. Allocating less than 32MBs is not recommended.
memory = 64
# A name for the new domain. All domains have to have different names,
+3 -9
View File
@@ -40,7 +40,6 @@ int speaker_data_on;
int dummy_refresh_clock;
static fdctrl_t *floppy_controller;
static RTCState *rtc_state;
static PITState *pit;
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
{
@@ -243,17 +242,13 @@ static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_
static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
speaker_data_on = (val >> 1) & 1;
pit_set_gate(pit, 2, val & 1);
fprintf(stderr, "speaker port should not be handled in DM!\n");
}
static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
{
int out;
out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
dummy_refresh_clock ^= 1;
return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
(dummy_refresh_clock << 4);
fprintf(stderr, "speaker port should not be handled in DM!\n");
return 0;
}
static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
@@ -529,7 +524,6 @@ void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
pic_init();
pit = pit_init(0x40, 0);
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
+1 -1
View File
@@ -75,7 +75,7 @@ static kbd_layout_t* parse_keyboard_layout(const char* language,kbd_layout_t* k)
char* file_name=malloc(strlen(prefix)+strlen(language)+strlen(bios_dir)+1);
if(!k)
k=calloc(sizeof(kbd_layout_t),1);
k=calloc(1, sizeof(kbd_layout_t));
strcpy(file_name,bios_dir);
strcat(file_name,prefix);
strcat(file_name,language);
+1 -1
View File
@@ -277,7 +277,7 @@ endif
# Hardware support
VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o i8254.o pc.o port-e9.o
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o pc.o port-e9.o
VL_OBJS+= cirrus_vga.o pcnet.o
VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
+3 -3
View File
@@ -183,9 +183,9 @@ int xc_linux_restore(int xc_handle, int io_fd,
/* We want zeroed memory so use calloc rather than malloc. */
p2m = calloc(sizeof(unsigned long), max_pfn);
pfn_type = calloc(sizeof(unsigned long), max_pfn);
region_mfn = calloc(sizeof(unsigned long), MAX_BATCH_SIZE);
p2m = calloc(max_pfn, sizeof(unsigned long));
pfn_type = calloc(max_pfn, sizeof(unsigned long));
region_mfn = calloc(MAX_BATCH_SIZE, sizeof(unsigned long));
if ((p2m == NULL) || (pfn_type == NULL) || (region_mfn == NULL)) {
ERR("memory alloc failed");
+1 -1
View File
@@ -11,7 +11,7 @@ build:
.PHONY: install
ifndef XEN_PYTHON_NATIVE_INSTALL
install: all
CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr"
CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix=""
else
install: all
CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
+1 -1
View File
@@ -11,7 +11,7 @@ build:
.PHONY: install
ifndef XEN_PYTHON_NATIVE_INSTALL
install: all
CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --force
CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force
else
install: all
CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force
+8 -1
View File
@@ -31,6 +31,13 @@ xs = Extension("xs",
libraries = libraries,
sources = [ "xen/lowlevel/xs/xs.c" ])
acm = Extension("acm",
extra_compile_args = extra_compile_args,
include_dirs = include_dirs + [ "xen/lowlevel/acm" ],
library_dirs = library_dirs,
libraries = libraries,
sources = [ "xen/lowlevel/acm/acm.c" ])
setup(name = 'xen',
version = '3.0',
description = 'Xen',
@@ -50,7 +57,7 @@ setup(name = 'xen',
'xen.xm.tests'
],
ext_package = "xen.lowlevel",
ext_modules = [ xc, xs ]
ext_modules = [ xc, xs, acm ]
)
os.chdir('logging')
+237
View File
@@ -0,0 +1,237 @@
/****************************************************************
* acm.c
*
* Copyright (C) 2006 IBM Corporation
*
* Authors:
* 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 low-level code that allows Python control code to leverage
* the ACM hypercall interface to retrieve real-time information
* from the Xen hypervisor security module.
*
* indent -i4 -kr -nut
*/
#include <Python.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <xen/acm.h>
#include <xen/acm_ops.h>
#include <xen/linux/privcmd.h>
#define PERROR(_m, _a...) \
fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
errno, strerror(errno))
static inline int do_acm_op(int xc_handle, struct acm_op *op)
{
int ret = -1;
privcmd_hypercall_t hypercall;
op->interface_version = ACM_INTERFACE_VERSION;
hypercall.op = __HYPERVISOR_acm_op;
hypercall.arg[0] = (unsigned long) op;
if (mlock(op, sizeof(*op)) != 0) {
PERROR("Could not lock memory for Xen policy hypercall");
goto out1;
}
ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
if (ret < 0) {
if (errno == EACCES)
PERROR("ACM operation failed.");
goto out2;
}
out2:
munlock(op, sizeof(*op));
out1:
return ret;
}
/* generic shared function */
void * __getssid(int domid, uint32_t *buflen)
{
struct acm_op op;
int acm_cmd_fd;
#define SSID_BUFFER_SIZE 4096
void *buf = NULL;
if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) < 0) {
goto out1;
}
if ((buf = malloc(SSID_BUFFER_SIZE)) == NULL) {
PERROR("acm.policytype: Could not allocate ssid buffer!\n");
goto out2;
}
memset(buf, 0, SSID_BUFFER_SIZE);
op.cmd = ACM_GETSSID;
op.interface_version = ACM_INTERFACE_VERSION;
op.u.getssid.ssidbuf = buf;
op.u.getssid.ssidbuf_size = SSID_BUFFER_SIZE;
op.u.getssid.get_ssid_by = DOMAINID;
op.u.getssid.id.domainid = domid;
if (do_acm_op(acm_cmd_fd, &op) < 0) {
free(buf);
buf = NULL;
goto out2;
} else {
*buflen = SSID_BUFFER_SIZE;
goto out2;
}
out2:
close(acm_cmd_fd);
out1:
return buf;
}
/* retrieve the policytype indirectly by retrieving the
* ssidref for domain 0 (always exists) */
static PyObject *policy(PyObject * self, PyObject * args)
{
/* out */
char *policyreference;
PyObject *ret = NULL;
void *ssid_buffer;
uint32_t buf_len;
if (!PyArg_ParseTuple(args, "", NULL)) {
goto out1;
}
ssid_buffer = __getssid(0, &buf_len);
if (ssid_buffer == NULL) {
goto out1;
} else if (buf_len < sizeof(struct acm_ssid_buffer)) {
goto out2;
} else {
struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)ssid_buffer;
policyreference = (char *)(ssid_buffer + ssid->policy_reference_offset
+ sizeof (struct acm_policy_reference_buffer));
}
ret = Py_BuildValue("s", policyreference);
out2:
free(ssid_buffer);
out1:
return ret;
}
/* retrieve ssid info for a domain domid*/
static PyObject *getssid(PyObject * self, PyObject * args)
{
/* in */
uint32_t domid;
/* out */
char *policytype, *policyreference;
uint32_t ssidref;
void *ssid_buffer;
uint32_t buf_len;
if (!PyArg_ParseTuple(args, "i", &domid)) {
return NULL;
}
ssid_buffer = __getssid(domid, &buf_len);
if (ssid_buffer == NULL) {
return NULL;
} else if (buf_len < sizeof(struct acm_ssid_buffer)) {
free(ssid_buffer);
return NULL;
} else {
struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *) ssid_buffer;
policytype = ACM_POLICY_NAME(ssid->secondary_policy_code << 4 |
ssid->primary_policy_code);
ssidref = ssid->ssidref;
policyreference = (char *)(ssid_buffer + ssid->policy_reference_offset
+ sizeof (struct acm_policy_reference_buffer));
}
free(ssid_buffer);
return Py_BuildValue("{s:s,s:s,s:i}",
"policyreference", policyreference,
"policytype", policytype,
"ssidref", ssidref);
}
/* retrieve access decision based on domain ids or ssidrefs */
static PyObject *getdecision(PyObject * self, PyObject * args)
{
char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
struct acm_op op;
int acm_cmd_fd, ret;
if (!PyArg_ParseTuple(args, "ssss", &arg1_name, &arg1, &arg2_name, &arg2)) {
return NULL;
}
if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
PERROR("Could not open xen privcmd device!\n");
return NULL;
}
if ((strcmp(arg1_name, "domid") && strcmp(arg1_name, "ssidref")) ||
(strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
return NULL;
op.cmd = ACM_GETDECISION;
op.interface_version = ACM_INTERFACE_VERSION;
op.u.getdecision.hook = SHARING;
if (!strcmp(arg1_name, "domid")) {
op.u.getdecision.get_decision_by1 = DOMAINID;
op.u.getdecision.id1.domainid = atoi(arg1);
} else {
op.u.getdecision.get_decision_by1 = SSIDREF;
op.u.getdecision.id1.ssidref = atol(arg1);
}
if (!strcmp(arg2_name, "domid")) {
op.u.getdecision.get_decision_by2 = DOMAINID;
op.u.getdecision.id2.domainid = atoi(arg2);
} else {
op.u.getdecision.get_decision_by2 = SSIDREF;
op.u.getdecision.id2.ssidref = atol(arg2);
}
ret = do_acm_op(acm_cmd_fd, &op);
close(acm_cmd_fd);
if (op.u.getdecision.acm_decision == ACM_ACCESS_PERMITTED)
decision = "PERMITTED";
else if (op.u.getdecision.acm_decision == ACM_ACCESS_DENIED)
decision = "DENIED";
return Py_BuildValue("s", decision);
}
/*=================General Python Extension Declarations=================*/
/* methods */
static PyMethodDef acmMethods[] = {
{"policy", policy, METH_VARARGS, "Retrieve Active ACM Policy Reference Name"},
{"getssid", getssid, METH_VARARGS, "Retrieve label information and ssidref for a domain"},
{"getdecision", getdecision, METH_VARARGS, "Retrieve ACM access control decision"},
/* end of list (extend list above this line) */
{NULL, NULL, 0, NULL}
};
/* inits */
PyMODINIT_FUNC initacm(void)
{
Py_InitModule("acm", acmMethods);
}
+16 -5
View File
@@ -11,10 +11,11 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Copyright (c) 2005 XenSource Ltd
# Copyright (c) 2005-2006 XenSource Inc
import re
import socket
import sys
from xen.xend import sxp
@@ -45,7 +46,6 @@ def diagnose(dom):
state = sxp.child_value(domain, 'state')
domid = int(sxp.child_value(domain, 'domid'))
name = sxp.child_value(domain, 'name')
dompath = '/local/domain/%d' % domid
print "Domain ID is %d." % domid
print "Domain name is %s." % name
@@ -55,12 +55,23 @@ def diagnose(dom):
if state.find('c') != -1:
print "Domain has crashed."
except socket.error, exn:
print "Cannot contact Xend."
diagnose_console()
diagnose_devices()
try:
domid = int(dom)
name = dom
except ValueError:
print \
"Without Xend, you will have to specify the domain ID, not the domain name."
sys.exit(1)
except xen.xend.XendProtocol.XendError, exn:
print exn
sys.exit(1)
dompath = '/local/domain/%d' % domid
diagnose_console()
diagnose_devices()
def diagnose_console():
+504
View File
@@ -0,0 +1,504 @@
#===========================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer
#============================================================================
import commands
import logging
import sys, os, string, re
import traceback
import shutil
from xen.lowlevel import acm
from xen.xend import sxp
#global directories and tools for security management
policy_dir_prefix = "/etc/xen/acm-security/policies"
boot_filename = "/boot/grub/menu.lst"
xensec_xml2bin = "/usr/sbin/xensec_xml2bin"
xensec_tool = "/usr/sbin/xensec_tool"
#global patterns for map file
#police_reference_tagname = "POLICYREFERENCENAME"
primary_entry_re = re.compile("\s*PRIMARY\s+.*", re.IGNORECASE)
secondary_entry_re = re.compile("\s*SECONDARY\s+.*", re.IGNORECASE)
label_template_re = re.compile(".*security_label_template.xml", re.IGNORECASE)
mapping_filename_re = re.compile(".*\.map", re.IGNORECASE)
policy_reference_entry_re = re.compile("\s*POLICYREFERENCENAME\s+.*", re.IGNORECASE)
vm_label_re = re.compile("\s*LABEL->SSID\s+VM\s+.*", re.IGNORECASE)
res_label_re = re.compile("\s*LABEL->SSID\s+RES\s+.*", re.IGNORECASE)
all_label_re = re.compile("\s*LABEL->SSID\s+.*", re.IGNORECASE)
access_control_re = re.compile("\s*access_control\s*=", re.IGNORECASE)
#global patterns for boot configuration file
xen_title_re = re.compile("\s*title\s+XEN", re.IGNORECASE)
any_title_re = re.compile("\s*title\s", re.IGNORECASE)
xen_kernel_re = re.compile("\s*kernel.*xen.*\.gz", re.IGNORECASE)
kernel_ver_re = re.compile("\s*module.*vmlinuz", re.IGNORECASE)
any_module_re = re.compile("\s*module\s", re.IGNORECASE)
empty_line_re = re.compile("^\s*$")
binary_name_re = re.compile(".*[chwall|ste|chwall_ste].*\.bin", re.IGNORECASE)
policy_name_re = re.compile(".*[chwall|ste|chwall_ste].*", re.IGNORECASE)
log = logging.getLogger("xend.util.security")
# Our own exception definition. It is masked (pass) if raised and
# whoever raises this exception must provide error information.
class ACMError(Exception):
def __init__(self,value):
self.value = value
def __str__(self):
return repr(self.value)
def err(msg):
"""Raise ACM exception.
"""
sys.stderr.write("ACMError: " + msg + "\n")
raise ACMError(msg)
active_policy = None
def refresh_security_policy():
"""
retrieves security policy
"""
global active_policy
try:
active_policy = acm.policy()
except:
active_policy = "INACTIVE"
# now set active_policy
refresh_security_policy()
def on():
"""
returns none if security policy is off (not compiled),
any string otherwise, use it: if not security.on() ...
"""
refresh_security_policy()
return (active_policy not in ['INACTIVE', 'NULL'])
# Assumes a 'security' info [security access_control ...] [ssidref ...]
def get_security_info(info, field):
"""retrieves security field from self.info['security'])
allowed search fields: ssidref, label, policy
"""
if isinstance(info, dict):
security = info['security']
elif isinstance(info, list):
security = sxp.child_value(info, 'security', )
if not security:
if field == 'ssidref':
#return default ssid
return 0
else:
err("Security information not found in info struct.")
if field == 'ssidref':
search = 'ssidref'
elif field in ['policy', 'label']:
search = 'access_control'
else:
err("Illegal field in get_security_info.")
for idx in range(0, len(security)):
if search != security[idx][0]:
continue
if search == 'ssidref':
return int(security[idx][1])
else:
for aidx in range(0, len(security[idx])):
if security[idx][aidx][0] == field:
return str(security[idx][aidx][1])
if search == 'ssidref':
return 0
else:
return None
def get_security_printlabel(info):
"""retrieves printable security label from self.info['security']),
preferably the label name and otherwise (if label is not specified
in config and cannot be found in mapping file) a hex string of the
ssidref or none if both not available
"""
try:
if not on():
return "INACTIVE"
if active_policy in ["DEFAULT"]:
return "DEFAULT"
printlabel = get_security_info(info, 'label')
if printlabel:
return printlabel
ssidref = get_security_info(info, 'ssidref')
if not ssidref:
return None
#try to translate ssidref to a label
result = ssidref2label(ssidref)
if not result:
printlabel = "0x%08x" % ssidref
else:
printlabel = result
return printlabel
except ACMError:
#don't throw an exception in xm list
return "ERROR"
def getmapfile(policyname):
"""
in: if policyname is None then the currently
active hypervisor policy is used
out: 1. primary policy, 2. secondary policy,
3. open file descriptor for mapping file, and
4. True if policy file is available, False otherwise
"""
if not policyname:
policyname = active_policy
map_file_ok = False
primary = None
secondary = None
#strip last part of policy as file name part
policy_dir_list = string.split(policyname, ".")
policy_file = policy_dir_list.pop()
if len(policy_dir_list) > 0:
policy_dir = string.join(policy_dir_list, "/") + "/"
else:
policy_dir = ""
map_filename = policy_dir_prefix + "/" + policy_dir + policy_file + ".map"
# check if it is there, if not check if policy file is there
if not os.path.isfile(map_filename):
policy_filename = policy_dir_prefix + "/" + policy_dir + policy_file + "-security_policy.xml"
if not os.path.isfile(policy_filename):
err("Policy file \'" + policy_filename + "\' not found.")
else:
err("Mapping file \'" + map_filename + "\' not found." +
" Use xm makepolicy to create it.")
f = open(map_filename)
for line in f:
if policy_reference_entry_re.match(line):
l = line.split()
if (len(l) == 2) and (l[1] == policyname):
map_file_ok = True
elif primary_entry_re.match(line):
l = line.split()
if len(l) == 2:
primary = l[1]
elif secondary_entry_re.match(line):
l = line.split()
if len(l) == 2:
secondary = l[1]
f.close()
f = open(map_filename)
if map_file_ok and primary and secondary:
return (primary, secondary, f, True)
else:
err("Mapping file inconsistencies found. Try makepolicy to create a new one.")
def ssidref2label(ssidref_var):
"""
returns labelname corresponding to ssidref;
maps current policy to default directory
to find mapping file
"""
#1. translated permitted input formats
if isinstance(ssidref_var, str):
ssidref_var.strip()
if ssidref_var[0:2] == "0x":
ssidref = int(ssidref_var[2:], 16)
else:
ssidref = int(ssidref_var)
elif isinstance(ssidref_var, int):
ssidref = ssidref_var
else:
err("Instance type of ssidref not supported (must be of type 'str' or 'int')")
(primary, secondary, f, pol_exists) = getmapfile(None)
if not f:
if (pol_exists):
err("Mapping file for policy \'" + policyname + "\' not found.\n" +
"Please use makepolicy command to create mapping file!")
else:
err("Policy file for \'" + active_policy + "\' not found.")
#2. get labelnames for both ssidref parts
pri_ssid = ssidref & 0xffff
sec_ssid = ssidref >> 16
pri_labels = []
sec_labels = []
labels = []
for line in f:
l = line.split()
if (len(l) < 5) or (l[0] != "LABEL->SSID"):
continue
if primary and (l[2] == primary) and (int(l[4], 16) == pri_ssid):
pri_labels.append(l[3])
if secondary and (l[2] == secondary) and (int(l[4], 16) == sec_ssid):
sec_labels.append(l[3])
f.close()
#3. get the label that is in both lists (combination must be a single label)
if secondary == "NULL":
labels = pri_labels
else:
for i in pri_labels:
for j in sec_labels:
if (i==j):
labels.append(i)
if len(labels) != 1:
err("Label for ssidref \'" + str(ssidref) +
"\' unknown or not unique in policy \'" + active_policy + "\'")
return labels[0]
def label2ssidref(labelname, policyname):
"""
returns ssidref corresponding to labelname;
maps current policy to default directory
to find mapping file """
if policyname in ['NULL', 'INACTIVE', 'DEFAULT']:
err("Cannot translate labels for \'" + policyname + "\' policy.")
(primary, secondary, f, pol_exists) = getmapfile(policyname)
#2. get labelnames for ssidref parts and find a common label
pri_ssid = []
sec_ssid = []
for line in f:
l = line.split()
if (len(l) < 5) or (l[0] != "LABEL->SSID"):
continue
if primary and (l[2] == primary) and (l[3] == labelname):
pri_ssid.append(int(l[4], 16))
if secondary and (l[2] == secondary) and (l[3] == labelname):
sec_ssid.append(int(l[4], 16))
f.close()
#3. sanity check and composition of ssidref
if (len(pri_ssid) == 0) or ((len(sec_ssid) == 0) and (secondary != "NULL")):
err("Label \'" + labelname + "\' not found.")
elif (len(pri_ssid) > 1) or (len(sec_ssid) > 1):
err("Label \'" + labelname + "\' not unique in policy (policy error)")
if secondary == "NULL":
return pri_ssid[0]
else:
return (sec_ssid[0] << 16) | pri_ssid[0]
def refresh_ssidref(config):
"""
looks up ssidref from security field
and refreshes the value if label exists
"""
#called by dom0, policy could have changed after xen.utils.security was initialized
refresh_security_policy()
security = None
if isinstance(config, dict):
security = config['security']
elif isinstance(config, list):
security = sxp.child_value(config, 'security',)
else:
err("Instance type of config parameter not supported.")
if not security:
#nothing to do (no security label attached)
return config
policyname = None
labelname = None
# compose new security field
for idx in range(0, len(security)):
if security[idx][0] == 'ssidref':
security.pop(idx)
break
elif security[idx][0] == 'access_control':
for jdx in [1, 2]:
if security[idx][jdx][0] == 'label':
labelname = security[idx][jdx][1]
elif security[idx][jdx][0] == 'policy':
policyname = security[idx][jdx][1]
else:
err("Illegal field in access_control")
#verify policy is correct
if active_policy != policyname:
err("Policy \'" + policyname + "\' in label does not match active policy \'"
+ active_policy +"\'!")
new_ssidref = label2ssidref(labelname, policyname)
if not new_ssidref:
err("SSIDREF refresh failed!")
security.append([ 'ssidref',str(new_ssidref)])
security = ['security', security ]
for idx in range(0,len(config)):
if config[idx][0] == 'security':
config.pop(idx)
break
config.append(security)
def get_ssid(domain):
"""
enables domains to retrieve the label / ssidref of a running domain
"""
if not on():
err("No policy active.")
if isinstance(domain, str):
domain_int = int(domain)
elif isinstance(domain, int):
domain_int = domain
else:
err("Illegal parameter type.")
try:
ssid_info = acm.getssid(int(domain_int))
except:
err("Cannot determine security information.")
if active_policy in ["DEFAULT"]:
label = "DEFAULT"
else:
label = ssidref2label(ssid_info["ssidref"])
return(ssid_info["policyreference"],
label,
ssid_info["policytype"],
ssid_info["ssidref"])
def get_decision(arg1, arg2):
"""
enables domains to retrieve access control decisions from
the hypervisor Access Control Module.
IN: args format = ['domid', id] or ['ssidref', ssidref]
or ['access_control', ['policy', policy], ['label', label]]
"""
if not on():
err("No policy active.")
#translate labels before calling low-level function
if arg1[0] == 'access_control':
if (arg1[1][0] != 'policy') or (arg1[2][0] != 'label') :
err("Argument type not supported.")
ssidref = label2ssidref(arg1[2][1], arg1[1][1])
arg1 = ['ssidref', str(ssidref)]
if arg2[0] == 'access_control':
if (arg2[1][0] != 'policy') or (arg2[2][0] != 'label') :
err("Argument type not supported.")
ssidref = label2ssidref(arg2[2][1], arg2[1][1])
arg2 = ['ssidref', str(ssidref)]
try:
decision = acm.getdecision(arg1[0], arg1[1], arg2[0], arg2[1])
except:
err("Cannot determine decision.")
if decision:
return decision
else:
err("Cannot determine decision (Invalid parameter).")
def make_policy(policy_name):
policy_file = string.join(string.split(policy_name, "."), "/")
if not os.path.isfile(policy_dir_prefix + "/" + policy_file + "-security_policy.xml"):
err("Unknown policy \'" + policy_name + "\'")
(ret, output) = commands.getstatusoutput(xensec_xml2bin + " -d " + policy_dir_prefix + " " + policy_file)
if ret:
err("Creating policy failed:\n" + output)
def load_policy(policy_name):
global active_policy
policy_file = policy_dir_prefix + "/" + string.join(string.split(policy_name, "."), "/")
if not os.path.isfile(policy_file + ".bin"):
if os.path.isfile(policy_file + "-security_policy.xml"):
err("Binary file does not exist." +
"Please use makepolicy to build the policy binary.")
else:
err("Unknown Policy " + policy_name)
#require this policy to be the first or the same as installed
if active_policy not in ['DEFAULT', policy_name]:
err("Active policy \'" + active_policy +
"\' incompatible with new policy \'" + policy_name + "\'")
(ret, output) = commands.getstatusoutput(xensec_tool + " loadpolicy " + policy_file + ".bin")
if ret:
err("Loading policy failed:\n" + output)
else:
# refresh active policy
refresh_security_policy()
def dump_policy():
if active_policy in ['NULL', 'INACTIVE']:
err("\'" + active_policy + "\' policy. Nothing to dump.")
(ret, output) = commands.getstatusoutput(xensec_tool + " getpolicy")
if ret:
err("Dumping hypervisor policy failed:\n" + output)
print output
def list_labels(policy_name, condition):
if (not policy_name) and (active_policy) in ["NULL", "INACTIVE", "DEFAULT"]:
err("Current policy \'" + active_policy + "\' has no labels defined.\n")
(primary, secondary, f, pol_exists) = getmapfile(policy_name)
if not f:
if pol_exists:
err("Cannot find mapfile for policy \'" + policy_name +
"\'.\nPlease use makepolicy to create mapping file.")
else:
err("Unknown policy \'" + policy_name + "\'")
labels = []
for line in f:
if condition.match(line):
label = line.split()[3]
if label not in labels:
labels.append(label)
return labels
+7 -4
View File
@@ -21,7 +21,8 @@ import xen.lowlevel.xc
import balloon
from XendError import XendError
from XendLogging import log
from XendDomainInfo import DEV_MIGRATE_STEP1, DEV_MIGRATE_STEP2
from XendDomainInfo import DEV_MIGRATE_STEP3
SIGNATURE = "LinuxGuestRecord"
XC_SAVE = "xc_save"
@@ -65,7 +66,7 @@ def save(fd, dominfo, live, dst):
dominfo.setName('migrating-' + domain_name)
try:
dominfo.migrateDevices(live, dst, 1, domain_name)
dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP1, domain_name)
write_exact(fd, pack("!i", len(config)),
"could not write guest state file: config len")
@@ -87,9 +88,11 @@ def save(fd, dominfo, live, dst):
log.debug("Suspending %d ...", dominfo.getDomid())
dominfo.shutdown('suspend')
dominfo.waitForShutdown()
dominfo.migrateDevices(live, dst, 2, domain_name)
dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP2,
domain_name)
log.info("Domain %d suspended.", dominfo.getDomid())
dominfo.migrateDevices(live, dst, 3, domain_name)
dominfo.migrateDevices(live, dst, DEV_MIGRATE_STEP3,
domain_name)
tochild.write("done\n")
tochild.flush()
log.debug('Written done')
+3 -1
View File
@@ -38,6 +38,7 @@ from xen.xend.XendError import XendError, XendInvalidDomain
from xen.xend.XendLogging import log
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
from xen.util import security
xc = xen.lowlevel.xc.xc()
@@ -265,7 +266,7 @@ class XendDomain:
# handling in the relocation-socket handling code (relocate.py) is
# poor, so we need to log this for debugging.
log.exception("Restore failed")
raise
raise XendError("Restore failed")
def restore_(self, config):
@@ -283,6 +284,7 @@ class XendDomain:
"""
self.domains_lock.acquire()
try:
security.refresh_ssidref(config)
dominfo = XendDomainInfo.restore(config)
self._add_domain(dominfo)
return dominfo
+49 -15
View File
@@ -33,7 +33,7 @@ import threading
import xen.lowlevel.xc
from xen.util import asserts
from xen.util.blkif import blkdev_uname_to_file
from xen.util import security
import balloon
import image
import sxp
@@ -87,6 +87,12 @@ SHUTDOWN_TIMEOUT = 30.0
ZOMBIE_PREFIX = 'Zombie-'
"""Constants for the different stages of ext. device migration """
DEV_MIGRATE_TEST = 0
DEV_MIGRATE_STEP1 = 1
DEV_MIGRATE_STEP2 = 2
DEV_MIGRATE_STEP3 = 3
"""Minimum time between domain restarts in seconds."""
MINIMUM_RESTART_TIME = 20
@@ -120,7 +126,6 @@ VM_CONFIG_PARAMS = [
# file, so those are handled separately.
ROUNDTRIPPING_CONFIG_ENTRIES = [
('uuid', str),
('ssidref', int),
('vcpus', int),
('vcpu_avail', int),
('cpu_weight', float),
@@ -138,7 +143,6 @@ ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
#
VM_STORE_ENTRIES = [
('uuid', str),
('ssidref', int),
('vcpus', int),
('vcpu_avail', int),
('memory', int),
@@ -291,6 +295,9 @@ def parseConfig(config):
result['cpu'] = get_cfg('cpu', int)
result['cpus'] = get_cfg('cpus', str)
result['image'] = get_cfg('image')
tmp_security = get_cfg('security')
if tmp_security:
result['security'] = tmp_security
try:
if result['image']:
@@ -437,7 +444,7 @@ class XendDomainInfo:
self.validateInfo()
self.image = None
self.security = None
self.store_port = None
self.store_mfn = None
self.console_port = None
@@ -515,6 +522,7 @@ class XendDomainInfo:
else:
entries = VM_STORE_ENTRIES
entries.append(('image', str))
entries.append(('security', str))
map(lambda x, y: useIfNeeded(x[0], y), entries,
self.readVMDetails(entries))
@@ -538,7 +546,6 @@ class XendDomainInfo:
try:
defaultInfo('name', lambda: "Domain-%d" % self.domid)
defaultInfo('ssidref', lambda: 0)
defaultInfo('on_poweroff', lambda: "destroy")
defaultInfo('on_reboot', lambda: "restart")
defaultInfo('on_crash', lambda: "restart")
@@ -565,12 +572,16 @@ class XendDomainInfo:
defaultInfo('backend', lambda: [])
defaultInfo('device', lambda: [])
defaultInfo('image', lambda: None)
defaultInfo('security', lambda: None)
self.check_name(self.info['name'])
if isinstance(self.info['image'], str):
self.info['image'] = sxp.from_string(self.info['image'])
if isinstance(self.info['security'], str):
self.info['security'] = sxp.from_string(self.info['security'])
if self.info['memory'] == 0:
if self.infoIsSet('mem_kb'):
self.info['memory'] = (self.info['mem_kb'] + 1023) / 1024
@@ -668,6 +679,20 @@ class XendDomainInfo:
if self.infoIsSet('image'):
to_store['image'] = sxp.to_string(self.info['image'])
if self.infoIsSet('security'):
security = self.info['security']
to_store['security'] = sxp.to_string(security)
for idx in range(0, len(security)):
if security[idx][0] == 'access_control':
to_store['security/access_control'] = sxp.to_string([ security[idx][1] , security[idx][2] ])
for aidx in range(1, len(security[idx])):
if security[idx][aidx][0] == 'label':
to_store['security/access_control/label'] = security[idx][aidx][1]
if security[idx][aidx][0] == 'policy':
to_store['security/access_control/policy'] = security[idx][aidx][1]
if security[idx][0] == 'ssidref':
to_store['security/ssidref'] = str(security[idx][1])
log.debug("Storing VM details: %s", to_store)
self.writeVm(to_store)
@@ -760,9 +785,8 @@ class XendDomainInfo:
self.storeVm('vcpu_avail', self.info['vcpu_avail'])
self.writeDom(self.vcpuDomDetails())
def getSsidref(self):
return self.info['ssidref']
def getLabel(self):
return security.get_security_info(self.info, 'label')
def getMemoryTarget(self):
"""Get this domain's target memory size, in KB."""
@@ -954,12 +978,21 @@ class XendDomainInfo:
"""
log.trace("XendDomainInfo.update(%s) on domain %d", info, self.domid)
if not info:
info = dom_get(self.domid)
if not info:
return
#manually update ssidref / security fields
if security.on() and info.has_key('ssidref'):
if (info['ssidref'] != 0) and self.info.has_key('security'):
security_field = self.info['security']
if not security_field:
#create new security element
self.info.update({'security': [['ssidref', str(info['ssidref'])]]})
#ssidref field not used any longer
info.pop('ssidref')
self.info.update(info)
self.validateInfo()
self.refreshShutdown(info)
@@ -996,7 +1029,6 @@ class XendDomainInfo:
s += " id=" + str(self.domid)
s += " name=" + self.info['name']
s += " memory=" + str(self.info['memory'])
s += " ssidref=" + str(self.info['ssidref'])
s += ">"
return s
@@ -1058,6 +1090,9 @@ class XendDomainInfo:
if self.infoIsSet('image'):
sxpr.append(['image', self.info['image']])
if self.infoIsSet('security'):
sxpr.append(['security', self.info['security']])
for cls in controllerClasses:
for config in self.getDeviceConfigurations(cls):
sxpr.append(['device', config])
@@ -1159,12 +1194,11 @@ class XendDomainInfo:
@raise: VmError on error
"""
log.debug('XendDomainInfo.construct: %s %s',
self.domid,
self.info['ssidref'])
log.debug('XendDomainInfo.construct: %s',
self.domid)
self.domid = xc.domain_create(
dom = 0, ssidref = self.info['ssidref'],
dom = 0, ssidref = security.get_security_info(self.info, 'ssidref'),
handle = uuid.fromString(self.info['uuid']))
if self.domid < 0:
@@ -1402,7 +1436,7 @@ class XendDomainInfo:
@raise: XendError for a device that cannot be migrated
"""
for (n, c) in self.info['device']:
rc = self.migrateDevice(n, c, live, dst, 0)
rc = self.migrateDevice(n, c, live, dst, DEV_MIGRATE_TEST)
if rc != 0:
raise XendError("Device of type '%s' refuses migration." % n)
+4 -3
View File
@@ -25,6 +25,7 @@ from xen.xend import sxp
from xen.xend.XendLogging import log
from xen.xend.XendError import XendError
from xen.xend import XendRoot
from xen.xend.XendDomainInfo import DEV_MIGRATE_TEST
from xen.xend.server.DevController import DevController
@@ -78,7 +79,7 @@ class TPMifController(DevController):
log.info("Request to live-migrate device to %s. step=%d.",
dst, step)
if step == 0:
if step == DEV_MIGRATE_TEST:
"""Assuming for now that everything is ok and migration
with the given tool can proceed.
"""
@@ -90,8 +91,8 @@ class TPMifController(DevController):
for line in fd.readlines():
mo = re.search('Error', line)
if mo:
raise XendError("vtpm: Fatal error in migration step %d." %
step)
raise XendError("vtpm: Fatal error in migration step %d: %s" %
(step, line))
return 0
else:
log.debug("External migration tool not in configuration.")
+76
View File
@@ -0,0 +1,76 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Labeling a domain configuration file.
"""
import sys, os
import traceback
from xen.util.security import ACMError, err, active_policy, label2ssidref, on, access_control_re
def usage():
print "\nUsage: xm addlabel <configfile> <label> [<policy>]\n"
print " This program adds an acm_label entry into the 'configfile'."
print " It derives the policy from the running hypervisor if it"
print " is not given (optional parameter). If the configfile is"
print " already labeled, then addlabel fails.\n"
err("Usage")
def main(argv):
try:
policyref = None
if len(argv) not in [3,4]:
usage()
configfile = argv[1]
label = argv[2]
if len(argv) == 4:
policyref = argv[3]
elif on():
policyref = active_policy
else:
err("No active policy. Policy must be specified in command line.")
#sanity checks: make sure this label can be instantiated later on
ssidref = label2ssidref(label, policyref)
new_label = "access_control = ['policy=%s,label=%s']\n" % (policyref, label)
if not os.path.isfile(configfile):
err("Configuration file \'" + configfile + "\' not found.")
config_fd = open(configfile, "ra+")
for line in config_fd:
if not access_control_re.match(line):
continue
config_fd.close()
err("Config file \'" + configfile + "\' is already labeled.")
config_fd.write(new_label)
config_fd.close()
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+188
View File
@@ -0,0 +1,188 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Configuring a security policy into the boot configuration
"""
import sys
import traceback
import tempfile
import os, stat
import re
import commands
import shutil
import string
from xen.util.security import ACMError, err
from xen.util.security import policy_dir_prefix, boot_filename, xen_title_re
from xen.util.security import any_title_re, xen_kernel_re, kernel_ver_re, any_module_re
from xen.util.security import empty_line_re, binary_name_re, policy_name_re
def usage():
print "\nUsage: xm cfgbootpolicy <policy> [<kernelversion>]\n"
print " Adds a 'module' line to the Xen grub.conf entry"
print " so that xen boots into a specific access control"
print " policy. If kernelversion is not given, then this"
print " script tries to determine it by looking for a grub"
print " entry with a line kernel xen.* If there are multiple"
print " Xen entries, then it must be called with an explicit"
print " version (it will fail otherwise).\n"
err("Usage")
def determine_kernelversion(user_specified):
within_xen_title = 0
within_xen_entry = 0
version_list = []
guess_version = None
grub_fd = open(boot_filename)
for line in grub_fd:
if xen_title_re.match(line):
within_xen_title = 1
elif within_xen_title and xen_kernel_re.match(line):
within_xen_entry = 1
elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
for i in line.split():
if (i.find("vmlinuz-") >= 0):
# skip start until "vmlinuz-"
guess_version = i[i.find("vmlinuz-") + len("vmlinuz-"):]
if user_specified:
if (guess_version == user_specified):
version_list.append(guess_version)
else:
version_list.append(guess_version)
elif len(line.split()) > 0:
if line.split()[0] == "title":
within_xen_title = 0
within_xen_entry = 0
if len(version_list) > 1:
err("Cannot decide between entries for kernels: " + version_list)
elif len(version_list) == 0:
err("Cannot find a boot entry candidate (please create a Xen boot entry first).")
else:
return version_list[0]
def insert_policy(boot_file, kernel_version, policy_name):
"""
inserts policy binary file as last line of the grub entry
matching the kernel_version version
"""
within_xen_title = 0
within_xen_entry = 0
insert_at_end_of_entry = 0
path_prefix = ''
done = False
(tmp_fd, tmp_grub) = tempfile.mkstemp()
#follow symlink since menue.lst might be linked to grub.conf
if stat.S_ISLNK(os.lstat(boot_file)[stat.ST_MODE]):
new_name = os.readlink(boot_file)
if new_name[0] == "/":
boot_file = new_name
else:
path = boot_file.split('/')
path[len(path)-1] = new_name
boot_file = '/'.join(path)
if not os.path.exists(boot_file):
err("Boot file \'" + boot_file + "\' not found.")
grub_fd = open(boot_file)
for line in grub_fd:
if xen_title_re.match(line):
within_xen_title = 1
elif within_xen_title and xen_kernel_re.match(line):
within_xen_entry = 1
elif within_xen_title and within_xen_entry and kernel_ver_re.match(line):
for i in line.split():
if (i.find("vmlinuz-") >= 0):
if kernel_version == i[i.find("vmlinuz-") + len("vmlinuz-"):]:
insert_at_end_of_entry = 1
path_prefix = i[0:i.find("vmlinuz-")]
elif any_module_re.match(line) and insert_at_end_of_entry:
if binary_name_re.match(line):
#delete existing policy module line
line=''
elif any_title_re.match(line):
within_xen_title = 0
within_xen_entry = 0
if (empty_line_re.match(line) or any_title_re.match(line)) and insert_at_end_of_entry:
#newline or new title: we insert the policy module line here
os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
insert_at_end_of_entry = 0
#write the line that was read (except potential existing policy entry)
os.write(tmp_fd, line)
if insert_at_end_of_entry:
#last entry, no empty line at end of file
os.write(tmp_fd, "\tmodule " + path_prefix + policy_name + ".bin\n")
#temp file might be destroyed when closing it, first copy ...
shutil.move(boot_file, boot_file+"_save")
shutil.copyfile(tmp_grub, boot_file)
os.close(tmp_fd)
#temp file did not disappear on my system ...
try:
os.remove(tmp_grub)
except:
pass
def main(argv):
try:
user_kver = None
policy = None
if len(argv) == 2:
policy = argv[1]
elif len(argv) == 3:
policy = argv[1]
user_kver = argv[2]
else:
usage()
if not policy_name_re.match(policy):
err("Illegal policy name \'" + policy + "\'")
policy_file = policy_dir_prefix + "/" + string.join(string.split(policy, "."), "/")
src_binary_policy_file = policy_file + ".bin"
#check if .bin exists or if policy file exists
if not os.path.isfile(src_binary_policy_file):
if not os.path.isfile(policy_file + "-security_policy.xml"):
err("Unknown policy \'" + policy +"\'")
else:
err("Cannot find binary file for policy \'" + policy +
"\'. Please use makepolicy to create binary file.")
dst_binary_policy_file = "/boot/" + policy + ".bin"
shutil.copyfile(src_binary_policy_file, dst_binary_policy_file)
kernel_version = determine_kernelversion(user_kver)
insert_policy(boot_filename, kernel_version, policy)
print "Boot entry created and \'%s\' copied to /boot" % (policy + ".bin")
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+74 -7
View File
@@ -35,6 +35,7 @@ import xen.xend.XendClient
from xen.xend.XendClient import server
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
from xen.util import security
from xen.xm.opts import *
@@ -145,10 +146,6 @@ gopts.var('memory', val='MEMORY',
fn=set_int, default=128,
use="Domain memory in MB.")
gopts.var('ssidref', val='SSIDREF',
fn=set_u32, default=0,
use="Security Identifier.")
gopts.var('maxmem', val='MEMORY',
fn=set_int, default=None,
use="Maximum domain memory in MB.")
@@ -293,6 +290,14 @@ gopts.var('vtpm', val="instance=INSTANCE,backend=DOM",
number can be found in /etc/xen/vtpm.db. Use the backend in the
given domain.""")
gopts.var('access_control', val="policy=POLICY,label=LABEL",
fn=append_value, default=[],
use="""Add a security label and the security policy reference that defines it.
The local ssid reference is calculated when starting/resuming the domain. At
this time, the policy is checked against the active policy as well. This way,
migrating through save/restore is covered and local labels are automatically
created correctly on the system where a domain is started / resumed.""")
gopts.var('nics', val="NUM",
fn=set_int, default=-1,
use="""DEPRECATED. Use empty vif entries instead.
@@ -502,6 +507,43 @@ def configure_usb(config_devs, vals):
config_usb = ['usb', ['path', path]]
config_devs.append(['device', config_usb])
def configure_security(config, vals):
"""Create the config for ACM security labels.
"""
access_control = vals.access_control
num = len(access_control)
if num == 1:
d = access_control[0]
policy = d.get('policy')
label = d.get('label')
if policy != security.active_policy:
err("Security policy (" + policy + ") incompatible with enforced policy ("
+ security.active_policy + ")." )
config_access_control = ['access_control',
['policy', policy],
['label', label] ]
#ssidref cannot be specified together with access_control
if sxp.child_value(config, 'ssidref'):
err("ERROR: SSIDREF and access_control are mutually exclusive but both specified!")
#else calculate ssidre from label
ssidref = security.label2ssidref(label, policy)
if not ssidref :
err("ERROR calculating ssidref from access_control.")
security_label = ['security', [ config_access_control, ['ssidref' , ssidref ] ] ]
config.append(security_label)
elif num == 0:
if hasattr(vals, 'ssidref'):
if not security.on():
err("ERROR: Security ssidref specified but no policy active.")
ssidref = getattr(vals, 'ssidref')
security_label = ['security', [ [ 'ssidref' , int(ssidref) ] ] ]
config.append(security_label)
elif num > 1:
err("VM config error: Multiple access_control definitions!")
def configure_vtpm(config_devs, vals):
"""Create the config for virtual TPM interfaces.
"""
@@ -595,9 +637,9 @@ def make_config(vals):
if v:
config.append([n, v])
map(add_conf, ['name', 'memory', 'ssidref', 'maxmem', 'restart',
'on_poweroff', 'on_reboot', 'on_crash', 'vcpus'])
map(add_conf, ['name', 'memory', 'maxmem', 'restart', 'on_poweroff',
'on_reboot', 'on_crash', 'vcpus'])
if vals.uuid is not None:
config.append(['uuid', vals.uuid])
if vals.cpu is not None:
@@ -628,6 +670,7 @@ def make_config(vals):
configure_vifs(config_devs, vals)
configure_usb(config_devs, vals)
configure_vtpm(config_devs, vals)
configure_security(config, vals)
config += config_devs
return config
@@ -696,6 +739,29 @@ def preprocess_vtpm(vals):
vtpms.append(d)
vals.vtpm = vtpms
def preprocess_access_control(vals):
if not vals.access_control:
return
access_controls = []
num = len(vals.access_control)
if num == 1:
access_control = (vals.access_control)[0]
d = {}
a = access_control.split(',')
if len(a) > 2:
err('Too many elements in access_control specifier: ' + access_control)
for b in a:
(k, v) = b.strip().split('=', 1)
k = k.strip()
v = v.strip()
if k not in ['policy','label']:
err('Invalid access_control specifier: ' + access_control)
d[k] = v
access_controls.append(d)
vals.access_control = access_controls
elif num > 1:
err('Multiple access_control definitions.')
def preprocess_ip(vals):
if vals.ip or vals.dhcp != 'off':
dummy_nfs_server = '1.2.3.4'
@@ -785,6 +851,7 @@ def preprocess(vals):
preprocess_nfs(vals)
preprocess_vnc(vals)
preprocess_vtpm(vals)
preprocess_access_control(vals)
def comma_sep_kv_to_dict(c):
+49
View File
@@ -0,0 +1,49 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Display currently enforced policy (low-level hypervisor representation).
"""
import sys
import traceback
import os
import commands
import shutil
import string
from xen.util.security import ACMError, err, dump_policy
def usage():
print "\nUsage: xm dumppolicy\n"
print " Retrieve and print currently enforced"
print " hypervisor policy information (low-level).\n"
err("Usage")
def main(argv):
try:
dump_policy()
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+85
View File
@@ -0,0 +1,85 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Listing available labels for a policy.
"""
import sys
import traceback
import os
import commands
import shutil
import string
from xen.util.security import ACMError, err, list_labels, active_policy
from xen.util.security import vm_label_re, res_label_re, all_label_re
def usage():
print "\nUsage: xm labels [<policy>] [<type=dom|res|any>]\n"
print " Prints labels of the specified type (default is dom)"
print " that are defined in policy (default is current"
print " hypervisor policy).\n"
err("Usage")
def main(argv):
try:
policy = None
type = None
for i in argv[1:]:
i_s = string.split(i, '=')
if len(i_s) > 1:
if (i_s[0] == 'type') and (len(i_s) == 2):
if not type:
type = i_s[1]
else:
usage()
else:
usage()
else:
if not policy:
policy = i
else:
usage()
if not policy:
policy = active_policy
if active_policy in ['NULL', 'INACTIVE', 'DEFAULT']:
err("No policy active. Please specify the <policy> parameter.")
if not type or (type in ['DOM', 'dom']):
condition = vm_label_re
elif type in ['RES', 'res']:
condition = res_label_re
elif type in ['ANY', 'any']:
condition = all_label_re
else:
err("Unknown label type \'" + type + "\'")
labels = list_labels(policy, condition)
labels.sort()
for label in labels:
print label
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+51
View File
@@ -0,0 +1,51 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Loading a compiled binary policy into the hypervisor.
"""
import sys
import traceback
import os
import commands
import shutil
import string
from xen.util.security import ACMError, err, load_policy
def usage():
print "\nUsage: xm loadpolicy <policy>\n"
print " Load the compiled binary (.bin) policy"
print " into the running hypervisor.\n"
err("Usage")
def main(argv):
try:
if len(argv) != 2:
usage()
load_policy(argv[1])
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+59 -10
View File
@@ -40,6 +40,7 @@ from xen.xm.opts import *
import console
import xen.xend.XendClient
from xen.xend.XendClient import server
from xen.util import security
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
@@ -55,6 +56,8 @@ create_help = """create [-c] <ConfigFile>
destroy_help = "destroy <DomId> Terminate a domain immediately"
help_help = "help Display this message"
list_help = "list [--long] [DomId, ...] List information about domains"
list_label_help = "list [--label] [DomId, ...] List information about domains including their labels"
mem_max_help = "mem-max <DomId> <Mem> Set maximum memory reservation for a domain"
mem_set_help = "mem-set <DomId> <Mem> Adjust the current memory usage for a domain"
migrate_help = "migrate <DomId> <Host> Migrate a domain to another machine"
@@ -114,6 +117,12 @@ vnet_list_help = "vnet-list [-l|--long] list vnets"
vnet_create_help = "vnet-create <config> create a vnet from a config file"
vnet_delete_help = "vnet-delete <vnetid> delete a vnet"
vtpm_list_help = "vtpm-list <DomId> [--long] list virtual TPM devices"
addlabel_help = "addlabel <ConfigFile> <label> Add security label to ConfigFile"
cfgbootpolicy_help = "cfgbootpolicy <policy> Add policy to boot configuration "
dumppolicy_help = "dumppolicy Print hypervisor ACM state information"
loadpolicy_help = "loadpolicy <policy> Load binary policy into hypervisor"
makepolicy_help = "makepolicy <policy> Build policy and create .bin/.map files"
labels_help = "labels [policy] [type=DOM|..] List <type> labels for (active) policy."
short_command_list = [
"console",
@@ -140,6 +149,7 @@ domain_commands = [
"domid",
"domname",
"list",
"list_label",
"mem-max",
"mem-set",
"migrate",
@@ -185,8 +195,17 @@ vnet_commands = [
"vnet-delete",
]
acm_commands = [
"labels",
"addlabel",
"makepolicy",
"loadpolicy",
"cfgbootpolicy",
"dumppolicy"
]
all_commands = (domain_commands + host_commands + scheduler_commands +
device_commands + vnet_commands)
device_commands + vnet_commands + acm_commands)
def commandToHelp(cmd):
@@ -225,6 +244,9 @@ xm full list of subcommands:
Vnet commands:
""" + help_spacer.join(map(commandToHelp, vnet_commands)) + """
Access Control commands:
""" + help_spacer.join(map(commandToHelp, acm_commands)) + """
<DomName> can be substituted for <DomId> in xm subcommands.
For a short list of subcommands run 'xm help'
@@ -332,8 +354,9 @@ def getDomains(domain_names):
def xm_list(args):
use_long = 0
show_vcpus = 0
show_labels = 0
try:
(options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus'])
(options, params) = getopt.gnu_getopt(args, 'lv', ['long','vcpus','label'])
except getopt.GetoptError, opterr:
err(opterr)
sys.exit(1)
@@ -343,6 +366,8 @@ def xm_list(args):
use_long = 1
if k in ['-v', '--vcpus']:
show_vcpus = 1
if k in ['--label']:
show_labels = 1
if show_vcpus:
print >>sys.stderr, (
@@ -354,6 +379,8 @@ def xm_list(args):
if use_long:
map(PrettyPrint.prettyprint, doms)
elif show_labels:
xm_label_list(doms)
else:
xm_brief_list(doms)
@@ -369,7 +396,7 @@ def parse_doms_info(info):
'vcpus' : get_info('online_vcpus', int, 0),
'state' : get_info('state', str, '??'),
'cpu_time' : get_info('cpu_time', float, 0),
'ssidref' : get_info('ssidref', int, 0),
'seclabel' : security.get_security_printlabel(info),
}
@@ -391,13 +418,29 @@ def xm_brief_list(doms):
print 'Name ID Mem(MiB) VCPUs State Time(s)'
for dom in doms:
d = parse_doms_info(dom)
if (d['ssidref'] != 0):
d['ssidstr'] = (" s:%04x/p:%04x" %
((d['ssidref'] >> 16) & 0xffff,
d['ssidref'] & 0xffff))
print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f" % d)
def xm_label_list(doms):
output = []
print 'Name ID Mem(MiB) VCPUs State Time(s) Label'
for dom in doms:
d = parse_doms_info(dom)
l = "%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f " % d
if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
if d['seclabel']:
line = (l, d['seclabel'])
else:
line = (l, "ERROR")
elif security.active_policy in ['DEFAULT']:
line = (l, "DEFAULT")
else:
d['ssidstr'] = ""
print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f%(ssidstr)s" % d)
line = (l, "INACTIVE")
output.append(line)
#sort by labels
output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
for l in output:
print l[0] + l[1]
def xm_vcpu_list(args):
@@ -1010,7 +1053,13 @@ subcommands = [
'create',
'migrate',
'sysrq',
'shutdown'
'shutdown',
'labels',
'addlabel',
'cfgbootpolicy',
'makepolicy',
'loadpolicy',
'dumppolicy'
]
for c in subcommands:
+53
View File
@@ -0,0 +1,53 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 International Business Machines Corp.
# Author: Reiner Sailer <sailer@us.ibm.com>
#============================================================================
"""Compiling a XML source policy file into mapping and binary versions.
"""
import sys
import traceback
import os
import commands
import shutil
import string
from xen.util.security import ACMError, err, make_policy
def usage():
print "\nUsage: xm makepolicy <policy>\n"
print " Translate an XML source policy and create"
print " mapping file and binary policy.\n"
err("Usage")
def main(argv):
try:
if len(argv) != 2:
usage()
make_policy(argv[1])
except ACMError:
pass
except:
traceback.print_exc(limit=1)
if __name__ == '__main__':
main(sys.argv)
+6 -18
View File
@@ -30,28 +30,23 @@ SRCS_TOOL = secpol_tool.c
OBJS_TOOL := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_TOOL)))
SRCS_XML2BIN = secpol_xml2bin.c secpol_xml2bin.h
OBJS_XML2BIN := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_XML2BIN)))
SRCS_GETD = get_decision.c
OBJS_GETD := $(patsubst %.c,%.o,$(filter %.c,$(SRCS_GETD)))
ACM_INST_TOOLS = xensec_tool xensec_xml2bin xensec_gen
ACM_NOINST_TOOLS = get_decision
ACM_OBJS = $(OBJS_TOOL) $(OBJS_XML2BIN) $(OBJS_GETD)
ACM_SCRIPTS = getlabel.sh setlabel.sh updategrub.sh labelfuncs.sh
ACM_SCRIPTS = python/xensec_tools/acm_getlabel python/xensec_tools/acm_getdecision
ACM_CONFIG_DIR = /etc/xen/acm-security
ACM_POLICY_DIR = $(ACM_CONFIG_DIR)/policies
ACM_SCRIPT_DIR = $(ACM_CONFIG_DIR)/scripts
ACM_INST_HTML = python/xensec_gen/index.html
ACM_INST_CGI = python/xensec_gen/cgi-bin/policy.cgi \
python/xensec_gen/cgi-bin/policylabel.cgi
ACM_INST_CGI = python/xensec_gen/cgi-bin/policy.cgi
ACM_SECGEN_HTMLDIR= /var/lib/xensec_gen
ACM_SECGEN_CGIDIR = $(ACM_SECGEN_HTMLDIR)/cgi-bin
ACM_SCHEMA = security_policy.xsd
ACM_EXAMPLES = null chwall ste chwall_ste
ACM_EXAMPLES = chwall ste chwall_ste
ACM_POLICY_SUFFIX = security_policy.xml
ACM_LABEL_SUFFIX = security_label_template.xml
ifeq ($(ACM_SECURITY),y)
.PHONY: all
@@ -64,10 +59,10 @@ install: all $(ACM_CONFIG_FILE)
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_CONFIG_DIR)
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)
$(INSTALL_DATA) -p policies/$(ACM_SCHEMA) $(DESTDIR)$(ACM_POLICY_DIR)
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)/example
for i in $(ACM_EXAMPLES); do \
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
$(INSTALL_DATA) -p policies/$$i/$$i-$(ACM_POLICY_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
$(INSTALL_DATA) -p policies/$$i/$$i-$(ACM_LABEL_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/$$i; \
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_POLICY_DIR)/example/$$i; \
$(INSTALL_DATA) -p policies/example/$$i/client_v1-$(ACM_POLICY_SUFFIX) $(DESTDIR)$(ACM_POLICY_DIR)/example/$$i; \
done
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_SCRIPT_DIR)
$(INSTALL_PROG) -p $(ACM_SCRIPTS) $(DESTDIR)$(ACM_SCRIPT_DIR)
@@ -99,9 +94,6 @@ xensec_tool: $(OBJS_TOOL)
xensec_xml2bin: $(OBJS_XML2BIN)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
get_decision: $(OBJS_GETD)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
xensec_gen: xensec_gen.py
cp -f $^ $@
@@ -116,8 +108,4 @@ clean:
.PHONY: mrproper
mrproper: clean
.PHONY: boot_install
boot_install: install
$(ACM_SCRIPT_DIR)/updategrub.sh $(POLICY) $(KERNEL_VERSION)
-include $(PROG_DEPS)
+213 -219
View File
@@ -3,119 +3,79 @@
#
# Author:
# Reiner Sailer 08/15/2005 <sailer@watson.ibm.com>
# 04/07/2006 update to using labels instead of ssidref
#
#
# This file introduces into the tools to manage policies
# and to label domains and resources.
##
We will show how to install and use the example chwall_ste policy.
Other policies work similarly. Feedback welcome!
We will show how to install and use the example one of the client_v1
policies. Other policies work similarly. Feedback welcome!
1. Using xensec_xml2bin to translate the chwall_ste policy:
===========================================================
1. Using xm tools to translate example.chwall_ste.client_v1 policy:
===================================================================
#xensec_xml2bin chwall_ste
Successful execution should print:
[root@laptopxn security]# xensec_xml2bin chwall_ste
Validating label file /etc/xen/acm-security/policies/chwall_ste/chwall_ste-security_label_template.xml...
XML Schema /etc/xen/acm-security/policies/security_policy.xsd valid.
Validating policy file /etc/xen/acm-security/policies/chwall_ste/chwall_ste-security_policy.xml...
XML Schema /etc/xen/acm-security/policies/security_policy.xsd valid.
Creating ssid mappings ...
Creating label mappings ...
Max chwall labels: 7
Max chwall-types: 4
Max chwall-ssids: 5
Max ste labels: 14
Max ste-types: 6
Max ste-ssids: 10
#xm makepolicy example.chwall_ste.client_v1
By default, the tool looks in directory /etc/xen/acm-security/policies
for a directory that matches the policy name (i.e. chwall_ste) to find
the label and policy files.
The '-d' option can be used to override the /etc/xen/acm-security/policies
directory, for example if running the tool in the Xen security tool build
directory.
for a directory that matches the policy name
(here:example/chwall_ste/client_v1-security_policy.xml) to find the
policy files. The '-d' option can be used to override the default
/etc/xen/acm-security/policies policy-root directory.
The default policy directory structure under /etc/xen/acm-security (and
the Xen security tool build directory - tools/security) looks like:
policies
|-- security_policy.xsd
|-- chwall
| |-- chwall-security_label_template.xml
| `-- chwall-security_policy.xml
|-- chwall_ste
| |-- chwall_ste-security_label_template.xml
| `-- chwall_ste-security_policy.xml
|-- null
| |-- null-security_label_template.xml
| `-- null-security_policy.xml
`-- ste
|-- ste-security_label_template.xml
`-- ste-security_policy.xml
|-- example
|-- chwall
| |-- client_v1-security_policy.xml
|
|-- chwall_ste
| |-- client_v1-security_policy.xml
|
|-- ste
|-- client_v1-security_policy.xml
The security_policy.xsd file contains the schema against which both the
label-template and the policy files must validate during translation.
The security_policy.xsd file contains the schema against which the
policy files must validate during translation.
The files ending in -security_policy.xml define the policies and the
types known to the policies.
The policy files, ending in -security_policy.xml, define the policies,
the types known to the policies, and the label definitions that group
types together and make them easier to use for users.
The files ending in -security_label_template.xml contain the label
definitions that group types together and make them easier to use for
users.
After executing the above 'xm makepolicy' command, you will find 2 new
files in the /etc/xen/acm-security/policies/example/chwall_ste
sub-directory:
After executing the above xensec_xml2bin command, you will find 2 new
files in the /etc/xen/acm-security/policies/chwall_ste sub-directory:
chwall_ste.map ... this file includes the mapping
client_v1.map ... this file includes the mapping
of names from the xml files into their binary code representation.
chwall_ste.bin ... this is the binary policy file,
the result of parsing the xml files and using the mapping to extract a
binary version that can be loaded into the hypervisor.
client_v1.bin ... this is the binary policy file, the result of
parsing the xml files and using the mapping to create a binary
version that can be loaded into the hypervisor.
2. Loading and activating the policy:
=====================================
We assume that xen is already configured to use the chwall_ste policy;
We assume that xen is already configured for security;
please refer to install.txt for instructions.
To activate the policy from the command line (assuming that the
currently established policy is the minimal boot-policy that is
hard-coded into the hypervisor):
To activate the policy from the command line:
# xensec_tool loadpolicy /etc/xen/acm-security/policies/chwall_ste/chwall_ste.bin
To activate the policy at next reboot:
# cp /etc/xen/acm-security/policies/chwall_ste/chwall_ste.bin /boot
Add a module line to your /boot/grub/grub.conf Xen entry.
My boot entry with chwall_ste enabled looks like this:
title Xen (2.6.12)
root (hd0,5)
kernel /boot/xen.gz dom0_mem=1200000 console=vga
module /boot/vmlinuz-2.6.12-xen0 ro root=/dev/hda6 rhgb
module /boot/initrd-2.6.12-xen0.img
module /boot/chwall_ste.bin
This tells the grub boot-loader to load the binary policy, which
the hypervisor will recognize. The hypervisor will then establish
this binary policy during boot instead of the minimal policy that
is hardcoded as default.
If you have any trouble here, maks sure you have the access control
framework enabled (see: install.txt).
# xm loadpolicy example.chwall_ste.client_v1
See install.txt for how to install a policy at boot time. This the
recommended default. You can only load a policy if the currently
enforced policy is "DEFAULT", a minimal startup policy, or if the
currently enforced policy has the same name as the new one. Support
for dynamic policy changes at run-time are a current working item.
3. Labeling domains:
@@ -127,156 +87,143 @@ The chwall_ste-security_label_template.xml file includes an attribute
"bootstrap", which is set to the label name that will be assigned to
Dom0 (this label will be mapped to ssidref 1/1, the default for Dom0).
b) Labeling User Domains:
Use the script tools/security/setlabel.sh to choose a label and to
assign labels to user domains.
To show available labels for the chwall_ste policy:
# /etc/xen/acm-security/scripts/setlabel.sh -l
lists all available labels. For the default chwall_ste it should print
the following:
[root@laptopxn security]# /etc/xen/acm-security/scripts/setlabel.sh -l chwall_ste
The following labels are available:
dom_SystemManagement
dom_HomeBanking
dom_Fun
dom_BoincClient
dom_StorageDomain
dom_NetworkDomain
You need to have compiled the policy beforehand so that a .map file
exists. Setlabel.sh uses the mapping file created throughout the
policy translation to translate a user-friendly label string into a
ssidref-number that is eventually used by the Xen hypervisor.
b) Labeling User Domains (domains started from dom0 using xm commands):
We distinguish two kinds of labels: a) VM labels (for domains) and RES
Labels (for resources). We are currently working on support for
resource labeling but will focus here on VM labels.
Labels (for resources). We focus here on VM labels. Resource labels
will be supported later.
Setlabel.sh only prints VM labels (which we have prefixed with "dom_")
since only those are used at this time.
To list all available domain labels of a policy, use:
#xm labels example.chwall_ste.client_v1
If you would like to assign the dom_HomeBanking label to one of your
user domains (which you hopefully keep clean), look at the hypothetical
domain configuration contained in /etc/xen/homebanking.xm:
To list all available labels including resource labels (their support
is current work), use:
#------HOMEBANKING---------
kernel = "/boot/vmlinuz-2.6.12-xenU"
#xm labels example.chwall_ste.client_v1 type=any
The policy parameter is optional. The currently enforced hypervisor
policy is used by default.
If you would like to assign the dom_HomeBanking label to one of your user domains,
look at the hypothetical domain configuration contained in /etc/xen/homebanking.xm:
#------FOR HOME/ONLINE BANKING---------
kernel = "/boot/vmlinuz-2.6.16-xen"
ramdisk="/boot/U1_ramdisk.img"
memory = 65
name = "test34"
cpu = -1 # leave to Xen to pick
# Number of network interfaces. Default is 1.
nics=1
dhcp="dhcp"
memory = 164
name = "homebanking"
vif=['']
dhcp = "dhcp"
#-------------------------
Now we label this domain
Now we label this domain (policy name is optional, see above):
[root@laptopxn security]# /etc/xen/acm-securit/scripts/setlabel.sh /etc/xen/homebanking.xm dom_HomeBanking chwall_ste
Mapped label 'dom_HomeBanking' to ssidref '0x00020002'.
# xm addlabel homebanking.xm dom_HomeBanking example.chwall_ste.client_v1
The domain configuration my look now like:
The domain configuration should look now like:
[root@laptopxn security]# cat homebanking.xm
#------HOMEBANKING---------
kernel = "/boot/vmlinuz-2.6.12-xenU"
# cat homebanking.xm
#------FOR HOME/ONLINE BANKING---------
kernel = "/boot/vmlinuz-2.6.16-xen"
ramdisk="/boot/U1_ramdisk.img"
memory = 65
name = "test34"
cpu = -1 # leave to Xen to pick
# Number of network interfaces. Default is 1.
nics=1
dhcp="dhcp"
#-------------------------
#ACM_POLICY=chwall_ste-security_policy.xml
#ACM_LABEL=dom_HomeBanking
ssidref = 0x00020002
memory = 164
name = "homebanking"
vif=['']
dhcp = "dhcp"
access_control = ['policy=example.chwall_ste.client_v1, label=dom_HomeBanking']
You can see 3 new entries, two of which are comments. The only value
that the hypervisor cares about is the ssidref that will reference
those types assigned to this label. You can look them up in the
xml label-template file for the chwall_ste policy.
You can see the access_control line that was added to the
configuration. This label will be translated into a local ssidref when
a domain is created or resumed (also after migration and
live-migration). The ssidref is a local security reference that is
used inside the hypervisor instead of the security label for
efficiency reasons. Since the same label can be mapped onto different
ssidrefs in different policy translations (e.g., if the position of
the label definition is changed in the policy file) or on different
systems, the ssidref is re-calculated from the label each time a
domain is instantiated or re-instantiated.
This script will eventually move into the domain management and will
be called when the domain is instantiated. For now, the setlabel
script must be run on domains whenever the policy files change since
the mapping between label names and ssidrefs can change in this case.
Currently, the labels are not held in the hypervisor but only in
.map files in the /etc/xen/acm-security/policies subdirectories. Only
ssidrefs are known inside the hypervisr. This of course can change in
the future.
4. Starting a labeled domain
============================
Now, start the domain:
#xm create -c homebanking.xm
#xm create homebanking.xm
Using config file "homebanking.xm".
Started domain fun
If you label another domain configuration as dom_Fun and try to start
it afterwards, its start will fail. Why?
[root@941e-4 VMconfigs]# xm list --label
Because the running homebanking domain has the chinese wall type
"cw_Sensitive". The new domain dom_Fun has the chinese wall label
"cw_Distrusted". This domain is not allowed to run simultaneously
because of the defined conflict set
Name ID Mem(MiB) VCPUs State Time(s) Label
fun 1 64 1 -b---- 5.9 dom_HomeBanking
Domain-0 0 1954 1 r----- 1321.4 dom_SystemManagement
If you label another domain configuration as dom_Fun and if
you try to start it afterwards, this create will fail.
Why? -- Because the running 'homebanking' domain has the chinese
wall type "cw_Sensitive". The new domain 'fun' has the chinese wall
label "cw_Distrusted". These domains are not allowed to run simultaneously
on the same system because of the defined conflict set
<conflictset name="Protection1">
<type>cw_Sensitive</type>
<type>cw_Distrusted</type>
</conflictset>
(in chwall_ste-security_policy.xml), which says that only one of the
(in client_v1-security_policy.xml), which says that only one of the
types cw_Sensitive and cw_Distrusted can run at a time.
If you save or shutdown the HomeBanking domain, you will be able to
start the "Fun" domain. You can look into the Xen log to see if a
If you save or shutdown the 'homebanking' domain, you will be able to
start the 'fun' domain. You can look into the Xen log to see if a
domain was denied to start because of the access control framework
with the command 'xm dmesg'.
It is important (and usually non-trivial) to define the labels in a
way that the semantics of the labels are enforced and supported by the
types and the conflict sets.
types and the conflict sets. Usually, a workload abstraction seems
helpful on the hypervisor level.
Note: While the chinese wall policy enforcement is complete, the type
enforcement is currently enforced in the Xen hypervisor
enforcement is currently enforced inside the Xen hypervisor
only. Therefore, only point-to-point sharing with regard to the type
enforcement is currently controlled. We are working on enhancements to
Dom0 that enforce types also for network traffic that is routed
through Dom0 and on the enforcement of resource labeling when binding
resources to domains (e.g., enforcing types between domains and
hardware resources, such as disk partitions).
enforcement is currently controlled. Enforcing the STE policy while
sharing virtual resources is ongoing work and assumed to be complete
by year end as well as enforcing the STE policy for network traffic
routed through dom0.
4. Adding your own policies
5. Adding your own policies
===========================
Writing your own policy (e.g. "mypolicy") requires the following:
Writing your own policy (e.g. "mypolicy.chwall.test") requires the policy
definition (types etc.) and the label definitions. Any policy name
must have chwall, ste, or chwall_ste in its name. This is used by the
configuration tool to identify existing binary policy entries in the
boot configuration file (menu.lst, grub.con). This part should, of
course, be consistent with policy type that is defined.
a) the policy definition (types etc.) file
b) the label template definition (labels etc.) file
If your policy name is "mypolicy", you need to create a
subdirectory mypolicy in /etc/xen/acm-security/policies.
Then you create
/etc/xen/acm-security/policies/mypolicy/mypolicy-security_policy.xml and
/etc/xen/acm-security/policies/mypolicy/mypolicy-security_label_template.xml.
First, you create
/etc/xen/acm-security/policies/mypolicy/chwall/test-security_policy.xml.
You need to keep to the schema as defined in
/etc/xen/acm-security/security_policy.xsd since the translation tool
xensec_xml2bin is written against this schema.
If you keep to the security policy schema, then you can use all the
tools described above. Refer to install.txt to install it.
/etc/xen/acm-security/security_policy.xsd since the translation tools
are written against this schema.
You can hand-edit the xml files to create your policy or you can use the
xensec_gen utility.
5. Generating policy files using xensec_gen:
6. Generating policy files using xensec_gen:
============================================
The xensec_gen utility starts a web-server that can be used to generate the
@@ -290,25 +237,28 @@ to see the full list of options available.
Once the xensec_gen utility is running, point a browser at the host and port
on which the utility is running (e.g. http://localhost:7777/). You will be
presented with a web page that allows you to create or modify the XML policy
files:
file:
- The Security Policy section allows you to create or modify a policy
definition file
- The Security Policy types section allows you to create or modify
the policy types and conflict set definitions
- The Security Policy Labeling section allows you to create or modify a
label template definition file
label definitions
Security Policy:
----------------
The Security Policy section allows you to modify an existing policy definition
file or create a new policy definition file. To modify an existing policy
definition, enter the full path to the existing file (the "Browse" button can
be used to aid in this) in the Policy File entry field. To create a new
policy definition file leave the Policy File entry field blank. At this point
click the "Create" button to begin modifying or creating your policy definition.
The policy generation tool allows you to modify an existing policy
definition or create a new policy definition file. To modify an
existing policy definition, enter the full path to the existing file
(the "Browse" button can be used to aid in this) in the Policy File
entry field. To create a new policy definition file leave the Policy
File entry field blank. At this point click the "Create" button to
begin modifying or creating your policy definition.
You will then be presented with a web page that will allow you to create either
Simple Type Enforcement types or Chinese Wall types or both.
Security Policy Types Section
-----------------------------
You will then be presented with a web page. The upper part of it will
allow you to create either Simple Type Enforcement types or Chinese
Wall types or both, as well as Chinese Wall conflict type sets.
As an example:
- To add a Simple Type Enforcement type:
@@ -326,32 +276,13 @@ files:
Wall Conflict Set will allow you to add Chinese Wall types from the list of
defined Chinese Wall types.
To create your policy definition file, click on the "Generate XML" button on
the top of the page. This will present you with a dialog box to save the
generated XML file on your system. The default name will be security_policy.xml
which you should change to follow the policy file naming conventions based on
the policy name that you choose to use.
To get a feel for the tool, you could use one of the example policy definition
files from /etc/xen/acm-security/policies as input.
Security Policy Labeling:
-------------------------
The Security Policy Labeling section allows you to modify an existing label
template definition file or create a new label template definition file. To
modify an existing label template definition, enter the full path to the
existing file (the "Browse" button can be used to aid in this) in the Policy
Labeling File entry field. Whether creating a new label template definition
file or modifying an existing one, you will need to specify the policy
definition file that is or will be associated with this label template
definition file. At this point click the "Create" button to begin modifying
or creating your label template definition file.
You will then be presented with a web page that will allow you to create labels
for classes of virtual machines. The input policy definition file will provide
the available types (Simple Type Enforcement and/or Chinese Wall) that can be
assigned to a virtual machine class.
The security policy label section of the web page allows you to create labels
for classes of virtual machines. The input policy type definitions on the upper
part of the web page will provide the available types (Simple Type Enforcement
and/or Chinese Wall) that can be assigned to a virtual machine class.
As an example:
- To add a Virtual Machine class (the name entered will become the label
@@ -372,11 +303,74 @@ files:
bootstrap domain (or Dom0 domain). By default, the first Virtual Machine class
created will be associated as the bootstrap domain.
To create your label template definition file, click on the "Generate XML" button
To save your policy definition file, click on the "Generate XML" button
on the top of the page. This will present you with a dialog box to save the
generated XML file on your system. The default name will be
security_label_template.xml which you should change to follow the policy file
security_policy.xml which you should change to follow the policy file
naming conventions based on the policy name that you choose to use.
To get a feel for the tool, you could use one of the example policy definition
and label template definition files from /etc/xen/acm-security/policies as input.
To get a feel for the tool, you could use one of the example policy definitions
files from /etc/xen/acm-security/policies/example as input.
7. Hypervisor - OS Security Interface
=====================================
We currently provide 2 hypercalls through which user operating systems
can interact with the hypervisor Access Control Module. Examples of
using them are under "xen_root"/tools/security/python/xensec_tools:
I) acm_getdecision -i domainid -l labelname
Call this example script without arguments to show its usage
information.
This script enables a domain to retrieve an access control decision
regarding the STE policy from the hypervisor. It will be used to
control access to virtual/real resources in hosting domains.
The script can be provided with any combination of domain ids or
labelnames. Before calling into the hypervisor, labels are translated
into ssidrefs. The hypervisor then retrieves for any domain id
paramter the ssidref before deciding access.
Example:
#/etc/xen/acm-security/scripts/acm_getdecision -l dom_Fun
-l dom_SystemManagement
PERMITTED
#/etc/xen/acm-security/scripts/acm_getdecision -i 0 -i 1
PERMITTED
#/etc/xen/acm-security/scripts/acm_getdecision -i 0 -l dom_Fun
PERMITTED
#/etc/xen/acm-security/scripts/acm_getdecision -i 0 -l no_label
ACMError: Label 'nolabel' not found.
Now, assume domain 123454 does not exist:
#/etc/xen/acm-security/scripts/acm_getdecision -i 123454 -l dom_Fun
ACMError: Cannot determine decision (Invalid parameter).
Return values:
* DENIED: access is denied based on the current hypervisor
policy
* PERMITTED: access is permitted based on the current
* Exception ACMError: one of the parameters was illegal,
i.e. an unknown label or a
non-existing domain id
I) acm_getlabel -i domainid
Retrieves the label of a runing domain. This function can be used
by domains to determine their own label or (if authorized) the label
other domains.
Example (result is broken up into different lines to simplify description):
# /etc/xen/acm-security/scripts/acm_getlabel -i 0
('example.chwall.client_v1', <--- policy describing labels etc.
'dom_SystemManagement', <--- label name of the domain
'CHINESE WALL', <--- policy type
65537) <--- hypervisor internal ssidref
-176
View File
@@ -1,176 +0,0 @@
/****************************************************************
* get_decision.c
*
* Copyright (C) 2005 IBM Corporation
*
* Authors:
* 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.
*
* An example program that shows how to retrieve an access control
* decision from the hypervisor ACM based on the currently active policy.
*
*/
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <string.h>
#include <netinet/in.h>
#include <xen/acm.h>
#include <xen/acm_ops.h>
#include <xen/linux/privcmd.h>
#define PERROR(_m, _a...) \
fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
errno, strerror(errno))
void usage(char *progname)
{
printf("Use: %s \n", progname);
printf(" Test program illustrating the retrieval of\n");
printf(" access control decisions from xen. At this time,\n");
printf(" only sharing (STE) policy decisions are supported.\n");
printf(" parameter options:\n");
printf("\t -i domid -i domid\n");
printf("\t -i domid -s ssidref\n");
printf("\t -s ssidref -s ssidref\n\n");
exit(-1);
}
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_acm_op(int xc_handle, struct acm_op *op)
{
int ret = -1;
privcmd_hypercall_t hypercall;
op->interface_version = ACM_INTERFACE_VERSION;
hypercall.op = __HYPERVISOR_acm_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, "ACM operation failed -- need to"
" rebuild the user-space tool set?\n");
goto out2;
}
out2:(void) munlock(op, sizeof(*op));
out1:return ret;
}
/************************ get decision ******************************/
/* this example uses two domain ids and retrieves the decision if these domains
* can share information (useful, i.e., to enforce policy onto network traffic in dom0
*/
int acm_get_decision(int xc_handle, int argc, char *const argv[])
{
struct acm_op op;
int ret;
op.cmd = ACM_GETDECISION;
op.interface_version = ACM_INTERFACE_VERSION;
op.u.getdecision.get_decision_by1 = UNSET;
op.u.getdecision.get_decision_by2 = UNSET;
op.u.getdecision.hook = SHARING;
while (1) {
int c = getopt(argc, argv, "i:s:");
if (c == -1)
break;
if (c == 'i') {
if (op.u.getdecision.get_decision_by1 == UNSET) {
op.u.getdecision.get_decision_by1 = DOMAINID;
op.u.getdecision.id1.domainid = strtoul(optarg, NULL, 0);
} else if (op.u.getdecision.get_decision_by2 == UNSET) {
op.u.getdecision.get_decision_by2 = DOMAINID;
op.u.getdecision.id2.domainid = strtoul(optarg, NULL, 0);
} else
usage(argv[0]);
} else if (c == 's') {
if (op.u.getdecision.get_decision_by1 == UNSET) {
op.u.getdecision.get_decision_by1 = SSIDREF;
op.u.getdecision.id1.ssidref = strtoul(optarg, NULL, 0);
} else if (op.u.getdecision.get_decision_by2 == UNSET) {
op.u.getdecision.get_decision_by2 = SSIDREF;
op.u.getdecision.id2.ssidref = strtoul(optarg, NULL, 0);
} else
usage(argv[0]);
} else
usage(argv[0]);
}
if ((op.u.getdecision.get_decision_by1 == UNSET) ||
(op.u.getdecision.get_decision_by2 == UNSET))
usage(argv[0]);
if ((ret = do_acm_op(xc_handle, &op))) {
printf("%s: Error getting decision (%d).\n", __func__, ret);
printf("%s: decision = %s.\n", __func__,
(op.u.getdecision.acm_decision ==
ACM_ACCESS_PERMITTED) ? "PERMITTED" : ((op.u.getdecision.
acm_decision ==
ACM_ACCESS_DENIED)
? "DENIED" :
"ERROR"));
return ret;
}
return op.u.getdecision.acm_decision;
}
/***************************** main **************************************/
int main(int argc, char **argv)
{
int acm_cmd_fd, ret = 0;
if (argc < 5)
usage(argv[0]);
if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
printf("ERROR: Could not open xen privcmd device!\n");
exit(-1);
}
ret = acm_get_decision(acm_cmd_fd, argc, argv);
printf("Decision: %s (%d)\n",
(ret == ACM_ACCESS_PERMITTED) ? "PERMITTED" :
((ret == ACM_ACCESS_DENIED) ? "DENIED" : "ERROR"), ret);
close(acm_cmd_fd);
return ret;
}
-94
View File
@@ -1,94 +0,0 @@
#!/bin/sh
# *
# * getlabel
# *
# * Copyright (C) 2005 IBM Corporation
# *
# * Authors:
# * Stefan Berger <stefanb@us.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.
# *
# * 'getlabel' tries to find the labels corresponding to the ssidref
# *
# * 'getlabel -?' shows the usage of the program
# *
# * 'getlabel -sid <ssidref> [<policy name>]' lists the label corresponding
# * to the given ssidref.
# *
# * 'getlabel -dom <domain id> [<policy name>]' lists the label of the
# * domain with given id
# *
#
if [ -z "$runbash" ]; then
runbash="1"
export runbash
exec sh -c "bash $0 $*"
fi
export PATH=$PATH:.
dir=`dirname $0`
source $dir/labelfuncs.sh
usage ()
{
prg=`basename $0`
echo "Use this tool to display the label of a domain or the label that is
corresponding to an ssidref given the name of the running policy.
Usage: $prg -sid <ssidref> [<policy name> [<policy dir>]] or
$prg -dom <domid> [<policy name> [<policy dir>]]
policy name : the name of the policy, i.e. 'chwall'
If the policy name is omitted, the grub.conf
entry of the running system is tried to be read
and the policy name determined from there.
policy dir : the directory where the <policy name> policy is located
The default location is '/etc/xen/acm-security/policies'
ssidref : an ssidref in hex or decimal format, i.e., '0x00010002'
or '65538'
domid : id of the domain, i.e., '1'; Use numbers from the 2nd
column shown when invoking 'xm list'
"
}
if [ "$1" == "-h" ]; then
usage
exit 0
elif [ "$1" == "-dom" ]; then
mode="domid"
shift
elif [ "$1" == "-sid" ]; then
mode="sid"
shift
else
usage
exit -1
fi
setPolicyVars $2 $3
findMapFile $policy $policydir
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not find map file for policy '$policy'."
exit -1
fi
if [ "$mode" == "domid" ]; then
getSSIDUsingSecpolTool $1
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not determine the SSID of the domain."
exit -1
fi
translateSSIDREF $ssid $mapfile
else # mode == sid
translateSSIDREF $1 $mapfile
fi
+42 -24
View File
@@ -3,10 +3,11 @@
#
# Author:
# Reiner Sailer 08/15/2005 <sailer@watson.ibm.com>
# 03/18/2006 update: new labeling
#
#
# This file shows how to activate and install the access control
# framework.
# framework for Xen.
##
@@ -20,43 +21,54 @@ Simple Type Enforcement policy. Some file names need to be replaced
below to activate the Chinese Wall OR the Type Enforcement policy
exclusively (chwall_ste --> {chwall, ste}).
0. build and install the xm man page. It includes the description of
available management commands for the security policy for Xen and
the labeling of domains. If not installed by default, you can make
and install the xm man page as follows:
# cd "xen_root"/doc
# make install
Then, use man xm to read it:
# man xm
1. enable access control in Xen
# cd "xen_root"
# edit/xemacs/vi Config.mk
change the lines:
ACM_SECURITY ?= n
ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_POLICY
to:
ACM_SECURITY ?= y
Now the hypervisor will boot into the policy that is specified
in the grub configuration. If you would like to boot into a
specific policy (even if you can't specify a boot policy but
need to set the policy later using the 'xensec_tool
loadpolicy'), then use the other config parameter to change
from NULL to any other default policy, e.g.:
ACM_DEFAULT_SECURITY_POLICY ?= ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY
# make all
# make dist
# ./install.sh
2. compile the policy from xml to a binary format that can be loaded
into the hypervisor for enforcement
2. Build acm and policy tools and create boot-able policy:
# cd tools/security
# make
# make install
manual steps (alternative to make boot_install):
# ./xensec_xml2bin -d policies/ chwall_ste
# cp policies/chwall_ste/chwall_ste.bin /boot
# edit /boot/grub/grub.conf
add the follwoing line to your xen boot entry:
"module /boot/chwall_ste.bin"
For description of the following commands, please see the xm
man page (docs/man1/xm.1). If it is not built, then you can
create it manually: cd "xen_root"/docs; make; man man1/xm.1
alternatively, you can try our automatic translation and
installation of the policy:
# make boot_install
[we try hard to do the right thing to the right boot entry but
please verify boot entry in /boot/grub/grub.conf afterwards;
your xen boot entry should have an additional module line
specifying a chwall_ste.bin file with the correct directory
(e.g. "/" or "/boot").]
Step1: Building binary version of an example policy:
# xm makepolicy example.chwall_ste.client_v1
# xm cfgbootpolicy example.chwall_ste.client_v1
Please verify boot entry in /boot/grub/grub.conf (or menu.lst):
title Xen (2.6.16)
root (hd0,0)
kernel /xen.gz dom0_mem=2000000 console=vga
module /vmlinuz-2.6.16-xen ro root=/dev/VolGroup00/LogVol00 rhgb
module /initrd-2.6.165-xen-U.img
module /example.chwall_ste.client_v1.bin
3. reboot into the newly compiled hypervisor
@@ -64,6 +76,12 @@ exclusively (chwall_ste --> {chwall, ste}).
# xm dmesg should show an entry about the policy being loaded
during the boot process
# xensec_tool getpolicy
should print the new chwall_ste binary policy representation
# xm dumppolicy
should print the new binary policy representation
including the policy name example.chwall_ste.client_v1
# xm list --label
should show security label names behind the running domains
For more information about how to use the security-enabled Xen, see
the examples.txt file in this directory.
-799
View File
@@ -1,799 +0,0 @@
# *
# * labelfuncs.sh
# *
# * Copyright (C) 2005 IBM Corporation
# *
# * Authors:
# * Stefan Berger <stefanb@us.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.
# *
# *
# * A collection of functions to handle polcies, mapfiles,
# * and ssidrefs.
#
#Some global variables for tools using this module
ACM_DEFAULT_ROOT="/etc/xen/acm-security"
# Set the policy and policydir variables
# Parameters:
# 1st : possible policy name
# 2nd : possible policy directory
# Results:
# The variables policy and policydir will hold the values for locating
# policy information
# If there are no errors, the functions returns a '1',
# a '0' otherwise.
setPolicyVars ()
{
local ret
# Set default values
policydir="$ACM_DEFAULT_ROOT/policies"
policy=""
if [ "$1" == "" ]; then
findGrubConf
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not find grub.conf."
return 0;
fi
findPolicyInGrub $grubconf
if [ "$policy" == "" ]; then
echo "Could not find policy in grub.conf. Looked for entry using kernel $linux."
return 0;
fi
echo "Assuming policy to be '$policy'.";
else
policy=$1
if [ "$2" != "" ]; then
policydir=$2
fi
fi
return 1
}
# Find the mapfile given a policy nmame
# Parameters:
# 1st : the name of the policy whose map file is to be found, i.e.,
# chwall
# 2nd : the policy directory for locating the map file
# Results:
# The variable mapfile will hold the realtive path to the mapfile
# for the given policy.
# In case the mapfile could be found, the functions returns a '1',
# a '0' otherwise.
findMapFile ()
{
mapfile="$2/$1/$1.map"
if [ -r "$mapfile" ]; then
return 1
fi
return 0
}
# Determine the name of the primary policy
# Parameters
# 1st : the path to the mapfile; the path may be relative
# to the current directory
# Results
# The variable primary will hold the name of the primary policy
getPrimaryPolicy ()
{
local mapfile=$1
primary=`cat $mapfile | \
awk ' \
{ \
if ( $1 == "PRIMARY" ) { \
res=$2; \
} \
} END { \
print res; \
} '`
}
# Determine the name of the secondary policy
# Parameters
# 1st : the path to the mapfile; the path may be relative
# to the current directory
# Results
# The variable secondary will hold the name of the secondary policy
getSecondaryPolicy ()
{
local mapfile=$1
secondary=`cat $mapfile | \
awk ' \
{ \
if ( $1 == "SECONDARY" ) { \
res=$2; \
} \
} END { \
print res; \
} '`
}
#Return where the grub.conf file is.
#I only know of one place it can be.
#Returns:
# 1 : if the file is writeable and readable
# 2 : if the file is only readable
# 0 : if the file does not exist
findGrubConf()
{
grubconf="/boot/grub/grub.conf"
if [ -w $grubconf ]; then
return 1
fi
if [ -r $grubconf ]; then
return 2
fi
return 0
}
# This function sets the global variable 'linux'
# to the name and version of the Linux kernel that was compiled
# for domain 0.
# If this variable could not be found, the variable 'linux'
# will hold a pattern
# Parameters:
# 1st: the path to reach the root directory of the XEN build tree
# where linux-*-xen0 is located at
# Results:
# The variable linux holds then name and version of the compiled
# kernel, i.e., 'vmlinuz-2.6.12-xen0'
getLinuxVersion ()
{
local path
local versionfile
local lnx
if [ "$1" == "" ]; then
path="/lib/modules/*-xen0"
else
path="/lib/modules/$1"
fi
linux=""
for f in $path/linux-*-xen0 ; do
versionfile=$f/build/include/linux/version.h
if [ -r $versionfile ]; then
lnx=`cat $versionfile | \
grep UTS_RELEASE | \
awk '{ \
len=length($3); \
version=substr($3,2,len-2); \
split(version,numbers,"."); \
if (numbers[4]=="") { \
printf("%s.%s.%s", \
numbers[1], \
numbers[2], \
numbers[3]); \
} else { \
printf("%s.%s.%s[.0-9]*-xen0",\
numbers[1], \
numbers[2], \
numbers[3]); \
} \
}'`
fi
if [ "$lnx" != "" ]; then
linux="[./0-9a-zA-z]*$lnx"
return;
fi
done
#Last resort.
linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
}
# Find out with which policy the hypervisor was booted with.
# Parameters
# 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
# Result:
# Sets the variable 'policy' to the name of the policy
findPolicyInGrub ()
{
local grubconf=$1
local linux=`uname -r`
policy=`cat $grubconf | \
awk -vlinux=$linux '{ \
if ( $1 == "title" ) { \
kernelfound = 0; \
policymaycome = 0; \
} \
else if ( $1 == "kernel" ) { \
if ( match($2,"xen.gz$") ) { \
pathlen=RSTART; \
kernelfound = 1; \
} \
} \
else if ( $1 == "module" && \
kernelfound == 1 && \
match($2,linux) ) { \
policymaycome = 1; \
} \
else if ( $1 == "module" && \
kernelfound == 1 && \
policymaycome == 1 && \
match($2,"[0-9a-zA-Z_]*.bin$") ) { \
policymaycome = 0; \
kernelfound = 0; \
polname = substr($2,pathlen); \
len=length(polname); \
polname = substr(polname,0,len-4); \
} \
} END { \
print polname \
}'`
}
# Get the SSID of a domain
# Parameters:
# 1st : domain ID, i.e. '1'
# Results
# If the ssid could be found, the variable 'ssid' will hold
# the currently used ssid in the hex format, i.e., '0x00010001'.
# The funtion returns '1' on success, '0' on failure
getSSIDUsingSecpolTool ()
{
local domid=$1
export PATH=$PATH:.
ssid=`xensec_tool getssid -d $domid -f | \
grep -E "SSID:" | \
awk '{ print $4 }'`
if [ "$ssid" != "" ]; then
return 1
fi
return 0
}
# Break the ssid identifier into its high and low values,
# which are equal to the secondary and primary policy references.
# Parameters:
# 1st: ssid to break into high and low value, i.e., '0x00010002'
# Results:
# The variable ssidlo_int and ssidhi_int will hold the low and
# high ssid values as integers.
getSSIDLOHI ()
{
local ssid=$1
ssidlo_int=`echo $ssid | awk \
'{ \
len=length($0); \
beg=substr($0,1,2); \
if ( beg == "0x" ) { \
dig = len - 2; \
if (dig <= 0) { \
exit; \
} \
if (dig > 4) { \
dig=4; \
} \
lo=sprintf("0x%s",substr($0,len-dig+1,dig)); \
print strtonum(lo);\
} else { \
lo=strtonum($0); \
if (lo < 65536) { \
print lo; \
} else { \
hi=lo; \
hi2= (hi / 65536);\
hi2_str=sprintf("%d",hi2); \
hi2=strtonum(hi2_str);\
lo=hi-(hi2*65536); \
printf("%d",lo); \
} \
} \
}'`
ssidhi_int=`echo $ssid | awk \
'{ \
len=length($0); \
beg=substr($0,1,2); \
if ( beg == "0x" ) { \
dig = len - 2; \
if (dig <= 0 || \
dig > 8) { \
exit; \
} \
if (dig < 4) { \
print 0; \
exit; \
} \
dig -= 4; \
hi=sprintf("0x%s",substr($0,len-4-dig+1,dig)); \
print strtonum(hi);\
} else { \
hi=strtonum($0); \
if (hi >= 65536) { \
hi = hi / 65536; \
printf ("%d",hi);\
} else { \
printf ("0"); \
} \
} \
}'`
if [ "$ssidhi_int" == "" -o \
"$ssidlo_int" == "" ]; then
return 0;
fi
return 1
}
#Update the grub configuration file.
#Search for existing entries and replace the current
#policy entry with the policy passed to this script
#
#Arguments passed to this function
# 1st : the grub configuration file with full path
# 2nd : the binary policy file name, i.e. chwall.bin
# 3rd : the name or pattern of the linux kernel name to match
# (this determines where the module entry will be made)
#
# The algorithm here is based on pattern matching
# and is working correctly if
# - under a title a line beginning with 'kernel' is found
# whose following item ends with "xen.gz"
# Example: kernel /xen.gz dom0_mem=....
# - a module line matching the 3rd parameter is found
#
updateGrub ()
{
local grubconf=$1
local policyfile=$2
local linux=$3
local tmpfile="/tmp/new_grub.conf"
cat $grubconf | \
awk -vpolicy=$policyfile \
-vlinux=$linux '{ \
if ( $1 == "title" ) { \
kernelfound = 0; \
if ( policymaycome == 1 ){ \
printf ("\tmodule %s%s\n", path, policy); \
} \
policymaycome = 0; \
} \
else if ( $1 == "kernel" ) { \
if ( match($2,"xen.gz$") ) { \
path=substr($2,1,RSTART-1); \
kernelfound = 1; \
} \
} \
else if ( $1 == "module" && \
kernelfound == 1 && \
match($2,linux) ) { \
policymaycome = 1; \
} \
else if ( $1 == "module" && \
kernelfound == 1 && \
policymaycome == 1 && \
match($2,"[0-9a-zA-Z]*.bin$") ) { \
printf ("\tmodule %s%s\n", path, policy); \
policymaycome = 0; \
kernelfound = 0; \
dontprint = 1; \
} \
else if ( $1 == "" && \
kernelfound == 1 && \
policymaycome == 1) { \
dontprint = 1; \
} \
if (dontprint == 0) { \
printf ("%s\n", $0); \
} \
dontprint = 0; \
} END { \
if ( policymaycome == 1 ) { \
printf ("\tmodule %s%s\n", path, policy); \
} \
}' > $tmpfile
if [ ! -r $tmpfile ]; then
echo "Could not create temporary file! Aborting."
exit -1
fi
diff $tmpfile $grubconf > /dev/null
RES=$?
if [ "$RES" == "0" ]; then
echo "No changes were made to $grubconf."
else
echo "Successfully updated $grubconf."
mv -f $tmpfile $grubconf
fi
}
#Compile a policy into its binary representation
# Parameters:
# 1st: The directory where the ./policies directory is located at
# 2nd: The name of the policy
genBinPolicy ()
{
local root=$1
local policy=$2
pushd $root > /dev/null
xensec_xml2bin -d policies $policy > /dev/null
popd > /dev/null
}
# Copy the bootpolicy into the destination directory
# Generate the policy's .bin and .map files if necessary
# Parameters:
# 1st: Destination directory
# 2nd: The root directory of the security tools; this is where the
# policies directory is located at
# 3rd: The policy name
# Returns '1' on success, '0' on failure.
cpBootPolicy ()
{
local dest=$1
local root=$2
local policy=$3
local binfile=$root/policies/$policy/$policy.bin
local dstfile=$dest/$policy.bin
if [ ! -e $binfile ]; then
genBinPolicy $root $policy
if [ ! -e $binfile ]; then
echo "Could not compile policy '$policy'."
return 0
fi
fi
if [ ! -e $dstfile -o \
$binfile -nt $dstfile ]; then
cp -f $binfile $dstfile
fi
return 1
}
# Display all the labels in a given mapfile
# Parameters
# 1st: Full or relative path to the policy's mapfile
showLabels ()
{
local mapfile=$1
local line
local ITEM
local found=0
if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
echo "Cannot read from vm configuration file $vmfile."
return -1
fi
getPrimaryPolicy $mapfile
getSecondaryPolicy $mapfile
echo "The following labels are available:"
let line=1
while [ 1 ]; do
ITEM=`cat $mapfile | \
awk -vline=$line \
-vprimary=$primary \
'{ \
if ($1 == "LABEL->SSID" && \
$2 == "VM" && \
$3 == primary ) { \
ctr++; \
if (ctr == line) { \
print $4; \
} \
} \
} END { \
}'`
if [ "$ITEM" == "" ]; then
break
fi
if [ "$secondary" != "NULL" ]; then
LABEL=`cat $mapfile | \
awk -vitem=$ITEM \
'{
if ($1 == "LABEL->SSID" && \
$2 == "VM" && \
$3 == "CHWALL" && \
$4 == item ) { \
result = item; \
} \
} END { \
print result \
}'`
else
LABEL=$ITEM
fi
if [ "$LABEL" != "" ]; then
echo "$LABEL"
found=1
fi
let line=line+1
done
if [ "$found" != "1" ]; then
echo "No labels found."
fi
}
# Get the default SSID given a mapfile and the policy name
# Parameters
# 1st: Full or relative path to the policy's mapfile
# 2nd: the name of the policy
getDefaultSsid ()
{
local mapfile=$1
local pol=$2
RES=`cat $mapfile \
awk -vpol=$pol \
{ \
if ($1 == "LABEL->SSID" && \
$2 == "ANY" && \
$3 == pol && \
$4 == "DEFAULT" ) {\
res=$5; \
} \
} END { \
printf "%04x", strtonum(res) \
}'`
echo "default NULL mapping is $RES"
defaultssid=$RES
}
#Relabel a VM configuration file
# Parameters
# 1st: Full or relative path to the VM configuration file
# 2nd: The label to translate into an ssidref
# 3rd: Full or relative path to the policy's map file
# 4th: The mode this function is supposed to operate in:
# 'relabel' : Relabels the file without querying the user
# other : Prompts the user whether to proceed
relabel ()
{
local vmfile=$1
local label=$2
local mapfile=$3
local mode=$4
local SSIDLO
local SSIDHI
local RES
if [ ! -r "$vmfile" ]; then
echo "Cannot read from vm configuration file $vmfile."
return -1
fi
if [ ! -w "$vmfile" ]; then
echo "Cannot write to vm configuration file $vmfile."
return -1
fi
if [ ! -r "$mapfile" ] ; then
echo "Cannot read mapping file $mapfile."
return -1
fi
# Determine which policy is primary, which sec.
getPrimaryPolicy $mapfile
getSecondaryPolicy $mapfile
# Calculate the primary policy's SSIDREF
if [ "$primary" == "NULL" ]; then
SSIDLO="0001"
else
SSIDLO=`cat $mapfile | \
awk -vlabel=$label \
-vprimary=$primary \
'{ \
if ( $1 == "LABEL->SSID" && \
$2 == "VM" && \
$3 == primary && \
$4 == label ) { \
result=$5 \
} \
} END { \
if (result != "" ) \
{printf "%04x", strtonum(result)}\
}'`
fi
# Calculate the secondary policy's SSIDREF
if [ "$secondary" == "NULL" ]; then
if [ "$primary" == "NULL" ]; then
SSIDHI="0001"
else
SSIDHI="0000"
fi
else
SSIDHI=`cat $mapfile | \
awk -vlabel=$label \
-vsecondary=$secondary \
'{ \
if ( $1 == "LABEL->SSID" && \
$2 == "VM" && \
$3 == secondary && \
$4 == label ) { \
result=$5 \
} \
} END { \
if (result != "" ) \
{printf "%04x", strtonum(result)}\
}'`
fi
if [ "$SSIDLO" == "" -o \
"$SSIDHI" == "" ]; then
echo "Could not map the given label '$label'."
return -1
fi
ACM_POLICY=`cat $mapfile | \
awk ' { if ( $1 == "POLICY" ) { \
result=$2 \
} \
} \
END { \
if (result != "") { \
printf result \
} \
}'`
if [ "$ACM_POLICY" == "" ]; then
echo "Could not find 'POLICY' entry in map file."
return -1
fi
SSIDREF="0x$SSIDHI$SSIDLO"
if [ "$mode" != "relabel" ]; then
RES=`cat $vmfile | \
awk '{ \
if ( substr($1,0,7) == "ssidref" ) {\
print $0; \
} \
}'`
if [ "$RES" != "" ]; then
echo "Do you want to overwrite the existing mapping ($RES)? (y/N)"
read user
if [ "$user" != "y" -a "$user" != "Y" ]; then
echo "Aborted."
return 0
fi
fi
fi
#Write the output
local vmtmp1="/tmp/__setlabel.tmp1"
local vmtmp2="/tmp/__setlabel.tmp2"
touch $vmtmp1
touch $vmtmp2
if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
echo "Cannot create temporary files. Aborting."
return -1
fi
RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
echo "#ACM_LABEL=$label" >> $vmtmp1
echo "ssidref = $SSIDREF" >> $vmtmp1
mv -f $vmtmp1 $vmfile
rm -rf $vmtmp1 $vmtmp2
echo "Mapped label '$label' to ssidref '$SSIDREF'."
}
# Translate an ssidref into its label. This does the reverse lookup
# to the relabel function above.
# This function displays the results.
# Parameters:
# 1st: The ssidref to translate; must be in the form '0x00010002'
# 2nd: Full or relative path to the policy's mapfile
translateSSIDREF ()
{
local ssidref=$1
local mapfile=$2
local line1
local line2
if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
echo "Cannot read from vm configuration file $vmfile."
return -1
fi
getPrimaryPolicy $mapfile
getSecondaryPolicy $mapfile
if [ "$primary" == "NULL" -a "$secondary" == "NULL" ]; then
echo "There are no labels for the NULL policy."
return
fi
getSSIDLOHI $ssidref
ret=$?
if [ $ret -ne 1 ]; then
echo "Error while parsing the ssid ref number '$ssidref'."
fi;
let line1=0
let line2=0
while [ 1 ]; do
ITEM1=`cat $mapfile | \
awk -vprimary=$primary \
-vssidlo=$ssidlo_int \
-vline=$line1 \
'{ \
if ( $1 == "LABEL->SSID" && \
$3 == primary && \
int($5) == ssidlo ) { \
if (l == line) { \
print $4; \
exit; \
} \
l++; \
} \
}'`
ITEM2=`cat $mapfile | \
awk -vsecondary=$secondary \
-vssidhi=$ssidhi_int \
-vline=$line2 \
'{ \
if ( $1 == "LABEL->SSID" && \
$3 == secondary && \
int($5) == ssidhi ) { \
if (l == line) { \
print $4; \
exit; \
} \
l++; \
} \
}'`
if [ "$secondary" != "NULL" ]; then
if [ "$ITEM1" == "" ]; then
let line1=0
let line2=line2+1
else
let line1=line1+1
fi
if [ "$ITEM1" == "" -a \
"$ITEM2" == "" ]; then
echo "Could not determine the referenced label."
break
fi
if [ "$ITEM1" == "$ITEM2" ]; then
echo "Label: $ITEM1"
break
fi
else
if [ "$ITEM1" != "" ]; then
echo "Label: $ITEM1"
else
if [ "$found" == "0" ]; then
found=1
else
break
fi
fi
let line1=line1+1
fi
done
}
@@ -1,76 +0,0 @@
<?xml version="1.0"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security labels, which can -->
<!-- be attached to Domains and resources. Based on -->
<!-- these labels, the access control module decides -->
<!-- about sharing between Domains and about access -->
<!-- of Domains to real resources. -->
<SecurityLabelTemplate
xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<LabelHeader>
<Name>chwall-security_label_template</Name>
<Date>2005-08-10</Date>
<PolicyName>
<Url>chwall-security_policy.xml</Url>
<Reference>abcdef123456abcdef</Reference>
</PolicyName>
</LabelHeader>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<ChineseWallTypes>
<Type>cw_Sensitive</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<ChineseWallTypes>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<ChineseWallTypes>
<Type>cw_Isolated</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
</SecurityLabelTemplate>
@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<PolicyHeader>
<Name>chwall-security_policy</Name>
<Date>2005-08-10</Date>
</PolicyHeader>
<!-- -->
<!-- example of a chinese wall type definition -->
<!-- along with its conflict sets -->
<!-- (typse in a confict set are exclusive, i.e. -->
<!-- once a Domain with one type of a set is -->
<!-- running, no other Domain with another type -->
<!-- of the same conflict set can start.) -->
<ChineseWall priority="PrimaryPolicyComponent">
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
<Type>cw_Sensitive</Type>
<Type>cw_Isolated</Type>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
<ConflictSets>
<Conflict name="Protection1">
<Type>cw_Sensitive</Type>
<Type>cw_Distrusted</Type>
</Conflict>
</ConflictSets>
</ChineseWall>
</SecurityPolicyDefinition>
@@ -1,167 +0,0 @@
<?xml version="1.0"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security labels, which can -->
<!-- be attached to Domains and resources. Based on -->
<!-- these labels, the access control module decides -->
<!-- about sharing between Domains and about access -->
<!-- of Domains to real resources. -->
<SecurityLabelTemplate
xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<LabelHeader>
<Name>chwall_ste-security_label_template</Name>
<Date>2005-08-10</Date>
<PolicyName>
<Url>chwall_ste-security_policy.xml</Url>
<Reference>abcdef123456abcdef</Reference>
</PolicyName>
</LabelHeader>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Sensitive</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Isolated</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<!-- since dom0 needs access to every domain and -->
<!-- resource right now ... -->
<Type>ste_SystemManagement</Type>
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
<Type>ste_PersistentStorageA</Type>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (hard drive a) -->
<Type>ste_PersistentStorageA</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (ethernet card) -->
<Type>ste_NetworkAdapter0</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
<ObjectLabels>
<ResourceLabel>
<Name>res_ManagementResource</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_HardDrive (hda)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersistentStorageA</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition1 (hda1)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition2 (hda2)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_EthernetCard</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_SecurityToken</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_GraphicsAdapter</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
</ObjectLabels>
</SecurityLabelTemplate>
@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<PolicyHeader>
<Name>chwall_ste-security_policy</Name>
<Date>2005-08-10</Date>
</PolicyHeader>
<!-- -->
<!-- example of a simple type enforcement policy definition -->
<!-- -->
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type> <!-- machine/security management -->
<Type>ste_PersonalFinances</Type> <!-- personal finances -->
<Type>ste_InternetInsecure</Type> <!-- games, active X, etc. -->
<Type>ste_DonatedCycles</Type> <!-- donation to BOINC/seti@home -->
<Type>ste_PersistentStorageA</Type> <!-- domain managing the harddrive A-->
<Type>ste_NetworkAdapter0</Type> <!-- type of the domain managing ethernet adapter 0-->
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
<!-- -->
<!-- example of a chinese wall type definition -->
<!-- along with its conflict sets -->
<!-- (typse in a confict set are exclusive, i.e. -->
<!-- once a Domain with one type of a set is -->
<!-- running, no other Domain with another type -->
<!-- of the same conflict set can start.) -->
<ChineseWall priority="PrimaryPolicyComponent">
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
<Type>cw_Sensitive</Type>
<Type>cw_Isolated</Type>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
<ConflictSets>
<Conflict name="Protection1">
<Type>cw_Sensitive</Type>
<Type>cw_Distrusted</Type>
</Conflict>
</ConflictSets>
</ChineseWall>
</SecurityPolicyDefinition>
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com ../../security_policy.xsd ">
<PolicyHeader>
<PolicyName>example.chwall.client_v1</PolicyName>
<PolicyUrl>www.ibm.com/example/chwall/client_v1</PolicyUrl>
<Date>2006-03-31</Date>
</PolicyHeader>
<!-- -->
<!-- example of a chinese wall type definition -->
<!-- along with its conflict sets -->
<!-- (typse in a confict set are exclusive, i.e. -->
<!-- once a Domain with one type of a set is -->
<!-- running, no other Domain with another type -->
<!-- of the same conflict set can start.) -->
<ChineseWall priority="PrimaryPolicyComponent">
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
<Type>cw_Sensitive</Type>
<Type>cw_Isolated</Type>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
<ConflictSets>
<Conflict name="Protection1">
<Type>cw_Sensitive</Type>
<Type>cw_Distrusted</Type>
</Conflict>
</ConflictSets>
</ChineseWall>
<SecurityLabelTemplate>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<ChineseWallTypes>
<Type>cw_Sensitive</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<ChineseWallTypes>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<ChineseWallTypes>
<Type>cw_Isolated</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
</SecurityLabelTemplate>
</SecurityPolicyDefinition>
@@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com ../../security_policy.xsd ">
<PolicyHeader>
<PolicyName>example.chwall_ste.client_v1</PolicyName>
<PolicyUrl>www.ibm.com/example/chwall_ste/client_v1</PolicyUrl>
<Date>2006-03-31</Date>
</PolicyHeader>
<!-- -->
<!-- example of a simple type enforcement policy definition -->
<!-- -->
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type><!-- machine/security management -->
<Type>ste_PersonalFinances</Type><!-- personal finances -->
<Type>ste_InternetInsecure</Type><!-- games, active X, etc. -->
<Type>ste_DonatedCycles</Type><!-- donation to BOINC/seti@home -->
<Type>ste_PersistentStorageA</Type><!-- domain managing the harddrive A-->
<Type>ste_NetworkAdapter0</Type><!-- type of the domain managing ethernet adapter 0-->
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
<!-- -->
<!-- example of a chinese wall type definition -->
<!-- along with its conflict sets -->
<!-- (typse in a confict set are exclusive, i.e. -->
<!-- once a Domain with one type of a set is -->
<!-- running, no other Domain with another type -->
<!-- of the same conflict set can start.) -->
<ChineseWall priority="PrimaryPolicyComponent">
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
<Type>cw_Sensitive</Type>
<Type>cw_Isolated</Type>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
<ConflictSets>
<Conflict name="Protection1">
<Type>cw_Sensitive</Type>
<Type>cw_Distrusted</Type>
</Conflict>
</ConflictSets>
</ChineseWall>
<SecurityLabelTemplate>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Sensitive</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Distrusted</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_Isolated</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<!-- since dom0 needs access to every domain and -->
<!-- resource right now ... -->
<Type>ste_SystemManagement</Type>
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
<Type>ste_PersistentStorageA</Type>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (hard drive a) -->
<Type>ste_PersistentStorageA</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (ethernet card) -->
<Type>ste_NetworkAdapter0</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
<ChineseWallTypes>
<Type>cw_SystemManagement</Type>
</ChineseWallTypes>
</VirtualMachineLabel>
</SubjectLabels>
<ObjectLabels>
<ResourceLabel>
<Name>res_ManagementResource</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_HardDrive(hda)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersistentStorageA</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition1(hda1)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition2(hda2)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_EthernetCard</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_SecurityToken</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_GraphicsAdapter</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
</ObjectLabels>
</SecurityLabelTemplate>
</SecurityPolicyDefinition>
@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com ../../security_policy.xsd ">
<PolicyHeader>
<PolicyName>example.ste.client_v1</PolicyName>
<PolicyUrl>www.ibm.com/example/ste/client_v1</PolicyUrl>
<Date>2006-03-31</Date>
</PolicyHeader>
<!-- -->
<!-- example of a simple type enforcement policy definition -->
<!-- -->
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type><!-- machine/security management -->
<Type>ste_PersonalFinances</Type><!-- personal finances -->
<Type>ste_InternetInsecure</Type><!-- games, active X, etc. -->
<Type>ste_DonatedCycles</Type><!-- donation to BOINC/seti@home -->
<Type>ste_PersistentStorageA</Type><!-- domain managing the harddrive A-->
<Type>ste_NetworkAdapter0</Type><!-- type of the domain managing ethernet adapter 0-->
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
<SecurityLabelTemplate>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<!-- since dom0 needs access to every domain and -->
<!-- resource right now ... -->
<Type>ste_SystemManagement</Type>
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
<Type>ste_PersistentStorageA</Type>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (hard drive a) -->
<Type>ste_PersistentStorageA</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (ethernet card) -->
<Type>ste_NetworkAdapter0</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
</SubjectLabels>
<ObjectLabels>
<ResourceLabel>
<Name>res_ManagementResource</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_HardDrive(hda)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersistentStorageA</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition1(hda1)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition2(hda2)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_EthernetCard</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_SecurityToken</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_GraphicsAdapter</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
</ObjectLabels>
</SecurityLabelTemplate>
</SecurityPolicyDefinition>
@@ -1,24 +0,0 @@
<?xml version="1.0"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security labels, which can -->
<!-- be attached to Domains and resources. Based on -->
<!-- these labels, the access control module decides -->
<!-- about sharing between Domains and about access -->
<!-- of Domains to real resources. -->
<SecurityLabelTemplate
xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<LabelHeader>
<Name>null-security_label_template</Name>
<Date>2005-08-10</Date>
<PolicyName>
<Url>null-security_policy.xml</Url>
<Reference>abcdef123456abcdef</Reference>
</PolicyName>
</LabelHeader>
</SecurityLabelTemplate>
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<PolicyHeader>
<Name>null-security_policy</Name>
<Date>2005-08-10</Date>
</PolicyHeader>
</SecurityPolicyDefinition>
+31 -50
View File
@@ -1,22 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Ray Valdez, Reiner Sailer {rvaldez,sailer}@us.ibm.com -->
<!-- This file defines the schema, which is used to define -->
<!-- the security policy and the security labels in Xe. -->
<!-- the security policy and the security labels in Xen. -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ibm.com" xmlns="http://www.ibm.com" elementFormDefault="qualified">
<xsd:element name="SecurityPolicyDefinition">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="PolicyHeader" minOccurs="0" maxOccurs="1"></xsd:element>
<xsd:element ref="PolicyHeader" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element ref="SimpleTypeEnforcement" minOccurs="0" maxOccurs="1"></xsd:element>
<xsd:element ref="ChineseWall" minOccurs="0" maxOccurs="1"></xsd:element>
<xsd:element ref="SecurityLabelTemplate" minOccurs="1" maxOccurs="1"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PolicyHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="PolicyName" minOccurs="1" maxOccurs="1" type="xsd:string"></xsd:element>
<xsd:element name="PolicyUrl" minOccurs="0" maxOccurs="1" type="xsd:string"></xsd:element>
<xsd:element name="Reference" type="xsd:string" minOccurs="0" maxOccurs="1" />
<xsd:element name="Date" minOccurs="0" maxOccurs="1" type="xsd:string"></xsd:element>
<xsd:element name="NameSpaceUrl" minOccurs="0" maxOccurs="1" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ChineseWall">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="ChineseWallTypes" minOccurs="1" maxOccurs="1" />
<xsd:element ref="ConflictSets" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="priority" type="PolicyOrder" use="optional"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="SimpleTypeEnforcement">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="SimpleTypeEnforcementTypes" />
</xsd:sequence>
<xsd:attribute name="priority" type="PolicyOrder" use="optional"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="SecurityLabelTemplate">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="LabelHeader" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="SubjectLabels" minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:sequence>
@@ -35,40 +63,6 @@
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PolicyHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Name" minOccurs="1" maxOccurs="1" />
<xsd:element ref="Date" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="LabelHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Name"></xsd:element>
<xsd:element ref="Date" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element ref="PolicyName" minOccurs="1" maxOccurs="1"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SimpleTypeEnforcement">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="SimpleTypeEnforcementTypes" />
</xsd:sequence>
<xsd:attribute name="priority" type="PolicyOrder" use="optional"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="ChineseWall">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="ChineseWallTypes" />
<xsd:element ref="ConflictSets" />
</xsd:sequence>
<xsd:attribute name="priority" type="PolicyOrder" use="optional"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="ChineseWallTypes">
<xsd:complexType>
<xsd:sequence>
@@ -115,24 +109,11 @@
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PolicyName">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Url" />
<xsd:element ref="Reference" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Date" type="xsd:string" />
<xsd:element name="Name" type="xsd:string" />
<xsd:element name="Type" type="xsd:string" />
<xsd:element name="Reference" type="xsd:string" />
<xsd:element name="Url"></xsd:element>
<xsd:simpleType name="PolicyOrder">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="PrimaryPolicyComponent"></xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
@@ -1,143 +0,0 @@
<?xml version="1.0"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security labels, which can -->
<!-- be attached to Domains and resources. Based on -->
<!-- these labels, the access control module decides -->
<!-- about sharing between Domains and about access -->
<!-- of Domains to real resources. -->
<SecurityLabelTemplate
xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<LabelHeader>
<Name>ste-security_label_template</Name>
<Date>2005-08-10</Date>
<PolicyName>
<Url>ste-security_policy.xml</Url>
<Reference>abcdef123456abcdef</Reference>
</PolicyName>
</LabelHeader>
<SubjectLabels bootstrap="dom_SystemManagement">
<!-- single ste typed domains -->
<!-- ACM enforces that only domains with -->
<!-- the same type can share information -->
<!-- -->
<!-- Bootstrap label is assigned to Dom0 -->
<VirtualMachineLabel>
<Name>dom_HomeBanking</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<Name>dom_Fun</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- donating some cycles to seti@home -->
<Name>dom_BoincClient</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<!-- Domains with multiple ste types services; such domains -->
<!-- must keep the types inside their domain safely confined. -->
<VirtualMachineLabel>
<Name>dom_SystemManagement</Name>
<SimpleTypeEnforcementTypes>
<!-- since dom0 needs access to every domain and -->
<!-- resource right now ... -->
<Type>ste_SystemManagement</Type>
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
<Type>ste_PersistentStorageA</Type>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves persistent storage to other domains -->
<Name>dom_StorageDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (hard drive a) -->
<Type>ste_PersistentStorageA</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
<VirtualMachineLabel>
<!-- serves network access to other domains -->
<Name>dom_NetworkDomain</Name>
<SimpleTypeEnforcementTypes>
<!-- access right to the resource (ethernet card) -->
<Type>ste_NetworkAdapter0</Type>
<!-- can serve following types -->
<Type>ste_PersonalFinances</Type>
<Type>ste_InternetInsecure</Type>
<Type>ste_DonatedCycles</Type>
</SimpleTypeEnforcementTypes>
</VirtualMachineLabel>
</SubjectLabels>
<ObjectLabels>
<ResourceLabel>
<Name>res_ManagementResource</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_HardDrive (hda)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersistentStorageA</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition1 (hda1)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_LogicalDiskPartition2 (hda2)</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_InternetInsecure</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_EthernetCard</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_NetworkAdapter0</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_SecurityToken</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_PersonalFinances</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
<ResourceLabel>
<Name>res_GraphicsAdapter</Name>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type>
</SimpleTypeEnforcementTypes>
</ResourceLabel>
</ObjectLabels>
</SecurityLabelTemplate>
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Author: Reiner Sailer, Ray Valdez {sailer,rvaldez}@us.ibm.com -->
<!-- This file defines the security policies, which -->
<!-- can be enforced by the Xen Access Control Module. -->
<!-- Currently: Chinese Wall and Simple Type Enforcement-->
<SecurityPolicyDefinition xmlns="http://www.ibm.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com security_policy.xsd">
<PolicyHeader>
<Name>ste-security_policy</Name>
<Date>2005-08-10</Date>
</PolicyHeader>
<!-- -->
<!-- example of a simple type enforcement policy definition -->
<!-- -->
<SimpleTypeEnforcement>
<SimpleTypeEnforcementTypes>
<Type>ste_SystemManagement</Type> <!-- machine/security management -->
<Type>ste_PersonalFinances</Type> <!-- personal finances -->
<Type>ste_InternetInsecure</Type> <!-- games, active X, etc. -->
<Type>ste_DonatedCycles</Type> <!-- donation to BOINC/seti@home -->
<Type>ste_PersistentStorageA</Type> <!-- domain managing the harddrive A-->
<Type>ste_NetworkAdapter0</Type> <!-- type of the domain managing ethernet adapter 0-->
</SimpleTypeEnforcementTypes>
</SimpleTypeEnforcement>
</SecurityPolicyDefinition>
+32 -20
View File
@@ -59,22 +59,34 @@ migrate). These controls decide based on the active policy
configuration (see i. and ii.) if the operation proceeds of if the
operation is aborted (denied).
In general, security policy instantiations in the Xen access control
framework are defined by two files:
framework are defined by XML policy files. Each security policy has
exactly one file including all the information the hypervisor needs to
enforce the policy.
a) a single "policy-name"-security_policy.xml file that defines the
types known to the ACM and policy rules based on these types
The name of a policy is unique and consists of a colon-separated list
of names, which can be translated into the location (subtree) where
this policy must be located. The last part of the name is the file
name pre-fix for the policy xml file. The preceding name parts are
translated into the local path relative to the global policy root
(/etc/xen/acm-security/policies) pointing to the policy xml file. For
example: example.chwall_ste.client_v1 denotes the policy file
example/chwall_ste/client_v1-security_policy.xml relative to the
global policy root directory.
b) a single "policy-name"-security_label_template.xml file that
defines labels based on known types
Every security policy has its own sub-directory under the global
policy root directory /etc/xen/acm-security/policies, which is
installed during the Xen installation or can be manually installed
(when switching from a "security disabled" Xen to a "security enabled"
Xen AFTER configuring security, see install.txt) by the command
sequence:
Every security policy has its own sub-directory under
"Xen-root"/tools/security/policies in order to simplify their
management and the security policy tools. We will describe those files
for our example policy (Chinese Wall and Simple Type Enforcement) in
more detail as we go along. Eventually, we will move towards a system
installation where the policies will reside under /etc.
cd "Xen-root"/tools/security/policies; make install
We will describe those files for our example policy (Chinese Wall and
Simple Type Enforcement) in more detail as we go along. Eventually, we
will move towards a system installation where the policies will reside
under /etc.
CHINESE WALL
@@ -117,9 +129,9 @@ constraints where necessary.
Example of a Chinese Wall Policy Instantiation
----------------------------------------------
The file chwall-security_policy.xml defines the Chinese Wall types as
well as the conflict sets for our example policy (you find it in the
directory "xen_root"/tools/security/policies/chwall).
The file client_v1-security_policy.xml defines the Chinese Wall types
as well as the conflict sets for our example policy (you find it in
the directory "policy_root"/example/chwall).
It defines four Chinese Wall types (prefixed with cw_) with the
following meaning:
@@ -168,11 +180,11 @@ policy.
SIMPLE TYPE ENFORCEMENT
=======================
The file ste-security_policy.xml defines the simple type enforcement
types for our example policy (you find it in the directory
"xen_root"/tools/security/policies/ste). The Simple Type Enforcement
policy defines which domains can share information with which other
domains. To this end, it controls
The file client_v1-security_policy.xml defines the simple type
enforcement types for our example policy (you find it in the directory
"policy_root"/example/ste). The Simple Type Enforcement policy defines
which domains can share information with which other domains. To this
end, it controls
i) inter-domain communication channels (e.g., network traffic, events,
and shared memory).
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+2 -56
View File
@@ -1,7 +1,7 @@
<!--
The Initial Developer of the Original Code is International
Business Machines Corporation. Portions created by IBM
Corporation are Copyright (C) 2005 International Business
Corporation are Copyright (C) 2005, 2006 International Business
Machines Corporation. All Rights Reserved.
-->
@@ -10,7 +10,7 @@
<HTML>
<HEAD>
<META name="author" content="Tom Lendacky">
<META name="copyright" content="Copyright (C) 2005 International Business Machines Corporation. All rights reserved">
<META name="copyright" content="Copyright (C) 2005, 2006 International Business Machines Corporation. All rights reserved">
<STYLE type="text/css">
<!--
@@ -67,60 +67,6 @@
</TR>
</TABLE>
</FORM>
<FORM action="/cgi-bin/policylabel.cgi" method="post" enctype="multipart/form-data">
<TABLE class="xen">
<COLGROUP>
<COL width="25%">
<COL width="20%">
<COL width="55%">
</COLGROUP>
<TR>
<TD valign="top" class="heading">
Security Policy Labeling
</TD>
<TD valign="top" colspan="2">
To generate or edit the Xen Security Policy Labeling you <B>must</B>
specify the name of
an existing Xen Security Policy file in the
<B>"Policy File"</B> entry field.<BR>
To generate new Xen Security Policy Labeling leave the
<B>"Policy Labeling File"</B> entry field
empty and click the "Create" button.<BR>
To modify existing Xen Security Policy Labeling enter the
file name containing the labeling in the
<B>"Policy Labeling File"</B> entry field
and click the "Create" button.<HR>
</TD>
</TR>
<TR>
<TD></TD>
<TD>
Policy File:
</TD>
<TD>
<INPUT type="file" size="50" name="i_policy">
</TD>
</TR>
<TR>
<TD></TD>
<TD>
Policy Labeling File:
</TD>
<TD>
<INPUT type="file" size="50" name="i_policyLabel">
</TD>
</TR>
<TR>
<TD></TD>
<TD valign="top">
<INPUT type="submit" name="i_policyLabelCreate" value="Create">
</TD>
<TD></TD>
</TR>
</TABLE>
</FORM>
</CENTER>
</BODY>
</HTML>
@@ -0,0 +1,55 @@
#!/usr/bin/env python
# -*- mode: python; -*-
import sys
import traceback
import getopt
# add fallback path for non-native python path installs if needed
sys.path.insert(-1, '/usr/lib/python')
sys.path.insert(-1, '/usr/lib64/python')
from xen.util.security import ACMError, err, get_decision, active_policy
def usage():
print "Usage: acm_getdecision -i domainid --label labelname"
print " Test program illustrating the retrieval of"
print " access control decisions from Xen. At this time,"
print " only sharing (STE) policy decisions are supported."
print " Arguments are two paramters in any combination:"
print "\t -i domain_id or --domid domain_id"
print "\t -l labelname or --label labelname"
print " Return value:"
print "\t PERMITTED if access is permitted"
print "\t DENIED if access is denied"
print "\t ACMError -- e.g., unknown label or domain id"
err("Usage")
try:
if len(sys.argv) != 5:
usage()
decision_args = []
for idx in range(1, len(sys.argv), 2):
if sys.argv[idx] in ['-i', '--domid']:
decision_args.append(['domid', sys.argv[idx+1]])
elif sys.argv[idx] in ['-l', '--label']:
decision_args.append(['access_control',
['policy', active_policy],
['label', sys.argv[idx+1]]
])
else:
print "unknown argument %s" % sys.argv[idx]
usage()
if len(decision_args) != 2:
print "too many arguments"
usage()
print get_decision(decision_args[0], decision_args[1])
except ACMError:
pass
except:
traceback.print_exc(limit=1)
@@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- mode: python; -*-
import sys
import traceback
import getopt
# add fallback path for non-native python path installs if needed
sys.path.insert(-1, '/usr/lib/python')
sys.path.insert(-1, '/usr/lib64/python')
from xen.util.security import ACMError, err, get_ssid
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
# may only be specified before positional arguments.
if not hasattr(getopt, 'gnu_getopt'):
getopt.gnu_getopt = getopt.getopt
def usage():
print "Usage: acm_getlabel -i domainid"
print " Test program illustrating the retrieval of"
print " label information (for domains) from Xen."
print " Argument is one paramter describing the domain"
print " for which the label is retrieved."
print "\t -i domain_id or --domid=domain_id"
print " Return value:"
print "\t none -- Error (e.g., unknown ssidref, label, or domain id)"
print "\t (labelname, policyname, ssidref)"
err("Usage")
try:
domid = None
(options, params) = getopt.gnu_getopt(sys.argv[1:], ':i:', ['domid='])
for (k, v) in options:
if k in ['-i', '--domid']:
if not domid:
domid = v
else:
usage()
if not domid:
usage()
print get_ssid(domid)
except ACMError:
pass
except:
traceback.print_exc(limit=1)
+10 -5
View File
@@ -10,20 +10,25 @@
# the access control policy and tools in Xen.
##
1. policy.txt:
1. 'xm' man page
describes the commands related to Xen management, including the
commands to manage security policies and labels. Read the access
control subcommand section of the xm manual first. If it is not
built by default, check install.txt.
2. policy.txt:
describes the general reasoning and examples for access
control policies in Xen
2. install.txt
3. install.txt
describes the activation of the access control framework
in Xen
3. example.txt
4. example.txt
describes the available tools for managing security policies
in Xen and the tools to label domains
+34 -165
View File
@@ -48,9 +48,7 @@ void usage(char *progname)
"ACTION is one of:\n"
"\t getpolicy\n"
"\t dumpstats\n"
"\t loadpolicy <binary policy file>\n"
"\t getssid -d <domainid> [-f]\n"
"\t getssid -s <ssidref> [-f]\n", progname);
"\t loadpolicy <binary policy file>\n", progname);
exit(-1);
}
@@ -68,7 +66,7 @@ static inline int do_xen_hypercall(int xc_handle,
(unsigned long) hypercall);
}
static inline int do_acm_op(int xc_handle, struct acm_op * op)
static inline int do_acm_op(int xc_handle, struct acm_op *op)
{
int ret = -1;
privcmd_hypercall_t hypercall;
@@ -78,15 +76,13 @@ static inline int do_acm_op(int xc_handle, struct acm_op * op)
hypercall.op = __HYPERVISOR_acm_op;
hypercall.arg[0] = (unsigned long) op;
if (mlock(op, sizeof(*op)) != 0)
{
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)
{
printf( "ACM operation failed: errno=%d\n", errno );
if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0) {
printf("ACM operation failed: errno=%d\n", errno);
if (errno == EACCES)
fprintf(stderr, "ACM operation failed -- need to"
" rebuild the user-space tool set?\n");
@@ -108,8 +104,7 @@ void acm_dump_chinesewall_buffer(void *buf, int buflen)
int i, j;
if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY)
{
if (htonl(cwbuf->policy_code) != ACM_CHINESE_WALL_POLICY) {
printf("CHINESE WALL POLICY CODE not found ERROR!!\n");
return;
}
@@ -129,8 +124,7 @@ void acm_dump_chinesewall_buffer(void *buf, int buflen)
printf("\nSSID To CHWALL-Type matrix:\n");
ssids = (domaintype_t *) (buf + ntohl(cwbuf->chwall_ssid_offset));
for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++)
{
for (i = 0; i < ntohl(cwbuf->chwall_max_ssidrefs); i++) {
printf("\n ssidref%2x: ", i);
for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
printf("%02x ",
@@ -139,8 +133,7 @@ void acm_dump_chinesewall_buffer(void *buf, int buflen)
printf("\n\nConfict Sets:\n");
conflicts =
(domaintype_t *) (buf + ntohl(cwbuf->chwall_conflict_sets_offset));
for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++)
{
for (i = 0; i < ntohl(cwbuf->chwall_max_conflictsets); i++) {
printf("\n c-set%2x: ", i);
for (j = 0; j < ntohl(cwbuf->chwall_max_types); j++)
printf("%02x ",
@@ -150,13 +143,11 @@ void acm_dump_chinesewall_buffer(void *buf, int buflen)
printf("\n");
printf("\nRunning\nTypes: ");
if (ntohl(cwbuf->chwall_running_types_offset))
{
if (ntohl(cwbuf->chwall_running_types_offset)) {
running_types =
(domaintype_t *) (buf +
ntohl(cwbuf->chwall_running_types_offset));
for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
{
for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++) {
printf("%02x ", ntohs(running_types[i]));
}
printf("\n");
@@ -164,13 +155,12 @@ void acm_dump_chinesewall_buffer(void *buf, int buflen)
printf("Not Reported!\n");
}
printf("\nConflict\nAggregate Set: ");
if (ntohl(cwbuf->chwall_conflict_aggregate_offset))
{
if (ntohl(cwbuf->chwall_conflict_aggregate_offset)) {
conflict_aggregate =
(domaintype_t *) (buf +
ntohl(cwbuf->chwall_conflict_aggregate_offset));
for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++)
{
ntohl(cwbuf->
chwall_conflict_aggregate_offset));
for (i = 0; i < ntohl(cwbuf->chwall_max_types); i++) {
printf("%02x ", ntohs(conflict_aggregate[i]));
}
printf("\n\n");
@@ -201,11 +191,11 @@ void acm_dump_ste_buffer(void *buf, int buflen)
printf("\nSSID To STE-Type matrix:\n");
ssids = (domaintype_t *) (buf + ntohl(stebuf->ste_ssid_offset));
for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++)
{
for (i = 0; i < ntohl(stebuf->ste_max_ssidrefs); i++) {
printf("\n ssidref%2x: ", i);
for (j = 0; j < ntohl(stebuf->ste_max_types); j++)
printf("%02x ", ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
printf("%02x ",
ntohs(ssids[i * ntohl(stebuf->ste_max_types) + j]));
}
printf("\n\n");
}
@@ -213,9 +203,12 @@ void acm_dump_ste_buffer(void *buf, int buflen)
void acm_dump_policy_buffer(void *buf, int buflen)
{
struct acm_policy_buffer *pol = (struct acm_policy_buffer *) buf;
char *policy_reference_name =
(buf + ntohl(pol->policy_reference_offset) +
sizeof(struct acm_policy_reference_buffer));
printf("\nPolicy dump:\n");
printf("============\n");
printf("POLICY REFERENCE = %s.\n", policy_reference_name);
printf("PolicyVer = %x.\n", ntohl(pol->policy_version));
printf("Magic = %x.\n", ntohl(pol->magic));
printf("Len = %x.\n", ntohl(pol->len));
@@ -227,8 +220,7 @@ void acm_dump_policy_buffer(void *buf, int buflen)
ACM_POLICY_NAME(ntohl(pol->secondary_policy_code)),
ntohl(pol->secondary_policy_code),
ntohl(pol->secondary_buffer_offset));
switch (ntohl(pol->primary_policy_code))
{
switch (ntohl(pol->primary_policy_code)) {
case ACM_CHINESE_WALL_POLICY:
acm_dump_chinesewall_buffer(buf +
ntohl(pol->primary_buffer_offset),
@@ -250,8 +242,7 @@ void acm_dump_policy_buffer(void *buf, int buflen)
printf("UNKNOWN POLICY!\n");
}
switch (ntohl(pol->secondary_policy_code))
{
switch (ntohl(pol->secondary_policy_code)) {
case ACM_CHINESE_WALL_POLICY:
acm_dump_chinesewall_buffer(buf +
ntohl(pol->secondary_buffer_offset),
@@ -303,26 +294,22 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename)
off_t len;
uint8_t *buffer;
if ((ret = stat(filename, &mystat)))
{
if ((ret = stat(filename, &mystat))) {
printf("File %s not found.\n", filename);
goto out;
}
len = mystat.st_size;
if ((buffer = malloc(len)) == NULL)
{
if ((buffer = malloc(len)) == NULL) {
ret = -ENOMEM;
goto out;
}
if ((fd = open(filename, O_RDONLY)) <= 0)
{
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))
{
if (len == read(fd, buffer, len)) {
struct acm_op op;
/* dump it and then push it down into xen/acm */
acm_dump_policy_buffer(buffer, len);
@@ -334,7 +321,7 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename)
if (ret)
printf
("ERROR setting policy. Try 'xm dmesg' to see details.\n");
("ERROR setting policy.\n");
else
printf("Successfully changed policy.\n");
@@ -382,9 +369,9 @@ int acm_domain_dumpstats(int xc_handle)
op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
ret = do_acm_op(xc_handle, &op);
if (ret < 0)
{
printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n");
if (ret < 0) {
printf
("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n");
return ret;
}
stats = (struct acm_stats_buffer *) stats_buffer;
@@ -394,8 +381,7 @@ int acm_domain_dumpstats(int xc_handle)
printf("Magic = %x.\n", ntohl(stats->magic));
printf("Len = %x.\n", ntohl(stats->len));
switch (ntohl(stats->primary_policy_code))
{
switch (ntohl(stats->primary_policy_code)) {
case ACM_NULL_POLICY:
printf("NULL Policy: No statistics apply.\n");
break;
@@ -414,8 +400,7 @@ int acm_domain_dumpstats(int xc_handle)
printf("UNKNOWN PRIMARY POLICY ERROR!\n");
}
switch (ntohl(stats->secondary_policy_code))
{
switch (ntohl(stats->secondary_policy_code)) {
case ACM_NULL_POLICY:
printf("NULL Policy: No statistics apply.\n");
break;
@@ -435,119 +420,6 @@ int acm_domain_dumpstats(int xc_handle)
}
return ret;
}
/************************ get ssidref & types ******************************/
/*
* the ssid (types) can be looked up either by domain id or by ssidref
*/
int acm_domain_getssid(int xc_handle, int argc, char * const argv[])
{
/* this includes header and a set of types */
#define MAX_SSIDBUFFER 2000
int ret, i;
struct acm_op op;
struct acm_ssid_buffer *hdr;
unsigned char *buf;
int nice_print = 1;
op.cmd = ACM_GETSSID;
op.interface_version = ACM_INTERFACE_VERSION;
op.u.getssid.get_ssid_by = UNSET;
/* arguments
-d ... domain id to look up
-s ... ssidref number to look up
-f ... formatted print (scripts depend on this format)
*/
while (1)
{
int c = getopt(argc, argv, "d:s:f");
if (c == -1)
break;
if (c == 'd')
{
if (op.u.getssid.get_ssid_by != UNSET)
usage(argv[0]);
op.u.getssid.get_ssid_by = DOMAINID;
op.u.getssid.id.domainid = strtoul(optarg, NULL, 0);
}
else if (c== 's')
{
if (op.u.getssid.get_ssid_by != UNSET)
usage(argv[0]);
op.u.getssid.get_ssid_by = SSIDREF;
op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0);
}
else if (c== 'f')
{
nice_print = 0;
}
else
usage(argv[0]);
}
if (op.u.getssid.get_ssid_by == UNSET)
usage(argv[0]);
buf = malloc(MAX_SSIDBUFFER);
if (!buf)
return -ENOMEM;
/* dump it and then push it down into xen/acm */
op.u.getssid.ssidbuf = buf; /* out */
op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER;
ret = do_acm_op(xc_handle, &op);
if (ret)
{
printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n");
goto out;
}
hdr = (struct acm_ssid_buffer *)buf;
if (hdr->len > MAX_SSIDBUFFER)
{
printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n",
ret, hdr->len);
return -EIO;
}
if (nice_print)
{
printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
printf(" P: %s, max_types = %d\n",
ACM_POLICY_NAME(hdr->primary_policy_code), hdr->primary_max_types);
printf(" Types: ");
for (i=0; i< hdr->primary_max_types; i++)
if (buf[hdr->primary_types_offset + i])
printf("%02x ", i);
else
printf("-- ");
printf("\n");
printf(" S: %s, max_types = %d\n",
ACM_POLICY_NAME(hdr->secondary_policy_code), hdr->secondary_max_types);
printf(" Types: ");
for (i=0; i< hdr->secondary_max_types; i++)
if (buf[hdr->secondary_types_offset + i])
printf("%02x ", i);
else
printf("-- ");
printf("\n");
}
else
{
/* formatted print for use with scripts (.sh)
* update scripts when updating here (usually
* used in combination with -d to determine a
* running domain's label
*/
printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
}
/* return ste ssidref */
if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
ret = (hdr->ssidref) & 0xffff;
else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
ret = (hdr->ssidref) >> 16;
out:
return ret;
}
/***************************** main **************************************/
@@ -559,8 +431,7 @@ int main(int argc, char **argv)
if (argc < 2)
usage(argv[0]);
if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0)
{
if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) {
printf("ERROR: Could not open xen privcmd device!\n");
exit(-1);
}
@@ -577,8 +448,6 @@ int main(int argc, char **argv)
if (argc != 2)
usage(argv[0]);
ret = acm_domain_dumpstats(acm_cmd_fd);
} else if (!strcmp(argv[1], "getssid")) {
ret = acm_domain_getssid(acm_cmd_fd, argc, argv);
} else
usage(argv[0]);
File diff suppressed because it is too large. Load diff
+92 -75
View File
@@ -12,37 +12,41 @@
* License.
*
*/
#define POLICY_DIR "/etc/xen/acm-security/policies/"
#define POLICY_EXTENSION "-security_policy.xml"
#define LABEL_EXTENSION "-security_label_template.xml"
#define BINARY_EXTENSION ".bin"
#define MAPPING_EXTENSION ".map"
#define PRIMARY_COMPONENT_ATTR_NAME "order"
#define BOOTSTRAP_LABEL_ATTR_NAME "bootstrap"
#define PRIMARY_COMPONENT "PrimaryPolicyComponent"
#define SCHEMA_FILENAME "security_policy.xsd"
#define POLICY_DIR "/etc/xen/acm-security/policies/"
#define POLICY_EXTENSION "-security_policy.xml"
#define BINARY_EXTENSION ".bin"
#define MAPPING_EXTENSION ".map"
#define PRIMARY_COMPONENT_ATTR_NAME "order"
#define BOOTSTRAP_LABEL_ATTR_NAME "bootstrap"
#define PRIMARY_COMPONENT "PrimaryPolicyComponent"
#define SCHEMA_FILENAME "security_policy.xsd"
/* basic states (used as 1 << X) */
#define XML2BIN_SECPOL 0 /* policy tokens */
#define XML2BIN_STE 1
#define ENDOFLIST_POS 22 /* ADAPT!! this position will be NULL; stay below 32 (bit) */
#define XML2BIN_SECPOL 0 /* policy tokens */
#define XML2BIN_STE 1
#define XML2BIN_CHWALL 2
#define XML2BIN_CONFLICTSETS 3
#define XML2BIN_CSTYPE 4
#define XML2BIN_CONFLICTSETS 3
#define XML2BIN_CSTYPE 4
#define XML2BIN_POLICYHEADER 5
#define XML2BIN_NSURL 6
#define XML2BIN_POLICYNAME 7
#define XML2BIN_URL 8
#define XML2BIN_REFERENCE 9
#define XML2BIN_DATE 10
#define XML2BIN_SECTEMPLATE 5 /* label tokens */
#define XML2BIN_POLICYHEADER 6
#define XML2BIN_LABELHEADER 7
#define XML2BIN_SUBJECTS 8
#define XML2BIN_OBJECTS 9
#define XML2BIN_VM 10
#define XML2BIN_RES 11
#define XML2BIN_LABELTEMPLATE 11 /* label tokens */
#define XML2BIN_SUBJECTS 12
#define XML2BIN_OBJECTS 13
#define XML2BIN_VM 14
#define XML2BIN_RES 15
#define XML2BIN_NAME 16
#define XML2BIN_STETYPES 12 /* shared tokens */
#define XML2BIN_CHWALLTYPES 13
#define XML2BIN_TYPE 14
#define XML2BIN_NAME 15
#define XML2BIN_TEXT 16
#define XML2BIN_COMMENT 17
#define XML2BIN_STETYPES 17 /* shared tokens */
#define XML2BIN_CHWALLTYPES 18
#define XML2BIN_TYPE 19
#define XML2BIN_TEXT 20
#define XML2BIN_COMMENT 21
/* type "data type" (currently 16bit) */
typedef u_int16_t type_t;
@@ -51,27 +55,34 @@ typedef u_int16_t type_t;
* state constants and token positions must be *
* in sync for correct state recognition */
char *token[20] = /* parser triggers */
char *token[32] = /* parser triggers */
{
[0] = "SecurityPolicyDefinition", /* policy xml */
[1] = "SimpleTypeEnforcement",
[2] = "ChineseWall",
[3] = "ConflictSets",
[4] = "Conflict", /* label-template xml */
[5] = "SecurityLabelTemplate",
[6] = "PolicyHeader",
[7] = "LabelHeader",
[8] = "SubjectLabels",
[9] = "ObjectLabels",
[10] = "VirtualMachineLabel",
[11] = "ResourceLabel",
[12] = "SimpleTypeEnforcementTypes", /* common tags */
[13] = "ChineseWallTypes",
[14] = "Type",
[15] = "Name",
[16] = "text",
[17] = "comment",
[18] = NULL,
[XML2BIN_SECPOL] = "SecurityPolicyDefinition", /* policy xml */
[XML2BIN_STE] = "SimpleTypeEnforcement",
[XML2BIN_CHWALL] = "ChineseWall",
[XML2BIN_CONFLICTSETS] = "ConflictSets",
[XML2BIN_CSTYPE] = "Conflict",
[XML2BIN_POLICYHEADER] = "PolicyHeader",
[XML2BIN_NSURL] = "NameSpaceUrl",
[XML2BIN_POLICYNAME] = "PolicyName",
[XML2BIN_URL] = "PolicyUrl",
[XML2BIN_REFERENCE] = "Reference",
[XML2BIN_DATE] = "Date",
[XML2BIN_LABELTEMPLATE] = "SecurityLabelTemplate", /* label-template xml */
[XML2BIN_SUBJECTS] = "SubjectLabels",
[XML2BIN_OBJECTS] = "ObjectLabels",
[XML2BIN_VM] = "VirtualMachineLabel",
[XML2BIN_RES] = "ResourceLabel",
[XML2BIN_NAME] = "Name",
[XML2BIN_STETYPES] = "SimpleTypeEnforcementTypes", /* common tags */
[XML2BIN_CHWALLTYPES] = "ChineseWallTypes",
[XML2BIN_TYPE] = "Type",
[XML2BIN_TEXT] = "text",
[XML2BIN_COMMENT] = "comment",
[ENDOFLIST_POS] = NULL /* End of LIST, adapt ENDOFLIST_POS
when adding entries */
};
/* important combined states */
@@ -82,47 +93,53 @@ char *token[20] = /* parser triggers */
/* e.g., here we are in a <secpol,ste,stetypes> environment, *
* so when finding a type element, we know where to put it */
#define XML2BIN_stetype_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_STE) | \
(1 << XML2BIN_STETYPES))
(1 << XML2BIN_STE) | \
(1 << XML2BIN_STETYPES))
#define XML2BIN_chwalltype_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CHWALLTYPES))
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CHWALLTYPES))
#define XML2BIN_conflictset_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CONFLICTSETS))
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CONFLICTSETS))
#define XML2BIN_conflictsettype_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CONFLICTSETS) | \
(1 << XML2BIN_CSTYPE))
(1 << XML2BIN_CHWALL) | \
(1 << XML2BIN_CONFLICTSETS) | \
(1 << XML2BIN_CSTYPE))
#define XML2BIN_PN_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_POLICYHEADER))
/* label xml states */
#define XML2BIN_VM_S ((1 << XML2BIN_SECTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM))
#define XML2BIN_VM_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM))
#define XML2BIN_RES_S ((1 << XML2BIN_SECTEMPLATE) | \
(1 << XML2BIN_OBJECTS) | \
(1 << XML2BIN_RES))
#define XML2BIN_RES_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
(1 << XML2BIN_OBJECTS) | \
(1 << XML2BIN_RES))
#define XML2BIN_VM_STE_S ((1 << XML2BIN_SECTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM) | \
(1 << XML2BIN_STETYPES))
#define XML2BIN_VM_STE_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM) | \
(1 << XML2BIN_STETYPES))
#define XML2BIN_VM_CHWALL_S ((1 << XML2BIN_SECTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM) | \
(1 << XML2BIN_CHWALLTYPES))
#define XML2BIN_RES_STE_S ((1 << XML2BIN_SECTEMPLATE) | \
(1 << XML2BIN_OBJECTS) | \
(1 << XML2BIN_RES) | \
(1 << XML2BIN_STETYPES))
#define XML2BIN_VM_CHWALL_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
(1 << XML2BIN_SUBJECTS) | \
(1 << XML2BIN_VM) | \
(1 << XML2BIN_CHWALLTYPES))
#define XML2BIN_RES_STE_S ((1 << XML2BIN_SECPOL) | \
(1 << XML2BIN_LABELTEMPLATE) | \
(1 << XML2BIN_OBJECTS) | \
(1 << XML2BIN_RES) | \
(1 << XML2BIN_STETYPES))
/* check versions of headers against which the
@@ -130,7 +147,7 @@ char *token[20] = /* parser triggers */
*/
/* protects from unnoticed changes in struct acm_policy_buffer */
#define WRITTEN_AGAINST_ACM_POLICY_VERSION 1
#define WRITTEN_AGAINST_ACM_POLICY_VERSION 2
/* protects from unnoticed changes in struct acm_chwall_policy_buffer */
#define WRITTEN_AGAINST_ACM_CHWALL_VERSION 1
-106
View File
@@ -1,106 +0,0 @@
#!/bin/sh
# *
# * setlabel
# *
# * Copyright (C) 2005 IBM Corporation
# *
# * Authors:
# * Stefan Berger <stefanb@us.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.
# *
# * 'setlabel' labels virtual machine (domain) configuration files with
# * security identifiers that can be enforced in Xen.
# *
# * 'setlabel -?' shows the usage of the program
# *
# * 'setlabel -l vmconfig-file' lists all available labels (only VM
# * labels are used right now)
# *
# * 'setlabel vmconfig-file security-label map-file' inserts the 'ssidref'
# * that corresponds to the security-label under the
# * current policy (if policy changes, 'label'
# * must be re-run over the configuration files;
# * map-file is created during policy translation and
# * is found in the policy's directory
#
if [ -z "$runbash" ]; then
runbash="1"
export runbash
exec sh -c "bash $0 $*"
fi
export PATH=$PATH:.
dir=`dirname $0`
source $dir/labelfuncs.sh
usage ()
{
prg=`basename $0`
echo "Use this tool to put the ssidref corresponding to a label of a policy into
the VM configuration file, or use it to display all labels of a policy.
Usage: $prg [-r] <vmfile> <label> [<policy name> [<policy dir>]] or
$prg -l [<policy name> [<policy dir>]]
-r : to relabel a file without being prompted
-l : to show the valid labels in a map file
vmfile : XEN vm configuration file; give complete path
label : the label to map to an ssidref
policy name : the name of the policy, i.e. 'chwall'
If the policy name is omitted, it is attempted
to find the current policy's name in grub.conf.
policy dir : the directory where the <policy name> policy is located
The default location is '/etc/xen/acm-security/policies'
"
}
if [ "$1" == "-r" ]; then
mode="relabel"
shift
elif [ "$1" == "-l" ]; then
mode="show"
shift
elif [ "$1" == "-h" ]; then
mode="usage"
fi
if [ "$mode" == "usage" ]; then
usage
elif [ "$mode" == "show" ]; then
setPolicyVars $1 $2
ret=$?
if [ $ret -eq 0 ]; then
echo "Error when trying to find policy-related information."
exit -1
fi
findMapFile $policy $policydir
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not find map file for policy '$policy'."
exit -1
fi
showLabels $mapfile
else
if [ "$2" == "" ]; then
usage
exit -1
fi
setPolicyVars $3 $4
ret=$?
if [ $ret -eq 0 ]; then
echo "Error when trying to find policy-related information."
exit -1
fi
findMapFile $policy $policydir
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not find map file for policy '$policy'."
exit -1
fi
relabel $1 $2 $mapfile $mode
fi
-90
View File
@@ -1,90 +0,0 @@
#!/bin/sh
# *
# * updategrub
# *
# * Copyright (C) 2005 IBM Corporation
# *
# * Authors:
# * Stefan Berger <stefanb@us.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.
# *
# *
#
if [ -z "$runbash" ]; then
runbash="1"
export runbash
exec sh -c "bash $0 $*"
exit
fi
dir=`dirname $0`
source $dir/labelfuncs.sh
acmroot=$ACM_DEFAULT_ROOT
# Show usage of this program
usage ()
{
prg=`basename $0`
echo "Use this tool to add the binary policy to the Xen grub entry and
have Xen automatically enforce the policy when starting.
Usage: $prg [-d <policies root>] <policy name> [<kernel version>]
<policies root> : The directory where the policies directory is located in;
default is $acmroot
<policy name> : The name of the policy, i.e. xen_null
<kernel version> : The version of the kernel to apply the policy
against, i.e. 2.6.12.6-xen0
If not specified, a kernel version ending with '-xen0'
will be searched for in '/lib/modules'
"
}
if [ "$1" == "-h" ]; then
usage
exit 0
elif [ "$1" == "-d" ]; then
shift
acmroot=$1
shift
fi
if [ "$1" == "" ]; then
echo "Error: Not enough command line parameters."
echo ""
usage
exit -1
fi
policy=$1
policyfile=$policy.bin
getLinuxVersion $2
findGrubConf
ret=$?
if [ $ret -eq 0 ]; then
echo "Could not find grub.conf."
exit -1
elif [ $ret -eq 2 ]; then
echo "Need to have write-access to $grubconf. Exiting."
exit -1
fi
cpBootPolicy /boot $acmroot $policy
ret=$?
if [ $ret -ne 1 ]; then
echo "Error copying or generating the binary policy."
exit -1
fi
updateGrub $grubconf $policyfile $linux
+18
View File
@@ -212,6 +212,24 @@ use it with relatively few problems.
Known Issues
============
If you create a domain with a small amount of memory, under 32MBs, you
may run into out of memory situations for the domain. There's no way
to know the amount of memory needed by the kernel and modules used. Xm-test
uses 64MBs as default and that should work. If there are out of memory
issues, the default can be changed. Edit xm-test/lib/XmTestLib/XenDomain.py
and change ParavirtDefaults and HVMDefaults "memory".
There are two tests that work with small memory, 15_create_smallmem_pos.py
and 16_create_smallmem_neg.py. The first makes sure the default 32 MBs
limit works. The second checks a low memory fail situation. These tests
are located in the xm-test/tests/create directory and can be easily edited
to change the MEM value they should test. If the 32MBs test fails, the
failure should be reported to the Xen xen-devel mailing list. The Xen
tools use 32MBs as a lower acceptable limit for domain creation. The Xen
mailing lists are located here:
http://lists.xensource.com/
Reporting Bugs
==============
+2 -2
View File
@@ -46,7 +46,7 @@ class ConsoleError(Exception):
class XmConsole:
def __init__(self, domain, historyLimit=256, historySaveAll=True, historySaveCmds=False):
def __init__(self, domain, historyLimit=256, historySaveAll=True, historySaveCmds=False, cLimit=131072):
"""
Parameters:
historyLimit: specifies how many lines of history are maintained
@@ -65,7 +65,7 @@ class XmConsole:
self.historySaveAll = historySaveAll
self.historySaveCmds = historySaveCmds
self.debugMe = False
self.limit = None
self.limit = cLimit
consoleCmd = ["/usr/sbin/xm", "xm", "console", domain]
+1 -1
View File
@@ -252,7 +252,7 @@ class XmTestDomain(XenDomain):
waitForBoot()
def minSafeMem(self):
return 16
return 32
if __name__ == "__main__":
Loaded 100 of 159 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.