mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
aaf9402dab
159 files changed
+7002
-5697
No files matched your search
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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]) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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():
|
||||
|
||||
@@ -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
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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.
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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,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
@@ -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]);
|
||||
|
||||
|
||||
+301
-327
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
==============
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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