Mailing List Archive

[xen-unstable] Xen Security Modules: XSM
# HG changeset patch
# User kfraser@localhost.localdomain
# Date 1188555695 -3600
# Node ID 96f64f4c42f043e3af2db369f4b9bdb9fcef017b
# Parent 0f196e11a14392b2a2554cd02b7111126b87e967
Xen Security Modules: XSM
Signed-off-by: George Coker <gscoker@alpha.ncsc.mil>
---
Config.mk | 6
xen/Makefile | 3
xen/Rules.mk | 2
xen/arch/x86/domctl.c | 56 +++
xen/arch/x86/hvm/hvm.c | 16 +
xen/arch/x86/mm.c | 35 ++
xen/arch/x86/mm/paging.c | 5
xen/arch/x86/physdev.c | 11
xen/arch/x86/platform_hypercall.c | 27 +
xen/arch/x86/setup.c | 3
xen/arch/x86/sysctl.c | 5
xen/arch/x86/x86_32/entry.S | 2
xen/arch/x86/x86_32/xen.lds.S | 2
xen/arch/x86/x86_64/entry.S | 2
xen/common/domain.c | 12
xen/common/domctl.c | 99 ++++++-
xen/common/event_channel.c | 46 +++
xen/common/grant_table.c | 47 +++
xen/common/kexec.c | 5
xen/common/memory.c | 25 +
xen/common/schedule.c | 8
xen/common/sysctl.c | 21 +
xen/common/xenoprof.c | 5
xen/drivers/char/console.c | 5
xen/include/public/xen.h | 1
xen/include/xen/hypercall.h | 5
xen/include/xsm/xsm.h | 537 ++++++++++++++++++++++++++++++++++++++
xen/xsm/Makefile | 5
xen/xsm/dummy.c | 488 ++++++++++++++++++++++++++++++++++
xen/xsm/xsm_core.c | 118 ++++++++
xen/xsm/xsm_policy.c | 67 ++++
31 files changed, 1665 insertions(+), 4 deletions(-)

diff -r 0f196e11a143 -r 96f64f4c42f0 Config.mk
--- a/Config.mk Fri Aug 31 11:12:57 2007 +0100
+++ b/Config.mk Fri Aug 31 11:21:35 2007 +0100
@@ -78,10 +78,12 @@ LDFLAGS += $(foreach i, $(EXTRA_LIB), -L
LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i))
CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))

+# Enable XSM security module. Enabling XSM requires selection of an
+# XSM security module.
+XSM_ENABLE ?= n
+
# If ACM_SECURITY = y, then the access control module is compiled
# into Xen and the policy type can be set by the boot policy file
-# y - Build the Xen ACM framework
-# n - Do not build the Xen ACM framework
ACM_SECURITY ?= n

# Optional components
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/Makefile
--- a/xen/Makefile Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/Makefile Fri Aug 31 11:21:35 2007 +0100
@@ -56,6 +56,7 @@ _clean: delete-unfresh-files
$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C xsm clean
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) clean
rm -f include/asm *.o $(TARGET)* *~ core
rm -f include/asm-*/asm-offsets.h
@@ -122,7 +123,7 @@ build-headers:
build-headers:
$(MAKE) -C include/public/foreign

-SUBDIRS = acm arch/$(TARGET_ARCH) common drivers
+SUBDIRS = xsm acm arch/$(TARGET_ARCH) common drivers
define all_sources
( find include/asm-$(TARGET_ARCH) -name '*.h' -print; \
find include -name 'asm-*' -prune -o -name '*.h' -print; \
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/Rules.mk
--- a/xen/Rules.mk Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/Rules.mk Fri Aug 31 11:21:35 2007 +0100
@@ -52,10 +52,12 @@ HDRS := $(filter-out %/asm-offsets.h,$(
# Note that link order matters!
ALL_OBJS-y += $(BASEDIR)/common/built_in.o
ALL_OBJS-y += $(BASEDIR)/drivers/built_in.o
+ALL_OBJS-y += $(BASEDIR)/xsm/built_in.o
ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o
ALL_OBJS-y += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o

CFLAGS-y += -g -D__XEN__
+CFLAGS-$(XSM_ENABLE) += -DXSM_ENABLE
CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY
CFLAGS-$(verbose) += -DVERBOSE
CFLAGS-$(crash_debug) += -DCRASH_DEBUG
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/domctl.c Fri Aug 31 11:21:35 2007 +0100
@@ -24,6 +24,7 @@
#include <asm/hvm/hvm.h>
#include <asm/hvm/support.h>
#include <asm/processor.h>
+#include <xsm/xsm.h>

long arch_do_domctl(
struct xen_domctl *domctl,
@@ -63,6 +64,14 @@ long arch_do_domctl(
ret = -ESRCH;
if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) )
break;
+
+ ret = xsm_ioport_permission(d, fp,
+ domctl->u.ioport_permission.allow_access);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

if ( np == 0 )
ret = 0;
@@ -89,6 +98,13 @@ long arch_do_domctl(
break;

page = mfn_to_page(mfn);
+
+ ret = xsm_getpageframeinfo(page);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

if ( likely(get_page(page, d)) )
{
@@ -173,6 +189,10 @@ long arch_do_domctl(

page = mfn_to_page(mfn);

+ ret = xsm_getpageframeinfo(page);
+ if ( ret )
+ continue;
+
if ( likely(mfn_valid(mfn) && get_page(page, d)) )
{
unsigned long type = 0;
@@ -230,6 +250,13 @@ long arch_do_domctl(
ret = -EINVAL;
if ( d != NULL )
{
+ ret = xsm_getmemlist(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
ret = 0;

spin_lock(&d->page_alloc_lock);
@@ -269,6 +296,13 @@ long arch_do_domctl(
if ( unlikely(d == NULL) )
break;

+ ret = xsm_hypercall_init(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
mfn = gmfn_to_mfn(d, gmfn);

ret = -EACCES;
@@ -304,6 +338,10 @@ long arch_do_domctl(
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;

+ ret = xsm_hvmcontext(d, domctl->cmd);
+ if ( ret )
+ goto sethvmcontext_out;
+
ret = -EINVAL;
if ( !is_hvm_domain(d) )
goto sethvmcontext_out;
@@ -337,6 +375,10 @@ long arch_do_domctl(
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;

+ ret = xsm_hvmcontext(d, domctl->cmd);
+ if ( ret )
+ goto gethvmcontext_out;
+
ret = -EINVAL;
if ( !is_hvm_domain(d) )
goto gethvmcontext_out;
@@ -390,6 +432,13 @@ long arch_do_domctl(
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;

+ ret = xsm_address_size(d, domctl->cmd);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
switch ( domctl->u.address_size.size )
{
#ifdef CONFIG_COMPAT
@@ -416,6 +465,13 @@ long arch_do_domctl(
ret = -ESRCH;
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;
+
+ ret = xsm_address_size(d, domctl->cmd);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

domctl->u.address_size.size = BITS_PER_GUEST_LONG(d);

diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri Aug 31 11:21:35 2007 +0100
@@ -1069,6 +1069,10 @@ static int hvmop_set_pci_intx_level(
if ( !is_hvm_domain(d) )
goto out;

+ rc = xsm_hvm_set_pci_intx_level(d);
+ if ( rc )
+ goto out;
+
rc = 0;
switch ( op.level )
{
@@ -1112,6 +1116,10 @@ static int hvmop_set_isa_irq_level(
if ( !is_hvm_domain(d) )
goto out;

+ rc = xsm_hvm_set_isa_irq_level(d);
+ if ( rc )
+ goto out;
+
rc = 0;
switch ( op.level )
{
@@ -1153,6 +1161,10 @@ static int hvmop_set_pci_link_route(

rc = -EINVAL;
if ( !is_hvm_domain(d) )
+ goto out;
+
+ rc = xsm_hvm_set_pci_link_route(d);
+ if ( rc )
goto out;

rc = 0;
@@ -1202,6 +1214,10 @@ long do_hvm_op(unsigned long op, XEN_GUE

rc = -EINVAL;
if ( !is_hvm_domain(d) )
+ goto param_fail;
+
+ rc = xsm_hvm_param(d, op);
+ if ( rc )
goto param_fail;

if ( op == HVMOP_set_param )
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/mm.c Fri Aug 31 11:21:35 2007 +0100
@@ -110,6 +110,7 @@
#include <asm/hypercall.h>
#include <asm/shared.h>
#include <public/memory.h>
+#include <xsm/xsm.h>

#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)

@@ -2048,6 +2049,10 @@ int do_mmuext_op(
type = PGT_l4_page_table;

pin_page:
+ rc = xsm_memory_pin_page(current->domain, page);
+ if ( rc )
+ break;
+
/* Ignore pinning of invalid paging levels. */
if ( (op.cmd - MMUEXT_PIN_L1_TABLE) > (CONFIG_PAGING_LEVELS - 1) )
break;
@@ -2333,6 +2338,10 @@ int do_mmu_update(
* MMU_NORMAL_PT_UPDATE: Normal update to any level of page table.
*/
case MMU_NORMAL_PT_UPDATE:
+
+ rc = xsm_mmu_normal_update(current->domain, req.val);
+ if ( rc )
+ break;

gmfn = req.ptr >> PAGE_SHIFT;
mfn = gmfn_to_mfn(d, gmfn);
@@ -2424,6 +2433,10 @@ int do_mmu_update(
mfn = req.ptr >> PAGE_SHIFT;
gpfn = req.val;

+ rc = xsm_mmu_machphys_update(current->domain, mfn);
+ if ( rc )
+ break;
+
if ( unlikely(!get_page_from_pagenr(mfn, FOREIGNDOM)) )
{
MEM_LOG("Could not get page for mach->phys update");
@@ -2802,6 +2815,10 @@ int do_update_va_mapping(unsigned long v
if ( unlikely(!__addr_ok(va) && !paging_mode_external(d)) )
return -EINVAL;

+ rc = xsm_update_va_mapping(current->domain, val);
+ if ( rc )
+ return rc;
+
LOCK_BIGLOCK(d);

pl1e = guest_map_l1e(v, va, &gl1mfn);
@@ -3063,6 +3080,12 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = rcu_lock_domain_by_id(xatp.domid)) == NULL )
return -ESRCH;

+ if ( xsm_add_to_physmap(current->domain, d) )
+ {
+ rcu_unlock_domain(d);
+ return -EPERM;
+ }
+
switch ( xatp.space )
{
case XENMAPSPACE_shared_info:
@@ -3139,6 +3162,13 @@ long arch_memory_op(int op, XEN_GUEST_HA
else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
return -ESRCH;

+ rc = xsm_domain_memory_map(d);
+ if ( rc )
+ {
+ rcu_unlock_domain(d);
+ return rc;
+ }
+
rc = copy_from_guest(d->arch.e820, fmap.map.buffer,
fmap.map.nr_entries) ? -EFAULT : 0;
d->arch.nr_e820 = fmap.map.nr_entries;
@@ -3172,9 +3202,14 @@ long arch_memory_op(int op, XEN_GUEST_HA
struct xen_memory_map memmap;
XEN_GUEST_HANDLE(e820entry_t) buffer;
int count;
+ int rc;

if ( !IS_PRIV(current->domain) )
return -EINVAL;
+
+ rc = xsm_machine_memory_map();
+ if ( rc )
+ return rc;

if ( copy_from_guest(&memmap, arg, 1) )
return -EFAULT;
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/mm/paging.c
--- a/xen/arch/x86/mm/paging.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/mm/paging.c Fri Aug 31 11:21:35 2007 +0100
@@ -26,6 +26,7 @@
#include <asm/p2m.h>
#include <asm/hap.h>
#include <asm/guest_access.h>
+#include <xsm/xsm.h>

/* Xen command-line option to enable hardware-assisted paging */
int opt_hap_enabled;
@@ -401,6 +402,10 @@ int paging_domctl(struct domain *d, xen_
d->domain_id);
return -EINVAL;
}
+
+ rc = xsm_shadow_control(d, sc->op);
+ if ( rc )
+ return rc;

/* Code to handle log-dirty. Note that some log dirty operations
* piggy-back on shadow operations. For example, when
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/physdev.c Fri Aug 31 11:21:35 2007 +0100
@@ -12,6 +12,7 @@
#include <asm/hypercall.h>
#include <public/xen.h>
#include <public/physdev.h>
+#include <xsm/xsm.h>

#ifndef COMPAT
typedef long ret_t;
@@ -73,6 +74,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
ret = -EPERM;
if ( !IS_PRIV(v->domain) )
break;
+ ret = xsm_apic(v->domain, cmd);
+ if ( ret )
+ break;
ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
if ( copy_to_guest(arg, &apic, 1) != 0 )
ret = -EFAULT;
@@ -87,6 +91,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
ret = -EPERM;
if ( !IS_PRIV(v->domain) )
break;
+ ret = xsm_apic(v->domain, cmd);
+ if ( ret )
+ break;
ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
break;
}
@@ -100,6 +107,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H

ret = -EPERM;
if ( !IS_PRIV(v->domain) )
+ break;
+
+ ret = xsm_assign_vector(v->domain, irq_op.irq);
+ if ( ret )
break;

irq = irq_op.irq;
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/platform_hypercall.c Fri Aug 31 11:21:35 2007 +0100
@@ -24,6 +24,7 @@
#include <asm/edd.h>
#include <asm/mtrr.h>
#include "cpu/mtrr/mtrr.h"
+#include <xsm/xsm.h>

extern uint16_t boot_edid_caps;
extern uint8_t boot_edid_info[];
@@ -59,6 +60,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
{
case XENPF_settime:
{
+ ret = xsm_xen_settime();
+ if ( ret )
+ break;
+
do_settime(op->u.settime.secs,
op->u.settime.nsecs,
op->u.settime.system_time);
@@ -68,6 +73,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe

case XENPF_add_memtype:
{
+ ret = xsm_memtype(op->cmd);
+ if ( ret )
+ break;
+
ret = mtrr_add_page(
op->u.add_memtype.mfn,
op->u.add_memtype.nr_mfns,
@@ -86,6 +95,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe

case XENPF_del_memtype:
{
+ ret = xsm_memtype(op->cmd);
+ if ( ret )
+ break;
+
if (op->u.del_memtype.handle == 0
/* mtrr/main.c otherwise does a lookup */
&& (int)op->u.del_memtype.reg >= 0)
@@ -104,6 +117,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
unsigned long mfn;
unsigned int nr_mfns;
mtrr_type type;
+
+ ret = xsm_memtype(op->cmd);
+ if ( ret )
+ break;

ret = -EINVAL;
if ( op->u.read_memtype.reg < num_var_ranges )
@@ -120,6 +137,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
case XENPF_microcode_update:
{
extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
+
+ ret = xsm_microcode();
+ if ( ret )
+ break;
+
#ifndef COMPAT
ret = microcode_update(op->u.microcode.data,
op->u.microcode.length);
@@ -136,6 +158,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
{
extern int opt_noirqbalance;
int quirk_id = op->u.platform_quirk.quirk_id;
+
+ ret = xsm_platform_quirk(quirk_id);
+ if ( ret )
+ break;
+
switch ( quirk_id )
{
case QUIRK_NOIRQBALANCING:
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/setup.c Fri Aug 31 11:21:35 2007 +0100
@@ -35,6 +35,7 @@
#include <acm/acm_hooks.h>
#include <xen/kexec.h>
#include <asm/edd.h>
+#include <xsm/xsm.h>

#if defined(CONFIG_X86_64)
#define BOOTSTRAP_DIRECTMAP_END (1UL << 32) /* 4GB */
@@ -963,6 +964,8 @@ void __init __start_xen(unsigned long mb

percpu_init_areas();

+ xsm_init(&initrdidx, mbi, initial_images_start);
+
init_idle_domain();

trap_init();
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/sysctl.c Fri Aug 31 11:21:35 2007 +0100
@@ -25,6 +25,7 @@
#include <asm/processor.h>
#include <asm/numa.h>
#include <xen/nodemask.h>
+#include <xsm/xsm.h>

#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)

@@ -41,6 +42,10 @@ long arch_do_sysctl(
uint32_t i, max_array_ent;

xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo;
+
+ ret = xsm_physinfo();
+ if ( ret )
+ break;

pi->threads_per_core =
cpus_weight(cpu_sibling_map[0]);
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/x86_32/entry.S Fri Aug 31 11:21:35 2007 +0100
@@ -676,6 +676,7 @@ ENTRY(hypercall_table)
.long do_sysctl /* 35 */
.long do_domctl
.long do_kexec_op
+ .long do_xsm_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -719,6 +720,7 @@ ENTRY(hypercall_args_table)
.byte 1 /* do_sysctl */ /* 35 */
.byte 1 /* do_domctl */
.byte 2 /* do_kexec_op */
+ .byte 1 /* do_xsm_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/x86_32/xen.lds.S Fri Aug 31 11:21:35 2007 +0100
@@ -63,6 +63,8 @@ SECTIONS
__initcall_start = .;
.initcall.init : { *(.initcall1.init) } :text
__initcall_end = .;
+ .xsm_initcall.init : { __xsm_initcall_start = .;
+ *(.xsm_initcall.init) __xsm_initcall_end = .; }
. = ALIGN(PAGE_SIZE);
__init_end = .;

diff -r 0f196e11a143 -r 96f64f4c42f0 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/arch/x86/x86_64/entry.S Fri Aug 31 11:21:35 2007 +0100
@@ -612,6 +612,7 @@ ENTRY(hypercall_table)
.quad do_sysctl /* 35 */
.quad do_domctl
.quad do_kexec_op
+ .quad do_xsm_op
.rept NR_hypercalls-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
@@ -655,6 +656,7 @@ ENTRY(hypercall_args_table)
.byte 1 /* do_sysctl */ /* 35 */
.byte 1 /* do_domctl */
.byte 2 /* do_kexec */
+ .byte 1 /* do_xsm_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/domain.c
--- a/xen/common/domain.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/domain.c Fri Aug 31 11:21:35 2007 +0100
@@ -29,6 +29,7 @@
#include <public/sched.h>
#include <public/vcpu.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>

/* Protect updates/reads (resp.) of domain_list and domain_hash. */
DEFINE_SPINLOCK(domlist_update_lock);
@@ -57,6 +58,13 @@ struct domain *alloc_domain(domid_t domi

memset(d, 0, sizeof(*d));
d->domain_id = domid;
+
+ if ( xsm_alloc_security_domain(d) != 0 )
+ {
+ free_domain(d);
+ return NULL;
+ }
+
atomic_set(&d->refcnt, 1);
spin_lock_init(&d->big_lock);
spin_lock_init(&d->page_alloc_lock);
@@ -69,6 +77,7 @@ struct domain *alloc_domain(domid_t domi

void free_domain(struct domain *d)
{
+ xsm_free_security_domain(d);
xfree(d);
}

@@ -193,6 +202,9 @@ struct domain *domain_create(

if ( !is_idle_domain(d) )
{
+ if ( xsm_domain_create(d, ssidref) != 0 )
+ goto fail;
+
d->is_paused_by_controller = 1;
atomic_inc(&d->pause_count);

diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/domctl.c
--- a/xen/common/domctl.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/domctl.c Fri Aug 31 11:21:35 2007 +0100
@@ -24,6 +24,7 @@
#include <asm/current.h>
#include <public/domctl.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>

extern long arch_do_domctl(
struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
@@ -127,7 +128,9 @@ void getdomaininfo(struct domain *d, str
info->ssidref = ((struct acm_ssid_domain *)d->ssid)->ssidref;
else
info->ssidref = ACM_DEFAULT_SSID;
-
+
+ xsm_security_domaininfo(d, info);
+
info->tot_pages = d->tot_pages;
info->max_pages = d->max_pages;
info->shared_info_frame = mfn_to_gmfn(d, __pa(d->shared_info)>>PAGE_SHIFT);
@@ -204,6 +207,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;

+ ret = xsm_setvcpucontext(d);
+ if ( ret )
+ goto svc_out;
+
ret = -EINVAL;
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
goto svc_out;
@@ -251,12 +258,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_pausedomain(d);
+ if ( ret )
+ goto pausedomain_out;
+
ret = -EINVAL;
if ( d != current->domain )
{
domain_pause_by_systemcontroller(d);
ret = 0;
}
+ pausedomain_out:
rcu_unlock_domain(d);
}
}
@@ -270,6 +282,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;

+ ret = xsm_unpausedomain(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
domain_unpause_by_systemcontroller(d);
rcu_unlock_domain(d);
ret = 0;
@@ -283,6 +302,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d == NULL )
break;
+
+ ret = xsm_resumedomain(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

domain_resume(d);
rcu_unlock_domain(d);
@@ -359,6 +385,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;

+ ret = xsm_max_vcpus(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
/* Needed, for example, to ensure writable p.t. state is synced. */
domain_pause(d);

@@ -395,12 +428,18 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( d != NULL )
{
+ ret = xsm_destroydomain(d);
+ if ( ret )
+ goto destroydomain_out;
+
ret = -EINVAL;
if ( d != current->domain )
{
domain_kill(d);
ret = 0;
}
+
+ destroydomain_out:
rcu_unlock_domain(d);
}
}
@@ -418,6 +457,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;

+ ret = xsm_vcpuaffinity(op->cmd, d);
+ if ( ret )
+ goto vcpuaffinity_out;
+
ret = -EINVAL;
if ( op->u.vcpuaffinity.vcpu >= MAX_VIRT_CPUS )
goto vcpuaffinity_out;
@@ -452,10 +495,15 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;

+ ret = xsm_scheduler(d);
+ if ( ret )
+ goto scheduler_op_out;
+
ret = sched_adjust(d, &op->u.scheduler_op);
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;

+ scheduler_op_out:
rcu_unlock_domain(d);
}
break;
@@ -478,12 +526,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
break;
}

+ ret = xsm_getdomaininfo(d);
+ if ( ret )
+ goto getdomaininfo_out;
+
getdomaininfo(d, &op->u.getdomaininfo);

op->domain = op->u.getdomaininfo.domain;
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;

+ getdomaininfo_out:
rcu_read_unlock(&domlist_read_lock);
}
break;
@@ -497,6 +550,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
ret = -ESRCH;
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;
+
+ ret = xsm_getvcpucontext(d);
+ if ( ret )
+ goto getvcpucontext_out;

ret = -EINVAL;
if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS )
@@ -554,6 +611,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = rcu_lock_domain_by_id(op->domain)) == NULL )
break;

+ ret = xsm_getvcpuinfo(d);
+ if ( ret )
+ goto getvcpuinfo_out;
+
ret = -EINVAL;
if ( op->u.getvcpuinfo.vcpu >= MAX_VIRT_CPUS )
goto getvcpuinfo_out;
@@ -589,6 +650,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;

+ ret = xsm_setdomainmaxmem(d);
+ if ( ret )
+ goto max_mem_out;
+
ret = -EINVAL;
new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10);

@@ -603,6 +668,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
spin_unlock(&d->page_alloc_lock);

+ max_mem_out:
rcu_unlock_domain(d);
}
break;
@@ -615,6 +681,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
break;
+
+ ret = xsm_setdomainhandle(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

memcpy(d->handle, op->u.setdomainhandle.handle,
sizeof(xen_domain_handle_t));
@@ -631,6 +704,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
break;
+
+ ret = xsm_setdebugging(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }

domain_pause(d);
d->debugger_attached = !!op->u.setdebugging.enable;
@@ -654,11 +734,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( d == NULL )
break;

+ ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access);
+ if ( ret )
+ goto irq_permission_out;
+
if ( op->u.irq_permission.allow_access )
ret = irq_permit_access(d, pirq);
else
ret = irq_deny_access(d, pirq);

+ irq_permission_out:
rcu_unlock_domain(d);
}
break;
@@ -677,12 +762,17 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
break;
+
+ ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access);
+ if ( ret )
+ goto iomem_permission_out;

if ( op->u.iomem_permission.allow_access )
ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
else
ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);

+ iomem_permission_out:
rcu_unlock_domain(d);
}
break;
@@ -695,6 +785,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
d = rcu_lock_domain_by_id(op->domain);
if ( d != NULL )
{
+ ret = xsm_domain_settime(d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ break;
+ }
+
d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
rcu_unlock_domain(d);
ret = 0;
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/event_channel.c
--- a/xen/common/event_channel.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/event_channel.c Fri Aug 31 11:21:35 2007 +0100
@@ -30,6 +30,7 @@
#include <public/xen.h>
#include <public/event_channel.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>

#define bucket_from_port(d,p) \
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
@@ -78,6 +79,7 @@ static int get_free_port(struct domain *
{
struct evtchn *chn;
int port;
+ int i, j;

if ( d->is_dying )
return -EINVAL;
@@ -95,6 +97,19 @@ static int get_free_port(struct domain *
memset(chn, 0, EVTCHNS_PER_BUCKET * sizeof(*chn));
bucket_from_port(d, port) = chn;

+ for ( i = 0; i < EVTCHNS_PER_BUCKET; i++ )
+ {
+ if ( xsm_alloc_security_evtchn(&chn[i]) )
+ {
+ for ( j = 0; j < i; j++ )
+ {
+ xsm_free_security_evtchn(&chn[j]);
+ }
+ xfree(chn);
+ return -ENOMEM;
+ }
+ }
+
return port;
}

@@ -123,6 +138,10 @@ static long evtchn_alloc_unbound(evtchn_
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
chn = evtchn_from_port(d, port);
+
+ rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom);
+ if ( rc )
+ goto out;

chn->state = ECS_UNBOUND;
if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
@@ -179,6 +198,10 @@ static long evtchn_bind_interdomain(evtc
if ( (rchn->state != ECS_UNBOUND) ||
(rchn->u.unbound.remote_domid != ld->domain_id) )
ERROR_EXIT(-EINVAL);
+
+ rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn);
+ if ( rc )
+ goto out;

lchn->u.interdomain.remote_dom = rd;
lchn->u.interdomain.remote_port = (u16)rport;
@@ -422,6 +445,8 @@ static long __evtchn_close(struct domain
chn1->state = ECS_FREE;
chn1->notify_vcpu_id = 0;

+ xsm_evtchn_close_post(chn1);
+
out:
if ( d2 != NULL )
{
@@ -465,6 +490,10 @@ long evtchn_send(unsigned int lport)
spin_unlock(&ld->evtchn_lock);
return -EINVAL;
}
+
+ ret = xsm_evtchn_send(ld, lchn);
+ if ( ret )
+ goto out;

switch ( lchn->state )
{
@@ -495,6 +524,7 @@ long evtchn_send(unsigned int lport)
ret = -EINVAL;
}

+out:
spin_unlock(&ld->evtchn_lock);

return ret;
@@ -613,6 +643,11 @@ static long evtchn_status(evtchn_status_
}

chn = evtchn_from_port(d, port);
+
+ rc = xsm_evtchn_status(d, chn);
+ if ( rc )
+ goto out;
+
switch ( chn->state )
{
case ECS_FREE:
@@ -743,6 +778,7 @@ static long evtchn_reset(evtchn_reset_t
domid_t dom = r->dom;
struct domain *d;
int i;
+ int rc;

if ( dom == DOMID_SELF )
dom = current->domain->domain_id;
@@ -751,6 +787,13 @@ static long evtchn_reset(evtchn_reset_t

if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
return -ESRCH;
+
+ rc = xsm_evtchn_reset(current->domain, d);
+ if ( rc )
+ {
+ rcu_unlock_domain(d);
+ return rc;
+ }

for ( i = 0; port_is_valid(d, i); i++ )
(void)__evtchn_close(d, i);
@@ -969,7 +1012,10 @@ void evtchn_destroy(struct domain *d)
/* Free all event-channel buckets. */
spin_lock(&d->evtchn_lock);
for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ )
+ {
+ xsm_free_security_evtchn(d->evtchn[i]);
xfree(d->evtchn[i]);
+ }
spin_unlock(&d->evtchn_lock);
}

diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/grant_table.c
--- a/xen/common/grant_table.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/grant_table.c Fri Aug 31 11:21:35 2007 +0100
@@ -33,6 +33,7 @@
#include <xen/guest_access.h>
#include <xen/domain_page.h>
#include <acm/acm_hooks.h>
+#include <xsm/xsm.h>

#ifndef max_nr_grant_frames
unsigned int max_nr_grant_frames = DEFAULT_MAX_NR_GRANT_FRAMES;
@@ -224,6 +225,14 @@ __gnttab_map_grant_ref(
return;
}

+ rc = xsm_grant_mapref(ld, rd, op->flags);
+ if ( rc )
+ {
+ rcu_unlock_domain(rd);
+ op->status = GNTST_permission_denied;
+ return;
+ }
+
if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
{
rcu_unlock_domain(rd);
@@ -448,6 +457,14 @@ __gnttab_unmap_common(
/* This can happen when a grant is implicitly unmapped. */
gdprintk(XENLOG_INFO, "Could not find domain %d\n", dom);
domain_crash(ld); /* naughty... */
+ return;
+ }
+
+ rc = xsm_grant_unmapref(ld, rd);
+ if ( rc )
+ {
+ rcu_unlock_domain(rd);
+ op->status = GNTST_permission_denied;
return;
}

@@ -705,6 +722,13 @@ gnttab_setup_table(
goto out;
}

+ if ( xsm_grant_setup(current->domain, d) )
+ {
+ rcu_unlock_domain(d);
+ op.status = GNTST_permission_denied;
+ goto out;
+ }
+
spin_lock(&d->grant_table->lock);

if ( (op.nr_frames > nr_grant_frames(d->grant_table)) &&
@@ -745,6 +769,7 @@ gnttab_query_size(
struct gnttab_query_size op;
struct domain *d;
domid_t dom;
+ int rc;

if ( count != 1 )
return -EINVAL;
@@ -770,6 +795,14 @@ gnttab_query_size(
{
gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
op.status = GNTST_bad_domain;
+ goto query_out;
+ }
+
+ rc = xsm_grant_query_size(current->domain, d);
+ if ( rc )
+ {
+ rcu_unlock_domain(d);
+ op.status = GNTST_permission_denied;
goto query_out;
}

@@ -916,6 +949,13 @@ gnttab_transfer(
page->count_info &= ~(PGC_count_mask|PGC_allocated);
free_domheap_page(page);
gop.status = GNTST_bad_domain;
+ goto copyback;
+ }
+
+ if ( xsm_grant_transfer(d, e) )
+ {
+ rcu_unlock_domain(e);
+ gop.status = GNTST_permission_denied;
goto copyback;
}

@@ -1138,6 +1178,13 @@ __gnttab_copy(
else if ( (dd = rcu_lock_domain_by_id(op->dest.domid)) == NULL )
PIN_FAIL(error_out, GNTST_bad_domain,
"couldn't find %d\n", op->dest.domid);
+
+ rc = xsm_grant_copy(sd, dd);
+ if ( rc )
+ {
+ rc = GNTST_permission_denied;
+ goto error_out;
+ }

if ( src_is_gref )
{
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/kexec.c
--- a/xen/common/kexec.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/kexec.c Fri Aug 31 11:21:35 2007 +0100
@@ -21,6 +21,7 @@
#include <xen/version.h>
#include <xen/console.h>
#include <public/elfnote.h>
+#include <xsm/xsm.h>

#ifndef COMPAT

@@ -367,6 +368,10 @@ ret_t do_kexec_op(unsigned long op, XEN_
if ( !IS_PRIV(current->domain) )
return -EPERM;

+ ret = xsm_kexec();
+ if ( ret )
+ return ret;
+
switch ( op )
{
case KEXEC_CMD_kexec_get_range:
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/memory.c
--- a/xen/common/memory.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/memory.c Fri Aug 31 11:21:35 2007 +0100
@@ -22,6 +22,7 @@
#include <asm/current.h>
#include <asm/hardirq.h>
#include <public/memory.h>
+#include <xsm/xsm.h>

struct memop_args {
/* INPUT */
@@ -216,6 +217,7 @@ static long translate_gpfn_list(
xen_pfn_t gpfn;
xen_pfn_t mfn;
struct domain *d;
+ int rc;

if ( copy_from_guest(&op, uop, 1) )
return -EFAULT;
@@ -258,6 +260,13 @@ static long translate_gpfn_list(
}

mfn = gmfn_to_mfn(d, gpfn);
+
+ rc = xsm_translate_gpfn_list(current->domain, mfn);
+ if ( rc )
+ {
+ rcu_unlock_domain(d);
+ return rc;
+ }

if ( unlikely(__copy_to_guest_offset(op.mfn_list, i, &mfn, 1)) )
{
@@ -538,6 +547,14 @@ long do_memory_op(unsigned long cmd, XEN
return start_extent;
args.domain = d;

+ rc = xsm_memory_adjust_reservation(current->domain, d);
+ if ( rc )
+ {
+ if ( reservation.domid != DOMID_SELF )
+ rcu_unlock_domain(d);
+ return rc;
+ }
+
switch ( op )
{
case XENMEM_increase_reservation:
@@ -583,6 +600,14 @@ long do_memory_op(unsigned long cmd, XEN
return -EPERM;
else if ( (d = rcu_lock_domain_by_id(domid)) == NULL )
return -ESRCH;
+
+ rc = xsm_memory_stat_reservation(current->domain, d);
+ if ( rc )
+ {
+ if ( domid != DOMID_SELF )
+ rcu_unlock_domain(d);
+ return rc;
+ }

switch ( op )
{
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/schedule.c
--- a/xen/common/schedule.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/schedule.c Fri Aug 31 11:21:35 2007 +0100
@@ -32,6 +32,7 @@
#include <xen/guest_access.h>
#include <xen/multicall.h>
#include <public/sched.h>
+#include <xsm/xsm.h>

/* opt_sched: scheduler - default to credit */
static char opt_sched[10] = "credit";
@@ -460,6 +461,13 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN
d = rcu_lock_domain_by_id(sched_remote_shutdown.domain_id);
if ( d == NULL )
break;
+
+ ret = xsm_schedop_shutdown(current->domain, d);
+ if ( ret )
+ {
+ rcu_unlock_domain(d);
+ return ret;
+ }

/* domain_pause() prevens any further execution in guest context. */
domain_pause(d);
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/sysctl.c
--- a/xen/common/sysctl.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/sysctl.c Fri Aug 31 11:21:35 2007 +0100
@@ -23,6 +23,7 @@
#include <public/sysctl.h>
#include <asm/numa.h>
#include <xen/nodemask.h>
+#include <xsm/xsm.h>

extern long arch_do_sysctl(
struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
@@ -48,6 +49,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
{
case XEN_SYSCTL_readconsole:
{
+ ret = xsm_readconsole(op->u.readconsole.clear);
+ if ( ret )
+ break;
+
ret = read_console_ring(
guest_handle_cast(op->u.readconsole.buffer, char),
&op->u.readconsole.count,
@@ -59,6 +64,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc

case XEN_SYSCTL_tbuf_op:
{
+ ret = xsm_tbufcontrol();
+ if ( ret )
+ break;
+
ret = tb_control(&op->u.tbuf_op);
if ( copy_to_guest(u_sysctl, op, 1) )
ret = -EFAULT;
@@ -67,6 +76,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc

case XEN_SYSCTL_sched_id:
{
+ ret = xsm_sched_id();
+ if ( ret )
+ break;
+
op->u.sched_id.sched_id = sched_id();
if ( copy_to_guest(u_sysctl, op, 1) )
ret = -EFAULT;
@@ -90,6 +103,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
if ( num_domains == op->u.getdomaininfolist.max_domains )
break;

+ ret = xsm_getdomaininfo(d);
+ if ( ret )
+ continue;
+
getdomaininfo(d, &info);

if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
@@ -117,6 +134,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
#ifdef PERF_COUNTERS
case XEN_SYSCTL_perfc_op:
{
+ ret = xsm_perfcontrol();
+ if ( ret )
+ break;
+
ret = perfc_control(&op->u.perfc_op);
if ( copy_to_guest(u_sysctl, op, 1) )
ret = -EFAULT;
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/common/xenoprof.c Fri Aug 31 11:21:35 2007 +0100
@@ -14,6 +14,7 @@
#include <xen/sched.h>
#include <public/xenoprof.h>
#include <xen/paging.h>
+#include <xsm/xsm.h>

/* Limit amount of pages used for shared buffer (per domain) */
#define MAX_OPROF_SHARED_PAGES 32
@@ -634,6 +635,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
return -EPERM;
}

+ ret = xsm_profile(current->domain, op);
+ if ( ret )
+ return ret;
+
spin_lock(&xenoprof_lock);

switch ( op )
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/drivers/char/console.c Fri Aug 31 11:21:35 2007 +0100
@@ -32,6 +32,7 @@
#include <asm/debugger.h>
#include <asm/io.h>
#include <asm/div64.h>
+#include <xsm/xsm.h>

/* console: comma-separated list of console outputs. */
static char opt_console[30] = OPT_CONSOLE_STR;
@@ -357,6 +358,10 @@ long do_console_io(int cmd, int count, X
if ( current->domain->domain_id != 0 )
return -EPERM;
#endif
+
+ rc = xsm_console_io(current->domain, cmd);
+ if ( rc )
+ return rc;

switch ( cmd )
{
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/include/public/xen.h
--- a/xen/include/public/xen.h Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/include/public/xen.h Fri Aug 31 11:21:35 2007 +0100
@@ -80,6 +80,7 @@
#define __HYPERVISOR_sysctl 35
#define __HYPERVISOR_domctl 36
#define __HYPERVISOR_kexec_op 37
+#define __HYPERVISOR_xsm_op 38

/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h Fri Aug 31 11:12:57 2007 +0100
+++ b/xen/include/xen/hypercall.h Fri Aug 31 11:21:35 2007 +0100
@@ -15,6 +15,7 @@
#include <public/acm_ops.h>
#include <public/event_channel.h>
#include <asm/hypercall.h>
+#include <xsm/xsm.h>

extern long
do_ni_hypercall(
@@ -125,4 +126,8 @@ compat_memory_op(

#endif

+extern long
+do_xsm_op(
+ XEN_GUEST_HANDLE(xsm_op_t) u_xsm_op);
+
#endif /* __XEN_HYPERCALL_H__ */
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/include/xsm/xsm.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/xsm/xsm.h Fri Aug 31 11:21:35 2007 +0100
@@ -0,0 +1,537 @@
+/*
+ * This file contains the XSM hook definitions for Xen.
+ *
+ * This work is based on the LSM implementation in Linux 2.6.13.4.
+ *
+ * Author: George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ * Contributors: Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __XSM_H__
+#define __XSM_H__
+
+#include <xen/sched.h>
+#include <xen/multiboot.h>
+
+typedef void xsm_op_t;
+DEFINE_XEN_GUEST_HANDLE(xsm_op_t);
+
+extern long do_xsm_op (XEN_GUEST_HANDLE(xsm_op_t) op);
+
+#ifdef XSM_ENABLE
+ #define xsm_call(fn) xsm_ops->fn
+#else
+ #define xsm_call(fn) 0
+#endif
+
+/* policy magic number (defined by XSM_MAGIC) */
+typedef u32 xsm_magic_t;
+#ifndef XSM_MAGIC
+#define XSM_MAGIC 0x00000000
+#endif
+
+#ifdef XSM_ENABLE
+
+extern char *policy_buffer;
+extern u32 policy_size;
+
+typedef int (*xsm_initcall_t)(void);
+
+extern xsm_initcall_t __xsm_initcall_start[], __xsm_initcall_end[];
+
+#define xsm_initcall(fn) \
+ static xsm_initcall_t __initcall_##fn \
+ __attribute_used__ __attribute__((__section__(".xsm_initcall.init"))) = fn
+
+struct xsm_operations {
+ void (*security_domaininfo) (struct domain *d,
+ struct xen_domctl_getdomaininfo *info);
+ int (*setvcpucontext) (struct domain *d);
+ int (*pausedomain) (struct domain *d);
+ int (*unpausedomain) (struct domain *d);
+ int (*resumedomain) (struct domain *d);
+ int (*domain_create) (struct domain *d, u32 ssidref);
+ int (*max_vcpus) (struct domain *d);
+ int (*destroydomain) (struct domain *d);
+ int (*vcpuaffinity) (int cmd, struct domain *d);
+ int (*scheduler) (struct domain *d);
+ int (*getdomaininfo) (struct domain *d);
+ int (*getvcpucontext) (struct domain *d);
+ int (*getvcpuinfo) (struct domain *d);
+ int (*domain_settime) (struct domain *d);
+ int (*tbufcontrol) (void);
+ int (*readconsole) (uint32_t clear);
+ int (*sched_id) (void);
+ int (*setdomainmaxmem) (struct domain *d);
+ int (*setdomainhandle) (struct domain *d);
+ int (*setdebugging) (struct domain *d);
+ int (*irq_permission) (struct domain *d, uint8_t pirq, uint8_t access);
+ int (*iomem_permission) (struct domain *d, unsigned long mfn,
+ uint8_t access);
+ int (*perfcontrol) (void);
+
+ int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2);
+ int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1,
+ struct domain *d2, struct evtchn *chn2);
+ void (*evtchn_close_post) (struct evtchn *chn);
+ int (*evtchn_send) (struct domain *d, struct evtchn *chn);
+ int (*evtchn_status) (struct domain *d, struct evtchn *chn);
+ int (*evtchn_reset) (struct domain *d1, struct domain *d2);
+
+ int (*grant_mapref) (struct domain *d1, struct domain *d2, uint32_t flags);
+ int (*grant_unmapref) (struct domain *d1, struct domain *d2);
+ int (*grant_setup) (struct domain *d1, struct domain *d2);
+ int (*grant_transfer) (struct domain *d1, struct domain *d2);
+ int (*grant_copy) (struct domain *d1, struct domain *d2);
+ int (*grant_query_size) (struct domain *d1, struct domain *d2);
+
+ int (*alloc_security_domain) (struct domain *d);
+ void (*free_security_domain) (struct domain *d);
+ int (*alloc_security_evtchn) (struct evtchn *chn);
+ void (*free_security_evtchn) (struct evtchn *chn);
+
+ int (*translate_gpfn_list) (struct domain *d, unsigned long mfn);
+ int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2);
+ int (*memory_stat_reservation) (struct domain *d1, struct domain *d2);
+ int (*memory_pin_page) (struct domain *d, struct page_info *page);
+ int (*update_va_mapping) (struct domain *d, l1_pgentry_t pte);
+
+ int (*console_io) (struct domain *d, int cmd);
+
+ int (*profile) (struct domain *d, int op);
+
+ int (*kexec) (void);
+ int (*schedop_shutdown) (struct domain *d1, struct domain *d2);
+
+ long (*__do_xsm_op) (XEN_GUEST_HANDLE(xsm_op_t) op);
+ void (*complete_init) (struct domain *d);
+
+#ifdef CONFIG_X86
+ int (*shadow_control) (struct domain *d, uint32_t op);
+ int (*ioport_permission) (struct domain *d, uint32_t ioport,
+ uint8_t access);
+ int (*getpageframeinfo) (struct page_info *page);
+ int (*getmemlist) (struct domain *d);
+ int (*hypercall_init) (struct domain *d);
+ int (*hvmcontext) (struct domain *d, uint32_t op);
+ int (*address_size) (struct domain *d, uint32_t op);
+ int (*hvm_param) (struct domain *d, unsigned long op);
+ int (*hvm_set_pci_intx_level) (struct domain *d);
+ int (*hvm_set_isa_irq_level) (struct domain *d);
+ int (*hvm_set_pci_link_route) (struct domain *d);
+ int (*apic) (struct domain *d, int cmd);
+ int (*assign_vector) (struct domain *d, uint32_t pirq);
+ int (*xen_settime) (void);
+ int (*memtype) (uint32_t access);
+ int (*microcode) (void);
+ int (*physinfo) (void);
+ int (*platform_quirk) (uint32_t);
+ int (*machine_memory_map) (void);
+ int (*domain_memory_map) (struct domain *d);
+ int (*mmu_normal_update) (struct domain *d, intpte_t fpte);
+ int (*mmu_machphys_update) (struct domain *d, unsigned long mfn);
+ int (*add_to_physmap) (struct domain *d1, struct domain *d2);
+#endif
+};
+
+#endif
+
+extern struct xsm_operations *xsm_ops;
+
+static inline void xsm_security_domaininfo (struct domain *d,
+ struct xen_domctl_getdomaininfo *info)
+{
+ xsm_call(security_domaininfo(d, info));
+}
+
+static inline int xsm_setvcpucontext(struct domain *d)
+{
+ return xsm_call(setvcpucontext(d));
+}
+
+static inline int xsm_pausedomain (struct domain *d)
+{
+ return xsm_call(pausedomain(d));
+}
+
+static inline int xsm_unpausedomain (struct domain *d)
+{
+ return xsm_call(unpausedomain(d));
+}
+
+static inline int xsm_resumedomain (struct domain *d)
+{
+ return xsm_call(resumedomain(d));
+}
+
+static inline int xsm_domain_create (struct domain *d, u32 ssidref)
+{
+ return xsm_call(domain_create(d, ssidref));
+}
+
+static inline int xsm_max_vcpus(struct domain *d)
+{
+ return xsm_call(max_vcpus(d));
+}
+
+static inline int xsm_destroydomain (struct domain *d)
+{
+ return xsm_call(destroydomain(d));
+}
+
+static inline int xsm_vcpuaffinity (int cmd, struct domain *d)
+{
+ return xsm_call(vcpuaffinity(cmd, d));
+}
+
+static inline int xsm_scheduler (struct domain *d)
+{
+ return xsm_call(scheduler(d));
+}
+
+static inline int xsm_getdomaininfo (struct domain *d)
+{
+ return xsm_call(getdomaininfo(d));
+}
+
+static inline int xsm_getvcpucontext (struct domain *d)
+{
+ return xsm_call(getvcpucontext(d));
+}
+
+static inline int xsm_getvcpuinfo (struct domain *d)
+{
+ return xsm_call(getvcpuinfo(d));
+}
+
+static inline int xsm_domain_settime (struct domain *d)
+{
+ return xsm_call(domain_settime(d));
+}
+
+static inline int xsm_tbufcontrol (void)
+{
+ return xsm_call(tbufcontrol());
+}
+
+static inline int xsm_readconsole (uint32_t clear)
+{
+ return xsm_call(readconsole(clear));
+}
+
+static inline int xsm_sched_id (void)
+{
+ return xsm_call(sched_id());
+}
+
+static inline int xsm_setdomainmaxmem (struct domain *d)
+{
+ return xsm_call(setdomainmaxmem(d));
+}
+
+static inline int xsm_setdomainhandle (struct domain *d)
+{
+ return xsm_call(setdomainhandle(d));
+}
+
+static inline int xsm_setdebugging (struct domain *d)
+{
+ return xsm_call(setdebugging(d));
+}
+
+static inline int xsm_irq_permission (struct domain *d, uint8_t pirq,
+ uint8_t access)
+{
+ return xsm_call(irq_permission(d, pirq, access));
+}
+
+static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn,
+ uint8_t access)
+{
+ return xsm_call(iomem_permission(d, mfn, access));
+}
+
+static inline int xsm_perfcontrol (void)
+{
+ return xsm_call(perfcontrol());
+}
+
+static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn,
+ domid_t id2)
+{
+ return xsm_call(evtchn_unbound(d1, chn, id2));
+}
+
+static inline int xsm_evtchn_interdomain (struct domain *d1,
+ struct evtchn *chan1, struct domain *d2, struct evtchn *chan2)
+{
+ return xsm_call(evtchn_interdomain(d1, chan1, d2, chan2));
+}
+
+static inline void xsm_evtchn_close_post (struct evtchn *chn)
+{
+ xsm_call(evtchn_close_post(chn));
+}
+
+static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn)
+{
+ return xsm_call(evtchn_send(d, chn));
+}
+
+static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn)
+{
+ return xsm_call(evtchn_status(d, chn));
+}
+
+static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(evtchn_reset(d1, d2));
+}
+
+static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2,
+ uint32_t flags)
+{
+ return xsm_call(grant_mapref(d1, d2, flags));
+}
+
+static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(grant_unmapref(d1, d2));
+}
+
+static inline int xsm_grant_setup (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(grant_setup(d1, d2));
+}
+
+static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(grant_transfer(d1, d2));
+}
+
+static inline int xsm_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(grant_copy(d1, d2));
+}
+
+static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(grant_query_size(d1, d2));
+}
+
+static inline int xsm_alloc_security_domain (struct domain *d)
+{
+ return xsm_call(alloc_security_domain(d));
+}
+
+static inline void xsm_free_security_domain (struct domain *d)
+{
+ xsm_call(free_security_domain(d));
+}
+
+static inline int xsm_alloc_security_evtchn (struct evtchn *chn)
+{
+ return xsm_call(alloc_security_evtchn(chn));
+}
+
+static inline void xsm_free_security_evtchn (struct evtchn *chn)
+{
+ xsm_call(free_security_evtchn(chn));
+}
+
+static inline int xsm_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return xsm_call(translate_gpfn_list(d, mfn));
+}
+
+static inline int xsm_memory_adjust_reservation (struct domain *d1, struct
+ domain *d2)
+{
+ return xsm_call(memory_adjust_reservation(d1, d2));
+}
+
+static inline int xsm_memory_stat_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return xsm_call(memory_stat_reservation(d1, d2));
+}
+
+static inline int xsm_memory_pin_page(struct domain *d, struct page_info *page)
+{
+ return xsm_call(memory_pin_page(d, page));
+}
+
+static inline int xsm_update_va_mapping(struct domain *d, l1_pgentry_t pte)
+{
+ return xsm_call(update_va_mapping(d, pte));
+}
+
+static inline int xsm_console_io (struct domain *d, int cmd)
+{
+ return xsm_call(console_io(d, cmd));
+}
+
+static inline int xsm_profile (struct domain *d, int op)
+{
+ return xsm_call(profile(d, op));
+}
+
+static inline int xsm_kexec (void)
+{
+ return xsm_call(kexec());
+}
+
+static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return xsm_call(schedop_shutdown(d1, d2));
+}
+
+static inline long __do_xsm_op (XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return xsm_call(__do_xsm_op(op));
+}
+
+static inline void xsm_complete_init (struct domain *d)
+{
+ xsm_call(complete_init(d));
+}
+
+#ifdef XSM_ENABLE
+extern int xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
+ unsigned long initial_images_start);
+extern int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
+ unsigned long initial_images_start);
+extern int register_xsm(struct xsm_operations *ops);
+extern int unregister_xsm(struct xsm_operations *ops);
+#else
+static inline int xsm_init (unsigned int *initrdidx,
+ const multiboot_info_t *mbi, unsigned long initial_images_start)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_X86
+static inline int xsm_shadow_control (struct domain *d, uint32_t op)
+{
+ return xsm_call(shadow_control(d, op));
+}
+
+static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport,
+ uint8_t access)
+{
+ return xsm_call(ioport_permission(d, ioport, access));
+}
+
+static inline int xsm_getpageframeinfo (struct page_info *page)
+{
+ return xsm_call(getpageframeinfo(page));
+}
+
+static inline int xsm_getmemlist (struct domain *d)
+{
+ return xsm_call(getmemlist(d));
+}
+
+static inline int xsm_hypercall_init (struct domain *d)
+{
+ return xsm_call(hypercall_init(d));
+}
+
+static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return xsm_call(hvmcontext(d, cmd));
+}
+
+static inline int xsm_address_size (struct domain *d, uint32_t cmd)
+{
+ return xsm_call(address_size(d, cmd));
+}
+
+static inline int xsm_hvm_param (struct domain *d, unsigned long op)
+{
+ return xsm_call(hvm_param(d, op));
+}
+
+static inline int xsm_hvm_set_pci_intx_level (struct domain *d)
+{
+ return xsm_call(hvm_set_pci_intx_level(d));
+}
+
+static inline int xsm_hvm_set_isa_irq_level (struct domain *d)
+{
+ return xsm_call(hvm_set_isa_irq_level(d));
+}
+
+static inline int xsm_hvm_set_pci_link_route (struct domain *d)
+{
+ return xsm_call(hvm_set_pci_link_route(d));
+}
+
+static inline int xsm_apic (struct domain *d, int cmd)
+{
+ return xsm_call(apic(d, cmd));
+}
+
+static inline int xsm_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return xsm_call(assign_vector(d, pirq));
+}
+
+static inline int xsm_xen_settime (void)
+{
+ return xsm_call(xen_settime());
+}
+
+static inline int xsm_memtype (uint32_t access)
+{
+ return xsm_call(memtype(access));
+}
+
+static inline int xsm_microcode (void)
+{
+ return xsm_call(microcode());
+}
+
+static inline int xsm_physinfo (void)
+{
+ return xsm_call(physinfo());
+}
+
+static inline int xsm_platform_quirk (uint32_t quirk)
+{
+ return xsm_call(platform_quirk(quirk));
+}
+
+static inline int xsm_machine_memory_map(void)
+{
+ return xsm_call(machine_memory_map());
+}
+
+static inline int xsm_domain_memory_map(struct domain *d)
+{
+ return xsm_call(domain_memory_map(d));
+}
+
+static inline int xsm_mmu_normal_update (struct domain *d, intpte_t fpte)
+{
+ return xsm_call(mmu_normal_update(d, fpte));
+}
+
+static inline int xsm_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return xsm_call(mmu_machphys_update(d, mfn));
+}
+
+static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2)
+{
+ return xsm_call(add_to_physmap(d1, d2));
+}
+#endif /* CONFIG_X86 */
+
+#endif /* __XSM_H */
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/xsm/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/Makefile Fri Aug 31 11:21:35 2007 +0100
@@ -0,0 +1,5 @@
+obj-y += xsm_core.o
+obj-y += xsm_policy.o
+ifeq ($(XSM_ENABLE),y)
+obj-y += dummy.o
+endif
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/xsm/dummy.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/dummy.c Fri Aug 31 11:21:35 2007 +0100
@@ -0,0 +1,488 @@
+/*
+ * This work is based on the LSM implementation in Linux 2.6.13.4.
+ *
+ * Author: George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ * Contributors: Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ */
+
+#include <xen/sched.h>
+#include <xsm/xsm.h>
+
+static void dummy_security_domaininfo(struct domain *d,
+ struct xen_domctl_getdomaininfo *info)
+{
+ return;
+}
+
+static int dummy_setvcpucontext(struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_pausedomain (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_unpausedomain (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_resumedomain (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_domain_create(struct domain *d, u32 ssidref)
+{
+ return 0;
+}
+
+static int dummy_max_vcpus(struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_destroydomain (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_vcpuaffinity (int cmd, struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_scheduler (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_getdomaininfo (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_getvcpucontext (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_getvcpuinfo (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_domain_settime (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_tbufcontrol (void)
+{
+ return 0;
+}
+
+static int dummy_readconsole (uint32_t clear)
+{
+ return 0;
+}
+
+static int dummy_sched_id (void)
+{
+ return 0;
+}
+
+static int dummy_setdomainmaxmem (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_setdomainhandle (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_setdebugging (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_irq_permission (struct domain *d, uint8_t pirq, uint8_t access)
+{
+ return 0;
+}
+
+static int dummy_iomem_permission (struct domain *d, unsigned long mfn,
+ uint8_t access)
+{
+ return 0;
+}
+
+static int dummy_perfcontrol (void)
+{
+ return 0;
+}
+
+static int dummy_alloc_security_domain (struct domain *d)
+{
+ return 0;
+}
+
+static void dummy_free_security_domain (struct domain *d)
+{
+ return;
+}
+
+static int dummy_grant_mapref (struct domain *d1, struct domain *d2,
+ uint32_t flags)
+{
+ return 0;
+}
+
+static int dummy_grant_unmapref (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_grant_setup (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_grant_transfer (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_grant_copy (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_grant_query_size (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_translate_gpfn_list (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static int dummy_memory_adjust_reservation (struct domain *d1,
+ struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_memory_stat_reservation (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_update_va_mapping (struct domain *d, l1_pgentry_t pte)
+{
+ return 0;
+}
+
+static int dummy_console_io (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static int dummy_profile (struct domain *d, int op)
+{
+ return 0;
+}
+
+static int dummy_kexec (void)
+{
+ return 0;
+}
+
+static int dummy_schedop_shutdown (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_memory_pin_page(struct domain *d, struct page_info *page)
+{
+ return 0;
+}
+
+static int dummy_evtchn_unbound (struct domain *d, struct evtchn *chn,
+ domid_t id2)
+{
+ return 0;
+}
+
+static int dummy_evtchn_interdomain (struct domain *d1, struct evtchn
+ *chan1, struct domain *d2, struct evtchn *chan2)
+{
+ return 0;
+}
+
+static void dummy_evtchn_close_post (struct evtchn *chn)
+{
+ return;
+}
+
+static int dummy_evtchn_send (struct domain *d, struct evtchn *chn)
+{
+ return 0;
+}
+
+static int dummy_evtchn_status (struct domain *d, struct evtchn *chn)
+{
+ return 0;
+}
+
+static int dummy_evtchn_reset (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+
+static int dummy_alloc_security_evtchn (struct evtchn *chn)
+{
+ return 0;
+}
+
+static void dummy_free_security_evtchn (struct evtchn *chn)
+{
+ return;
+}
+
+static void dummy_complete_init (struct domain *d)
+{
+ return;
+}
+
+static long dummy___do_xsm_op(XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return -ENOSYS;
+}
+
+#ifdef CONFIG_X86
+static int dummy_shadow_control (struct domain *d, uint32_t op)
+{
+ return 0;
+}
+
+static int dummy_ioport_permission (struct domain *d, uint32_t ioport,
+ uint8_t access)
+{
+ return 0;
+}
+
+static int dummy_getpageframeinfo (struct page_info *page)
+{
+ return 0;
+}
+
+static int dummy_getmemlist (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_hypercall_init (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_hvmcontext (struct domain *d, uint32_t cmd)
+{
+ return 0;
+}
+
+static int dummy_address_size (struct domain *d, uint32_t cmd)
+{
+ return 0;
+}
+
+static int dummy_hvm_param (struct domain *d, unsigned long op)
+{
+ return 0;
+}
+
+static int dummy_hvm_set_pci_intx_level (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_hvm_set_isa_irq_level (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_hvm_set_pci_link_route (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_apic (struct domain *d, int cmd)
+{
+ return 0;
+}
+
+static int dummy_assign_vector (struct domain *d, uint32_t pirq)
+{
+ return 0;
+}
+
+static int dummy_xen_settime (void)
+{
+ return 0;
+}
+
+static int dummy_memtype (uint32_t access)
+{
+ return 0;
+}
+
+static int dummy_microcode (void)
+{
+ return 0;
+}
+
+static int dummy_physinfo (void)
+{
+ return 0;
+}
+
+static int dummy_platform_quirk (uint32_t quirk)
+{
+ return 0;
+}
+
+static int dummy_machine_memory_map (void)
+{
+ return 0;
+}
+
+static int dummy_domain_memory_map (struct domain *d)
+{
+ return 0;
+}
+
+static int dummy_mmu_normal_update (struct domain *d, intpte_t fpte)
+{
+ return 0;
+}
+
+static int dummy_mmu_machphys_update (struct domain *d, unsigned long mfn)
+{
+ return 0;
+}
+
+static int dummy_add_to_physmap (struct domain *d1, struct domain *d2)
+{
+ return 0;
+}
+#endif
+
+struct xsm_operations dummy_xsm_ops;
+
+#define set_to_dummy_if_null(ops, function) \
+ do { \
+ if ( !ops->function ) \
+ { \
+ ops->function = dummy_##function; \
+ dprintk(XENLOG_DEBUG, "Had to override the " #function \
+ " security operation with the dummy one.\n"); \
+ } \
+ } while (0)
+
+void xsm_fixup_ops (struct xsm_operations *ops)
+{
+ set_to_dummy_if_null(ops, security_domaininfo);
+ set_to_dummy_if_null(ops, setvcpucontext);
+ set_to_dummy_if_null(ops, pausedomain);
+ set_to_dummy_if_null(ops, unpausedomain);
+ set_to_dummy_if_null(ops, resumedomain);
+ set_to_dummy_if_null(ops, domain_create);
+ set_to_dummy_if_null(ops, max_vcpus);
+ set_to_dummy_if_null(ops, destroydomain);
+ set_to_dummy_if_null(ops, vcpuaffinity);
+ set_to_dummy_if_null(ops, scheduler);
+ set_to_dummy_if_null(ops, getdomaininfo);
+ set_to_dummy_if_null(ops, getvcpucontext);
+ set_to_dummy_if_null(ops, getvcpuinfo);
+ set_to_dummy_if_null(ops, domain_settime);
+ set_to_dummy_if_null(ops, tbufcontrol);
+ set_to_dummy_if_null(ops, readconsole);
+ set_to_dummy_if_null(ops, sched_id);
+ set_to_dummy_if_null(ops, setdomainmaxmem);
+ set_to_dummy_if_null(ops, setdomainhandle);
+ set_to_dummy_if_null(ops, setdebugging);
+ set_to_dummy_if_null(ops, irq_permission);
+ set_to_dummy_if_null(ops, iomem_permission);
+ set_to_dummy_if_null(ops, perfcontrol);
+
+ set_to_dummy_if_null(ops, evtchn_unbound);
+ set_to_dummy_if_null(ops, evtchn_interdomain);
+ set_to_dummy_if_null(ops, evtchn_close_post);
+ set_to_dummy_if_null(ops, evtchn_send);
+ set_to_dummy_if_null(ops, evtchn_status);
+ set_to_dummy_if_null(ops, evtchn_reset);
+
+ set_to_dummy_if_null(ops, grant_mapref);
+ set_to_dummy_if_null(ops, grant_unmapref);
+ set_to_dummy_if_null(ops, grant_setup);
+ set_to_dummy_if_null(ops, grant_transfer);
+ set_to_dummy_if_null(ops, grant_copy);
+ set_to_dummy_if_null(ops, grant_query_size);
+
+ set_to_dummy_if_null(ops, alloc_security_domain);
+ set_to_dummy_if_null(ops, free_security_domain);
+ set_to_dummy_if_null(ops, alloc_security_evtchn);
+ set_to_dummy_if_null(ops, free_security_evtchn);
+
+ set_to_dummy_if_null(ops, translate_gpfn_list);
+ set_to_dummy_if_null(ops, memory_adjust_reservation);
+ set_to_dummy_if_null(ops, memory_stat_reservation);
+ set_to_dummy_if_null(ops, memory_pin_page);
+ set_to_dummy_if_null(ops, update_va_mapping);
+
+ set_to_dummy_if_null(ops, console_io);
+
+ set_to_dummy_if_null(ops, profile);
+
+ set_to_dummy_if_null(ops, kexec);
+ set_to_dummy_if_null(ops, schedop_shutdown);
+
+ set_to_dummy_if_null(ops, __do_xsm_op);
+ set_to_dummy_if_null(ops, complete_init);
+
+#ifdef CONFIG_X86
+ set_to_dummy_if_null(ops, shadow_control);
+ set_to_dummy_if_null(ops, ioport_permission);
+ set_to_dummy_if_null(ops, getpageframeinfo);
+ set_to_dummy_if_null(ops, getmemlist);
+ set_to_dummy_if_null(ops, hypercall_init);
+ set_to_dummy_if_null(ops, hvmcontext);
+ set_to_dummy_if_null(ops, address_size);
+ set_to_dummy_if_null(ops, hvm_param);
+ set_to_dummy_if_null(ops, hvm_set_pci_intx_level);
+ set_to_dummy_if_null(ops, hvm_set_isa_irq_level);
+ set_to_dummy_if_null(ops, hvm_set_pci_link_route);
+ set_to_dummy_if_null(ops, apic);
+ set_to_dummy_if_null(ops, assign_vector);
+ set_to_dummy_if_null(ops, xen_settime);
+ set_to_dummy_if_null(ops, memtype);
+ set_to_dummy_if_null(ops, microcode);
+ set_to_dummy_if_null(ops, physinfo);
+ set_to_dummy_if_null(ops, platform_quirk);
+ set_to_dummy_if_null(ops, machine_memory_map);
+ set_to_dummy_if_null(ops, domain_memory_map);
+ set_to_dummy_if_null(ops, mmu_normal_update);
+ set_to_dummy_if_null(ops, mmu_machphys_update);
+ set_to_dummy_if_null(ops, add_to_physmap);
+#endif
+}
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/xsm/xsm_core.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_core.c Fri Aug 31 11:21:35 2007 +0100
@@ -0,0 +1,118 @@
+/*
+ * This work is based on the LSM implementation in Linux 2.6.13.4.
+ *
+ * Author: George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ * Contributors: Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ */
+
+#include <xen/init.h>
+#include <xen/errno.h>
+#include <xen/lib.h>
+
+#include <xsm/xsm.h>
+
+#ifdef XSM_ENABLE
+
+#define XSM_FRAMEWORK_VERSION "1.0.0"
+
+extern struct xsm_operations dummy_xsm_ops;
+extern void xsm_fixup_ops(struct xsm_operations *ops);
+
+struct xsm_operations *xsm_ops;
+
+static inline int verify(struct xsm_operations *ops)
+{
+ /* verify the security_operations structure exists */
+ if ( !ops )
+ return -EINVAL;
+ xsm_fixup_ops(ops);
+ return 0;
+}
+
+static void __init do_xsm_initcalls(void)
+{
+ xsm_initcall_t *call;
+ call = __xsm_initcall_start;
+ while ( call < __xsm_initcall_end )
+ {
+ (*call) ();
+ call++;
+ }
+}
+
+int __init xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
+ unsigned long initial_images_start)
+{
+ int ret = 0;
+
+ printk("XSM Framework v" XSM_FRAMEWORK_VERSION " initialized\n");
+
+ if ( XSM_MAGIC )
+ {
+ ret = xsm_policy_init(initrdidx, mbi, initial_images_start);
+ if ( ret )
+ {
+ printk("%s: Error initializing policy.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ }
+
+ if ( verify(&dummy_xsm_ops) )
+ {
+ printk("%s could not verify "
+ "dummy_xsm_ops structure.\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ xsm_ops = &dummy_xsm_ops;
+ do_xsm_initcalls();
+
+ return 0;
+}
+
+int register_xsm(struct xsm_operations *ops)
+{
+ if ( verify(ops) )
+ {
+ printk("%s could not verify "
+ "security_operations structure.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if ( xsm_ops != &dummy_xsm_ops )
+ return -EAGAIN;
+
+ xsm_ops = ops;
+
+ return 0;
+}
+
+
+int unregister_xsm(struct xsm_operations *ops)
+{
+ if ( ops != xsm_ops )
+ {
+ printk("%s: trying to unregister "
+ "a security_opts structure that is not "
+ "registered, failing.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ xsm_ops = &dummy_xsm_ops;
+
+ return 0;
+}
+
+#endif
+
+long do_xsm_op (XEN_GUEST_HANDLE(xsm_op_t) op)
+{
+ return __do_xsm_op(op);
+}
+
+
diff -r 0f196e11a143 -r 96f64f4c42f0 xen/xsm/xsm_policy.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/xsm/xsm_policy.c Fri Aug 31 11:21:35 2007 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer, <sailer@watson.ibm.com>
+ * Stefan Berger, <stefanb@watson.ibm.com>
+ *
+ * Contributors:
+ * Michael LeMay, <mdlemay@epoch.ncsc.mil>
+ * George Coker, <gscoker@alpha.ncsc.mil>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ *
+ * This file contains the XSM policy init functions for Xen.
+ * This file is based on the ACM functions of the same name.
+ *
+ */
+
+#include <xsm/xsm.h>
+#include <xen/multiboot.h>
+
+char *policy_buffer = NULL;
+u32 policy_size = 0;
+
+int xsm_policy_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
+ unsigned long initial_images_start)
+{
+ int i;
+ module_t *mod = (module_t *)__va(mbi->mods_addr);
+ int rc = 0;
+ u32 *_policy_start;
+ unsigned long start, _policy_len;
+
+ /*
+ * Try all modules and see whichever could be the binary policy.
+ * Adjust the initrdidx if module[1] is the binary policy.
+ */
+ for ( i = mbi->mods_count-1; i >= 1; i-- )
+ {
+ start = initial_images_start + (mod[i].mod_start-mod[0].mod_start);
+#if defined(__i386__)
+ _policy_start = (u32 *)start;
+#elif defined(__x86_64__)
+ _policy_start = maddr_to_virt(start);
+#endif
+ _policy_len = mod[i].mod_end - mod[i].mod_start;
+
+ if ( (xsm_magic_t)(*_policy_start) == XSM_MAGIC )
+ {
+ policy_buffer = (char *)_policy_start;
+ policy_size = _policy_len;
+
+ printk("Policy len 0x%lx, start at %p.\n",
+ _policy_len,_policy_start);
+
+ if ( i == 1 )
+ *initrdidx = (mbi->mods_count > 2) ? 2 : 0;
+ break;
+
+ }
+ }
+
+ return rc;
+}

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog